diff options
author | Brian Behlendorf <[email protected]> | 2011-03-15 12:41:19 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2011-03-15 13:33:29 -0700 |
commit | 0de19dad9cbca9ac89aea1c7742f131713ef8012 (patch) | |
tree | 34838cb31a2bcb2a80848adb05a7a065ce328554 | |
parent | 03f9ba9d990efb911026ebee0902671915db01a3 (diff) |
Register .remount_fs handler
Register the missing .remount_fs handler. This handler isn't strictly
required because the VFS does a pretty good job updating most of the
MS_* flags. However, there's no harm in using the hook to call the
registered zpl callback for various MS_* flags. Additionaly, this
allows us to lay the ground work for more complicated argument parsing
in the future.
-rw-r--r-- | include/sys/zfs_vfsops.h | 1 | ||||
-rw-r--r-- | module/zfs/zfs_vfsops.c | 40 | ||||
-rw-r--r-- | module/zfs/zpl_super.c | 12 |
3 files changed, 52 insertions, 1 deletions
diff --git a/include/sys/zfs_vfsops.h b/include/sys/zfs_vfsops.h index a2f00acf0..7622f0308 100644 --- a/include/sys/zfs_vfsops.h +++ b/include/sys/zfs_vfsops.h @@ -187,6 +187,7 @@ extern int zfs_register_callbacks(zfs_sb_t *zsb); extern void zfs_unregister_callbacks(zfs_sb_t *zsb); extern int zfs_domount(struct super_block *sb, void *data, int silent); extern int zfs_umount(struct super_block *sb); +extern int zfs_remount(struct super_block *sb, int *flags, char *data); extern int zfs_root(zfs_sb_t *zsb, struct inode **ipp); extern int zfs_statvfs(struct dentry *dentry, struct kstatfs *statp); extern int zfs_vget(struct vfsmount *vfsp, struct inode **ipp, fid_t *fidp); diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 1e8e6af9a..803607484 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -1292,6 +1292,46 @@ zfs_umount(struct super_block *sb) EXPORT_SYMBOL(zfs_umount); int +zfs_remount(struct super_block *sb, int *flags, char *data) +{ + zfs_sb_t *zsb = sb->s_fs_info; + boolean_t readonly = B_FALSE; + boolean_t setuid = B_TRUE; + boolean_t exec = B_TRUE; + boolean_t devices = B_TRUE; + boolean_t atime = B_TRUE; + + if (*flags & MS_RDONLY) + readonly = B_TRUE; + + if (*flags & MS_NOSUID) { + devices = B_FALSE; + setuid = B_FALSE; + } else { + if (*flags & MS_NODEV) + devices = B_FALSE; + } + + if (*flags & MS_NOEXEC) + exec = B_FALSE; + + if (*flags & MS_NOATIME) + atime = B_FALSE; + + /* + * Invoke our callbacks to set required flags. + */ + readonly_changed_cb(zsb, readonly); + setuid_changed_cb(zsb, setuid); + exec_changed_cb(zsb, exec); + devices_changed_cb(zsb, devices); + atime_changed_cb(zsb, atime); + + return (0); +} +EXPORT_SYMBOL(zfs_remount); + +int zfs_vget(struct vfsmount *vfsp, struct inode **ipp, fid_t *fidp) { zfs_sb_t *zsb = VTOZSB(vfsp); diff --git a/module/zfs/zpl_super.c b/module/zfs/zpl_super.c index 73e5268f5..6524a65ef 100644 --- a/module/zfs/zpl_super.c +++ b/module/zfs/zpl_super.c @@ -130,6 +130,16 @@ zpl_statfs(struct dentry *dentry, struct kstatfs *statp) } static int +zpl_remount_fs(struct super_block *sb, int *flags, char *data) +{ + int error; + error = -zfs_remount(sb, flags, data); + ASSERT3S(error, <=, 0); + + return (error); +} + +static int zpl_show_options(struct seq_file *seq, struct vfsmount *vfsp) { struct super_block *sb = vfsp->mnt_sb; @@ -197,7 +207,7 @@ const struct super_operations zpl_super_operations = { .freeze_fs = NULL, .unfreeze_fs = NULL, .statfs = zpl_statfs, - .remount_fs = NULL, + .remount_fs = zpl_remount_fs, .show_options = zpl_show_options, .show_stats = NULL, }; |