diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2008-02-08 07:21:35 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-08 12:22:39 -0500 |
commit | b3b304a23a8f7ae4c40c7b512ee45afae0010a70 (patch) | |
tree | 04ada9ae35e912b6c3d56c0aefdc297216f2e0a5 | |
parent | f84e3f521e1449300e0fdc314b7b43b418a66dc3 (diff) |
mount options: add generic_show_options()
Add a new s_options field to struct super_block. Filesystems can save
mount options passed to them in mount or remount. It is automatically
freed when the superblock is destroyed.
A new helper function, generic_show_options() is introduced, which uses
this field to display the mount options in /proc/mounts.
Another helper function, save_mount_options() may be used by
filesystems to save the options in the super block.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/namespace.c | 49 | ||||
-rw-r--r-- | fs/super.c | 1 | ||||
-rw-r--r-- | include/linux/fs.h | 9 |
3 files changed, 54 insertions, 5 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index e9c10cd01e13..db51ddc9b671 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -320,6 +320,50 @@ void mnt_unpin(struct vfsmount *mnt) | |||
320 | 320 | ||
321 | EXPORT_SYMBOL(mnt_unpin); | 321 | EXPORT_SYMBOL(mnt_unpin); |
322 | 322 | ||
323 | static inline void mangle(struct seq_file *m, const char *s) | ||
324 | { | ||
325 | seq_escape(m, s, " \t\n\\"); | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * Simple .show_options callback for filesystems which don't want to | ||
330 | * implement more complex mount option showing. | ||
331 | * | ||
332 | * See also save_mount_options(). | ||
333 | */ | ||
334 | int generic_show_options(struct seq_file *m, struct vfsmount *mnt) | ||
335 | { | ||
336 | const char *options = mnt->mnt_sb->s_options; | ||
337 | |||
338 | if (options != NULL && options[0]) { | ||
339 | seq_putc(m, ','); | ||
340 | mangle(m, options); | ||
341 | } | ||
342 | |||
343 | return 0; | ||
344 | } | ||
345 | EXPORT_SYMBOL(generic_show_options); | ||
346 | |||
347 | /* | ||
348 | * If filesystem uses generic_show_options(), this function should be | ||
349 | * called from the fill_super() callback. | ||
350 | * | ||
351 | * The .remount_fs callback usually needs to be handled in a special | ||
352 | * way, to make sure, that previous options are not overwritten if the | ||
353 | * remount fails. | ||
354 | * | ||
355 | * Also note, that if the filesystem's .remount_fs function doesn't | ||
356 | * reset all options to their default value, but changes only newly | ||
357 | * given options, then the displayed options will not reflect reality | ||
358 | * any more. | ||
359 | */ | ||
360 | void save_mount_options(struct super_block *sb, char *options) | ||
361 | { | ||
362 | kfree(sb->s_options); | ||
363 | sb->s_options = kstrdup(options, GFP_KERNEL); | ||
364 | } | ||
365 | EXPORT_SYMBOL(save_mount_options); | ||
366 | |||
323 | /* iterator */ | 367 | /* iterator */ |
324 | static void *m_start(struct seq_file *m, loff_t *pos) | 368 | static void *m_start(struct seq_file *m, loff_t *pos) |
325 | { | 369 | { |
@@ -341,11 +385,6 @@ static void m_stop(struct seq_file *m, void *v) | |||
341 | up_read(&namespace_sem); | 385 | up_read(&namespace_sem); |
342 | } | 386 | } |
343 | 387 | ||
344 | static inline void mangle(struct seq_file *m, const char *s) | ||
345 | { | ||
346 | seq_escape(m, s, " \t\n\\"); | ||
347 | } | ||
348 | |||
349 | static int show_vfsmnt(struct seq_file *m, void *v) | 388 | static int show_vfsmnt(struct seq_file *m, void *v) |
350 | { | 389 | { |
351 | struct vfsmount *mnt = list_entry(v, struct vfsmount, mnt_list); | 390 | struct vfsmount *mnt = list_entry(v, struct vfsmount, mnt_list); |
diff --git a/fs/super.c b/fs/super.c index ceaf2e3d594c..65f6849847f4 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -105,6 +105,7 @@ static inline void destroy_super(struct super_block *s) | |||
105 | { | 105 | { |
106 | security_sb_free(s); | 106 | security_sb_free(s); |
107 | kfree(s->s_subtype); | 107 | kfree(s->s_subtype); |
108 | kfree(s->s_options); | ||
108 | kfree(s); | 109 | kfree(s); |
109 | } | 110 | } |
110 | 111 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 3db22fc2249a..cb3a9001f3b9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1038,6 +1038,12 @@ struct super_block { | |||
1038 | * in /proc/mounts will be "type.subtype" | 1038 | * in /proc/mounts will be "type.subtype" |
1039 | */ | 1039 | */ |
1040 | char *s_subtype; | 1040 | char *s_subtype; |
1041 | |||
1042 | /* | ||
1043 | * Saved mount options for lazy filesystems using | ||
1044 | * generic_show_options() | ||
1045 | */ | ||
1046 | char *s_options; | ||
1041 | }; | 1047 | }; |
1042 | 1048 | ||
1043 | extern struct timespec current_fs_time(struct super_block *sb); | 1049 | extern struct timespec current_fs_time(struct super_block *sb); |
@@ -1970,6 +1976,9 @@ extern int __must_check inode_setattr(struct inode *, struct iattr *); | |||
1970 | 1976 | ||
1971 | extern void file_update_time(struct file *file); | 1977 | extern void file_update_time(struct file *file); |
1972 | 1978 | ||
1979 | extern int generic_show_options(struct seq_file *m, struct vfsmount *mnt); | ||
1980 | extern void save_mount_options(struct super_block *sb, char *options); | ||
1981 | |||
1973 | static inline ino_t parent_ino(struct dentry *dentry) | 1982 | static inline ino_t parent_ino(struct dentry *dentry) |
1974 | { | 1983 | { |
1975 | ino_t res; | 1984 | ino_t res; |