aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2011-03-15 12:41:19 -0700
committerBrian Behlendorf <[email protected]>2011-03-15 13:33:29 -0700
commit0de19dad9cbca9ac89aea1c7742f131713ef8012 (patch)
tree34838cb31a2bcb2a80848adb05a7a065ce328554
parent03f9ba9d990efb911026ebee0902671915db01a3 (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.h1
-rw-r--r--module/zfs/zfs_vfsops.c40
-rw-r--r--module/zfs/zpl_super.c12
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,
};