On Mon 06-10-14 15:12:08, Benjamin Marzinski wrote: > Currently, freezing a filesystem involves calling freeze_super, which locks > sb->s_umount and then calls the fs-specific freeze_fs hook. This makes it > hard for gfs2 (and potentially other cluster filesystems) to use the vfs > freezing code to do freezes on all the cluster nodes. > > In order to communicate that a freeze has been requested, and to make sure > that only one node is trying to freeze at a time, gfs2 uses a glock > (sd_freeze_gl). The problem is that there is no hook for gfs2 to acquire > this lock before calling freeze_super. This means that two nodes can > attempt to freeze the filesystem by both calling freeze_super, acquiring > the sb->s_umount lock, and then attempting to grab the cluster glock > sd_freeze_gl. Only one will succeed, and the other will be stuck in > freeze_super, making it impossible to finish freezing the node. > > To solve this problem, this patch adds the freeze_super and thaw_super > hooks. If a filesystem implements these hooks, they are called instead of > the vfs freeze_super and thaw_super functions. This means that every > filesystem that implements these hooks must call the vfs freeze_super and > thaw_super functions itself within the hook function to make use of the vfs > freezing code. > > Signed-off-by: Benjamin Marzinski <bmarzins@xxxxxxxxxx> The patch looks good. You can add: Reviewed-by: Jan Kara <jack@xxxxxxx> Honza > --- > fs/block_dev.c | 10 ++++++++-- > fs/ioctl.c | 6 +++++- > include/linux/fs.h | 2 ++ > 3 files changed, 15 insertions(+), 3 deletions(-) > > diff --git a/fs/block_dev.c b/fs/block_dev.c > index 6d72746..febd57c 100644 > --- a/fs/block_dev.c > +++ b/fs/block_dev.c > @@ -245,7 +245,10 @@ struct super_block *freeze_bdev(struct block_device *bdev) > sb = get_active_super(bdev); > if (!sb) > goto out; > - error = freeze_super(sb); > + if (sb->s_op->freeze_super) > + error = sb->s_op->freeze_super(sb); > + else > + error = freeze_super(sb); > if (error) { > deactivate_super(sb); > bdev->bd_fsfreeze_count--; > @@ -282,7 +285,10 @@ int thaw_bdev(struct block_device *bdev, struct super_block *sb) > if (!sb) > goto out; > > - error = thaw_super(sb); > + if (sb->s_op->thaw_super) > + error = sb->s_op->thaw_super(sb); > + else > + error = thaw_super(sb); > if (error) { > bdev->bd_fsfreeze_count++; > mutex_unlock(&bdev->bd_fsfreeze_mutex); > diff --git a/fs/ioctl.c b/fs/ioctl.c > index 8ac3fad..77c9a78 100644 > --- a/fs/ioctl.c > +++ b/fs/ioctl.c > @@ -518,10 +518,12 @@ static int ioctl_fsfreeze(struct file *filp) > return -EPERM; > > /* If filesystem doesn't support freeze feature, return. */ > - if (sb->s_op->freeze_fs == NULL) > + if (sb->s_op->freeze_fs == NULL && sb->s_op->freeze_super == NULL) > return -EOPNOTSUPP; > > /* Freeze */ > + if (sb->s_op->freeze_super) > + return sb->s_op->freeze_super(sb); > return freeze_super(sb); > } > > @@ -533,6 +535,8 @@ static int ioctl_fsthaw(struct file *filp) > return -EPERM; > > /* Thaw */ > + if (sb->s_op->thaw_super) > + return sb->s_op->thaw_super(sb); > return thaw_super(sb); > } > > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 9418772..1d1e07d 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -1570,7 +1570,9 @@ struct super_operations { > void (*evict_inode) (struct inode *); > void (*put_super) (struct super_block *); > int (*sync_fs)(struct super_block *sb, int wait); > + int (*freeze_super) (struct super_block *); > int (*freeze_fs) (struct super_block *); > + int (*thaw_super) (struct super_block *); > int (*unfreeze_fs) (struct super_block *); > int (*statfs) (struct dentry *, struct kstatfs *); > int (*remount_fs) (struct super_block *, int *, char *); > -- > 1.8.3.1 > -- Jan Kara <jack@xxxxxxx> SUSE Labs, CR -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html