Re: [RFC PATCH RESEND] fs: fix a hungtask problem when freeze/unfreeze fs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 2020/12/26 23:55, Al Viro wrote:
On Sat, Dec 26, 2020 at 04:56:41AM -0500, Shijie Luo wrote:

The root cause is that when offline/onlines disks, the filesystem can easily get into
a error state and this makes it change to be read-only. Function freeze_super() will hold
all sb_writers rwsems including rwsem of SB_FREEZE_WRITE when filesystem not read-only,
but thaw_super_locked() cannot release these while the filesystem suddenly become read-only,
because the logic will go to out.

freeze_super
     hold sb_writers rwsems
         sb->s_writers.frozen = SB_FREEZE_COMPLETE
                                                  thaw_super_locked
                                                      sb_rdonly
                                                         sb->s_writers.frozen = SB_UNFROZEN;
                                                             goto out // not release rwsems

And at this time, if we call mnt_want_write(), the process will be blocked.

This patch fixes this problem, when filesystem is read-only, just not to set sb_writers.frozen
be SB_FREEZE_COMPLETE in freeze_super() and then release all rwsems in thaw_super_locked.
I really don't like that - you end up with a case when freeze_super() returns 0 *and*
consumes the reference it had been give.

Consuming the reference here because we won't "set frozen = SB_FREEZE_COMPLETE" in thaw_super_locked() now.

If don't do that, we never have a chance to consume it, thaw_super_locked() will directly return "-EINVAL". But I do

agree that it's not a good idea to return 0. How about returning "-EINVAL or -ENOTSUPP" ?

And, If we keep "frozen = SB_FREEZE_COMPLETE" in freeze_super() here, it will cause another problem, thaw_super_locked()

will always release rwsems in my logic, but freeze_super() won't acquire the rwsems when filesystem is read-only.

Thanks.

  	if (sb_rdonly(sb)) {
-		/* Nothing to do really... */
-		sb->s_writers.frozen = SB_FREEZE_COMPLETE;
-		up_write(&sb->s_umount);
+		deactivate_locked_super(sb);
  		return 0;
  	}
.




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux