]>
Commit | Line | Data |
---|---|---|
68184a5a JR |
1 | From aa88a112a579b0122e62eff87d581fcca11ad805 Mon Sep 17 00:00:00 2001 |
2 | From: Erez Zadok <ezk@fsl.cs.sunysb.edu> | |
3 | Date: Mon, 23 May 2011 20:59:20 -0400 | |
4 | Subject: [PATCH 06/13] overlayfs: implement show_options | |
5 | Patch-mainline: not yet | |
6 | ||
7 | This is useful because of the stacking nature of overlayfs. Users like to | |
8 | find out (via /proc/mounts) which lower/upper directory were used at mount | |
9 | time. | |
10 | ||
11 | Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu> | |
12 | Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> | |
13 | --- | |
14 | fs/overlayfs/super.c | 63 ++++++++++++++++++++++++++++++++++----------------- | |
15 | 1 file changed, 43 insertions(+), 20 deletions(-) | |
16 | ||
17 | Index: linux-3.6-rc7-master/fs/overlayfs/super.c | |
18 | =================================================================== | |
19 | --- linux-3.6-rc7-master.orig/fs/overlayfs/super.c 2012-09-28 13:36:55.000000000 +0200 | |
20 | +++ linux-3.6-rc7-master/fs/overlayfs/super.c 2012-09-28 13:36:57.000000000 +0200 | |
21 | @@ -18,6 +18,7 @@ | |
22 | #include <linux/cred.h> | |
23 | #include <linux/sched.h> | |
24 | #include <linux/statfs.h> | |
25 | +#include <linux/seq_file.h> | |
26 | #include "overlayfs.h" | |
27 | ||
28 | MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); | |
29 | @@ -26,12 +27,21 @@ MODULE_LICENSE("GPL"); | |
30 | ||
31 | #define OVERLAYFS_SUPER_MAGIC 0x794c764f | |
32 | ||
33 | +struct ovl_config { | |
34 | + char *lowerdir; | |
35 | + char *upperdir; | |
36 | +}; | |
37 | + | |
38 | +/* private information held for overlayfs's superblock */ | |
39 | struct ovl_fs { | |
40 | struct vfsmount *upper_mnt; | |
41 | struct vfsmount *lower_mnt; | |
42 | long lower_namelen; | |
43 | + /* pathnames of lower and upper dirs, for show_options */ | |
44 | + struct ovl_config config; | |
45 | }; | |
46 | ||
47 | +/* private information held for every overlayfs dentry */ | |
48 | struct ovl_entry { | |
49 | /* | |
50 | * Keep "double reference" on upper dentries, so that | |
51 | @@ -388,6 +398,8 @@ static void ovl_put_super(struct super_b | |
52 | mntput(ufs->upper_mnt); | |
53 | mntput(ufs->lower_mnt); | |
54 | ||
55 | + kfree(ufs->config.lowerdir); | |
56 | + kfree(ufs->config.upperdir); | |
57 | kfree(ufs); | |
58 | } | |
59 | ||
60 | @@ -436,15 +448,27 @@ static int ovl_statfs(struct dentry *den | |
61 | return err; | |
62 | } | |
63 | ||
64 | +/** | |
65 | + * ovl_show_options | |
66 | + * | |
67 | + * Prints the mount options for a given superblock. | |
68 | + * Returns zero; does not fail. | |
69 | + */ | |
70 | +static int ovl_show_options(struct seq_file *m, struct dentry *dentry) | |
71 | +{ | |
72 | + struct super_block *sb = dentry->d_sb; | |
73 | + struct ovl_fs *ufs = sb->s_fs_info; | |
74 | + | |
75 | + seq_printf(m, ",lowerdir=%s", ufs->config.lowerdir); | |
76 | + seq_printf(m, ",upperdir=%s", ufs->config.upperdir); | |
77 | + return 0; | |
78 | +} | |
79 | + | |
80 | static const struct super_operations ovl_super_operations = { | |
81 | .put_super = ovl_put_super, | |
82 | .remount_fs = ovl_remount_fs, | |
83 | .statfs = ovl_statfs, | |
84 | -}; | |
85 | - | |
86 | -struct ovl_config { | |
87 | - char *lowerdir; | |
88 | - char *upperdir; | |
89 | + .show_options = ovl_show_options, | |
90 | }; | |
91 | ||
92 | enum { | |
93 | @@ -504,34 +528,33 @@ static int ovl_fill_super(struct super_b | |
94 | struct dentry *root_dentry; | |
95 | struct ovl_entry *oe; | |
96 | struct ovl_fs *ufs; | |
97 | - struct ovl_config config; | |
98 | struct kstatfs statfs; | |
99 | int err; | |
100 | ||
101 | - err = ovl_parse_opt((char *) data, &config); | |
102 | - if (err) | |
103 | + err = -ENOMEM; | |
104 | + ufs = kmalloc(sizeof(struct ovl_fs), GFP_KERNEL); | |
105 | + if (!ufs) | |
106 | goto out; | |
107 | ||
108 | + err = ovl_parse_opt((char *) data, &ufs->config); | |
109 | + if (err) | |
110 | + goto out_free_ufs; | |
111 | + | |
112 | err = -EINVAL; | |
113 | - if (!config.upperdir || !config.lowerdir) { | |
114 | + if (!ufs->config.upperdir || !ufs->config.lowerdir) { | |
115 | printk(KERN_ERR "overlayfs: missing upperdir or lowerdir\n"); | |
116 | goto out_free_config; | |
117 | } | |
118 | ||
119 | - err = -ENOMEM; | |
120 | - ufs = kmalloc(sizeof(struct ovl_fs), GFP_KERNEL); | |
121 | - if (!ufs) | |
122 | - goto out_free_config; | |
123 | - | |
124 | oe = ovl_alloc_entry(); | |
125 | if (oe == NULL) | |
126 | - goto out_free_ufs; | |
127 | + goto out_free_config; | |
128 | ||
129 | - err = kern_path(config.upperdir, LOOKUP_FOLLOW, &upperpath); | |
130 | + err = kern_path(ufs->config.upperdir, LOOKUP_FOLLOW, &upperpath); | |
131 | if (err) | |
132 | goto out_free_oe; | |
133 | ||
134 | - err = kern_path(config.lowerdir, LOOKUP_FOLLOW, &lowerpath); | |
135 | + err = kern_path(ufs->config.lowerdir, LOOKUP_FOLLOW, &lowerpath); | |
136 | if (err) | |
137 | goto out_put_upperpath; | |
138 | ||
139 | @@ -615,11 +638,11 @@ static int ovl_fill_super(struct super_b | |
140 | path_put(&upperpath); | |
141 | out_free_oe: | |
142 | kfree(oe); | |
143 | +out_free_config: | |
144 | + kfree(ufs->config.lowerdir); | |
145 | + kfree(ufs->config.upperdir); | |
146 | out_free_ufs: | |
147 | kfree(ufs); | |
148 | -out_free_config: | |
149 | - kfree(config.lowerdir); | |
150 | - kfree(config.upperdir); | |
151 | out: | |
152 | return err; | |
153 | } |