aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/namespace.c49
-rw-r--r--fs/super.c1
-rw-r--r--include/linux/fs.h9
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
321EXPORT_SYMBOL(mnt_unpin); 321EXPORT_SYMBOL(mnt_unpin);
322 322
323static 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 */
334int 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}
345EXPORT_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 */
360void save_mount_options(struct super_block *sb, char *options)
361{
362 kfree(sb->s_options);
363 sb->s_options = kstrdup(options, GFP_KERNEL);
364}
365EXPORT_SYMBOL(save_mount_options);
366
323/* iterator */ 367/* iterator */
324static void *m_start(struct seq_file *m, loff_t *pos) 368static 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
344static inline void mangle(struct seq_file *m, const char *s)
345{
346 seq_escape(m, s, " \t\n\\");
347}
348
349static int show_vfsmnt(struct seq_file *m, void *v) 388static 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
1043extern struct timespec current_fs_time(struct super_block *sb); 1049extern 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
1971extern void file_update_time(struct file *file); 1977extern void file_update_time(struct file *file);
1972 1978
1979extern int generic_show_options(struct seq_file *m, struct vfsmount *mnt);
1980extern void save_mount_options(struct super_block *sb, char *options);
1981
1973static inline ino_t parent_ino(struct dentry *dentry) 1982static inline ino_t parent_ino(struct dentry *dentry)
1974{ 1983{
1975 ino_t res; 1984 ino_t res;