diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-16 06:59:40 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-16 16:48:06 -0400 |
commit | c7f404b40a3665d9f4e9a927cc5c1ee0479ed8f9 (patch) | |
tree | 2d6fa2bef00efa759f36b17f3be0d4fab3ac9bb5 | |
parent | f8ad9c4bae99854c961ca79ed130a0d11d9ab53c (diff) |
vfs: new superblock methods to override /proc/*/mount{s,info}
a) ->show_devname(m, mnt) - what to put into devname columns in mounts,
mountinfo and mountstats
b) ->show_path(m, mnt) - what to put into relative path column in mountinfo
Leaving those NULL gives old behaviour. NFS switched to using those.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/namespace.c | 39 | ||||
-rw-r--r-- | fs/nfs/super.c | 28 | ||||
-rw-r--r-- | include/linux/fs.h | 2 |
3 files changed, 60 insertions, 9 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index dffe6f49ab93..75d843ae46d2 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -978,7 +978,13 @@ static int show_vfsmnt(struct seq_file *m, void *v) | |||
978 | int err = 0; | 978 | int err = 0; |
979 | struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; | 979 | struct path mnt_path = { .dentry = mnt->mnt_root, .mnt = mnt }; |
980 | 980 | ||
981 | mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); | 981 | if (mnt->mnt_sb->s_op->show_devname) { |
982 | err = mnt->mnt_sb->s_op->show_devname(m, mnt); | ||
983 | if (err) | ||
984 | goto out; | ||
985 | } else { | ||
986 | mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); | ||
987 | } | ||
982 | seq_putc(m, ' '); | 988 | seq_putc(m, ' '); |
983 | seq_path(m, &mnt_path, " \t\n\\"); | 989 | seq_path(m, &mnt_path, " \t\n\\"); |
984 | seq_putc(m, ' '); | 990 | seq_putc(m, ' '); |
@@ -1025,7 +1031,12 @@ static int show_mountinfo(struct seq_file *m, void *v) | |||
1025 | 1031 | ||
1026 | seq_printf(m, "%i %i %u:%u ", mnt->mnt_id, mnt->mnt_parent->mnt_id, | 1032 | seq_printf(m, "%i %i %u:%u ", mnt->mnt_id, mnt->mnt_parent->mnt_id, |
1027 | MAJOR(sb->s_dev), MINOR(sb->s_dev)); | 1033 | MAJOR(sb->s_dev), MINOR(sb->s_dev)); |
1028 | seq_dentry(m, mnt->mnt_root, " \t\n\\"); | 1034 | if (sb->s_op->show_path) |
1035 | err = sb->s_op->show_path(m, mnt); | ||
1036 | else | ||
1037 | seq_dentry(m, mnt->mnt_root, " \t\n\\"); | ||
1038 | if (err) | ||
1039 | goto out; | ||
1029 | seq_putc(m, ' '); | 1040 | seq_putc(m, ' '); |
1030 | seq_path_root(m, &mnt_path, &root, " \t\n\\"); | 1041 | seq_path_root(m, &mnt_path, &root, " \t\n\\"); |
1031 | if (root.mnt != p->root.mnt || root.dentry != p->root.dentry) { | 1042 | if (root.mnt != p->root.mnt || root.dentry != p->root.dentry) { |
@@ -1060,7 +1071,12 @@ static int show_mountinfo(struct seq_file *m, void *v) | |||
1060 | seq_puts(m, " - "); | 1071 | seq_puts(m, " - "); |
1061 | show_type(m, sb); | 1072 | show_type(m, sb); |
1062 | seq_putc(m, ' '); | 1073 | seq_putc(m, ' '); |
1063 | mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); | 1074 | if (sb->s_op->show_devname) |
1075 | err = sb->s_op->show_devname(m, mnt); | ||
1076 | else | ||
1077 | mangle(m, mnt->mnt_devname ? mnt->mnt_devname : "none"); | ||
1078 | if (err) | ||
1079 | goto out; | ||
1064 | seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw"); | 1080 | seq_puts(m, sb->s_flags & MS_RDONLY ? " ro" : " rw"); |
1065 | err = show_sb_opts(m, sb); | 1081 | err = show_sb_opts(m, sb); |
1066 | if (err) | 1082 | if (err) |
@@ -1086,11 +1102,15 @@ static int show_vfsstat(struct seq_file *m, void *v) | |||
1086 | int err = 0; | 1102 | int err = 0; |
1087 | 1103 | ||
1088 | /* device */ | 1104 | /* device */ |
1089 | if (mnt->mnt_devname) { | 1105 | if (mnt->mnt_sb->s_op->show_devname) { |
1090 | seq_puts(m, "device "); | 1106 | err = mnt->mnt_sb->s_op->show_devname(m, mnt); |
1091 | mangle(m, mnt->mnt_devname); | 1107 | } else { |
1092 | } else | 1108 | if (mnt->mnt_devname) { |
1093 | seq_puts(m, "no device"); | 1109 | seq_puts(m, "device "); |
1110 | mangle(m, mnt->mnt_devname); | ||
1111 | } else | ||
1112 | seq_puts(m, "no device"); | ||
1113 | } | ||
1094 | 1114 | ||
1095 | /* mount point */ | 1115 | /* mount point */ |
1096 | seq_puts(m, " mounted on "); | 1116 | seq_puts(m, " mounted on "); |
@@ -1104,7 +1124,8 @@ static int show_vfsstat(struct seq_file *m, void *v) | |||
1104 | /* optional statistics */ | 1124 | /* optional statistics */ |
1105 | if (mnt->mnt_sb->s_op->show_stats) { | 1125 | if (mnt->mnt_sb->s_op->show_stats) { |
1106 | seq_putc(m, ' '); | 1126 | seq_putc(m, ' '); |
1107 | err = mnt->mnt_sb->s_op->show_stats(m, mnt); | 1127 | if (!err) |
1128 | err = mnt->mnt_sb->s_op->show_stats(m, mnt); | ||
1108 | } | 1129 | } |
1109 | 1130 | ||
1110 | seq_putc(m, '\n'); | 1131 | seq_putc(m, '\n'); |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index a6ab483c9ad0..79bc61fe2868 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -263,6 +263,8 @@ static match_table_t nfs_local_lock_tokens = { | |||
263 | static void nfs_umount_begin(struct super_block *); | 263 | static void nfs_umount_begin(struct super_block *); |
264 | static int nfs_statfs(struct dentry *, struct kstatfs *); | 264 | static int nfs_statfs(struct dentry *, struct kstatfs *); |
265 | static int nfs_show_options(struct seq_file *, struct vfsmount *); | 265 | static int nfs_show_options(struct seq_file *, struct vfsmount *); |
266 | static int nfs_show_devname(struct seq_file *, struct vfsmount *); | ||
267 | static int nfs_show_path(struct seq_file *, struct vfsmount *); | ||
266 | static int nfs_show_stats(struct seq_file *, struct vfsmount *); | 268 | static int nfs_show_stats(struct seq_file *, struct vfsmount *); |
267 | static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); | 269 | static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *); |
268 | static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type, | 270 | static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type, |
@@ -296,6 +298,8 @@ static const struct super_operations nfs_sops = { | |||
296 | .evict_inode = nfs_evict_inode, | 298 | .evict_inode = nfs_evict_inode, |
297 | .umount_begin = nfs_umount_begin, | 299 | .umount_begin = nfs_umount_begin, |
298 | .show_options = nfs_show_options, | 300 | .show_options = nfs_show_options, |
301 | .show_devname = nfs_show_devname, | ||
302 | .show_path = nfs_show_path, | ||
299 | .show_stats = nfs_show_stats, | 303 | .show_stats = nfs_show_stats, |
300 | .remount_fs = nfs_remount, | 304 | .remount_fs = nfs_remount, |
301 | }; | 305 | }; |
@@ -366,6 +370,8 @@ static const struct super_operations nfs4_sops = { | |||
366 | .evict_inode = nfs4_evict_inode, | 370 | .evict_inode = nfs4_evict_inode, |
367 | .umount_begin = nfs_umount_begin, | 371 | .umount_begin = nfs_umount_begin, |
368 | .show_options = nfs_show_options, | 372 | .show_options = nfs_show_options, |
373 | .show_devname = nfs_show_devname, | ||
374 | .show_path = nfs_show_path, | ||
369 | .show_stats = nfs_show_stats, | 375 | .show_stats = nfs_show_stats, |
370 | .remount_fs = nfs_remount, | 376 | .remount_fs = nfs_remount, |
371 | }; | 377 | }; |
@@ -726,6 +732,28 @@ static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt) | |||
726 | return 0; | 732 | return 0; |
727 | } | 733 | } |
728 | 734 | ||
735 | static int nfs_show_devname(struct seq_file *m, struct vfsmount *mnt) | ||
736 | { | ||
737 | char *page = (char *) __get_free_page(GFP_KERNEL); | ||
738 | char *devname, *dummy; | ||
739 | int err = 0; | ||
740 | if (!page) | ||
741 | return -ENOMEM; | ||
742 | devname = nfs_path(&dummy, mnt->mnt_root, page, PAGE_SIZE); | ||
743 | if (IS_ERR(devname)) | ||
744 | err = PTR_ERR(devname); | ||
745 | else | ||
746 | seq_escape(m, devname, " \t\n\\"); | ||
747 | free_page((unsigned long)page); | ||
748 | return err; | ||
749 | } | ||
750 | |||
751 | static int nfs_show_path(struct seq_file *m, struct vfsmount *mnt) | ||
752 | { | ||
753 | seq_puts(m, "/"); | ||
754 | return 0; | ||
755 | } | ||
756 | |||
729 | /* | 757 | /* |
730 | * Present statistical information for this VFS mountpoint | 758 | * Present statistical information for this VFS mountpoint |
731 | */ | 759 | */ |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 13df14e2c42e..e6d3fe45981b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1632,6 +1632,8 @@ struct super_operations { | |||
1632 | void (*umount_begin) (struct super_block *); | 1632 | void (*umount_begin) (struct super_block *); |
1633 | 1633 | ||
1634 | int (*show_options)(struct seq_file *, struct vfsmount *); | 1634 | int (*show_options)(struct seq_file *, struct vfsmount *); |
1635 | int (*show_devname)(struct seq_file *, struct vfsmount *); | ||
1636 | int (*show_path)(struct seq_file *, struct vfsmount *); | ||
1635 | int (*show_stats)(struct seq_file *, struct vfsmount *); | 1637 | int (*show_stats)(struct seq_file *, struct vfsmount *); |
1636 | #ifdef CONFIG_QUOTA | 1638 | #ifdef CONFIG_QUOTA |
1637 | ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); | 1639 | ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); |