aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-07-02 14:23:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-07-02 14:23:00 -0400
commit320cd413faefe2d30f4ee9651efddec5141bc95b (patch)
tree7bd339c24aff9bed4204c3f20f65f692a076db20
parenta7ba4bf5e7ff6bfe83e41c748b77b49297c1b5d9 (diff)
parentcdb672795876d7bc1870aed9a2d7cb59f43d1d96 (diff)
Merge branch 'overlayfs-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs updates from Miklos Szeredi: "This relaxes the requirements on the lower layer filesystem: now ones that implement .d_revalidate, such as NFS, can be used. Upper layer filesystems still has the "no .d_revalidate" requirement. Also a bad interaction with jffs2 locking has been fixed" * 'overlayfs-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: ovl: lookup whiteouts outside iterate_dir() ovl: allow distributed fs as lower layer ovl: don't traverse automount points
-rw-r--r--fs/overlayfs/readdir.c77
-rw-r--r--fs/overlayfs/super.c113
2 files changed, 139 insertions, 51 deletions
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
index 907870e81a72..70e9af551600 100644
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -23,6 +23,7 @@ struct ovl_cache_entry {
23 u64 ino; 23 u64 ino;
24 struct list_head l_node; 24 struct list_head l_node;
25 struct rb_node node; 25 struct rb_node node;
26 struct ovl_cache_entry *next_maybe_whiteout;
26 bool is_whiteout; 27 bool is_whiteout;
27 char name[]; 28 char name[];
28}; 29};
@@ -39,7 +40,7 @@ struct ovl_readdir_data {
39 struct rb_root root; 40 struct rb_root root;
40 struct list_head *list; 41 struct list_head *list;
41 struct list_head middle; 42 struct list_head middle;
42 struct dentry *dir; 43 struct ovl_cache_entry *first_maybe_whiteout;
43 int count; 44 int count;
44 int err; 45 int err;
45}; 46};
@@ -79,7 +80,7 @@ static struct ovl_cache_entry *ovl_cache_entry_find(struct rb_root *root,
79 return NULL; 80 return NULL;
80} 81}
81 82
82static struct ovl_cache_entry *ovl_cache_entry_new(struct dentry *dir, 83static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd,
83 const char *name, int len, 84 const char *name, int len,
84 u64 ino, unsigned int d_type) 85 u64 ino, unsigned int d_type)
85{ 86{
@@ -98,29 +99,8 @@ static struct ovl_cache_entry *ovl_cache_entry_new(struct dentry *dir,
98 p->is_whiteout = false; 99 p->is_whiteout = false;
99 100
100 if (d_type == DT_CHR) { 101 if (d_type == DT_CHR) {
101 struct dentry *dentry; 102 p->next_maybe_whiteout = rdd->first_maybe_whiteout;
102 const struct cred *old_cred; 103 rdd->first_maybe_whiteout = p;
103 struct cred *override_cred;
104
105 override_cred = prepare_creds();
106 if (!override_cred) {
107 kfree(p);
108 return NULL;
109 }
110
111 /*
112 * CAP_DAC_OVERRIDE for lookup
113 */
114 cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE);
115 old_cred = override_creds(override_cred);
116
117 dentry = lookup_one_len(name, dir, len);
118 if (!IS_ERR(dentry)) {
119 p->is_whiteout = ovl_is_whiteout(dentry);
120 dput(dentry);
121 }
122 revert_creds(old_cred);
123 put_cred(override_cred);
124 } 104 }
125 return p; 105 return p;
126} 106}
@@ -148,7 +128,7 @@ static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
148 return 0; 128 return 0;
149 } 129 }
150 130
151 p = ovl_cache_entry_new(rdd->dir, name, len, ino, d_type); 131 p = ovl_cache_entry_new(rdd, name, len, ino, d_type);
152 if (p == NULL) 132 if (p == NULL)
153 return -ENOMEM; 133 return -ENOMEM;
154 134
@@ -169,7 +149,7 @@ static int ovl_fill_lower(struct ovl_readdir_data *rdd,
169 if (p) { 149 if (p) {
170 list_move_tail(&p->l_node, &rdd->middle); 150 list_move_tail(&p->l_node, &rdd->middle);
171 } else { 151 } else {
172 p = ovl_cache_entry_new(rdd->dir, name, namelen, ino, d_type); 152 p = ovl_cache_entry_new(rdd, name, namelen, ino, d_type);
173 if (p == NULL) 153 if (p == NULL)
174 rdd->err = -ENOMEM; 154 rdd->err = -ENOMEM;
175 else 155 else
@@ -219,6 +199,43 @@ static int ovl_fill_merge(struct dir_context *ctx, const char *name,
219 return ovl_fill_lower(rdd, name, namelen, offset, ino, d_type); 199 return ovl_fill_lower(rdd, name, namelen, offset, ino, d_type);
220} 200}
221 201
202static int ovl_check_whiteouts(struct dentry *dir, struct ovl_readdir_data *rdd)
203{
204 int err;
205 struct ovl_cache_entry *p;
206 struct dentry *dentry;
207 const struct cred *old_cred;
208 struct cred *override_cred;
209
210 override_cred = prepare_creds();
211 if (!override_cred)
212 return -ENOMEM;
213
214 /*
215 * CAP_DAC_OVERRIDE for lookup
216 */
217 cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE);
218 old_cred = override_creds(override_cred);
219
220 err = mutex_lock_killable(&dir->d_inode->i_mutex);
221 if (!err) {
222 while (rdd->first_maybe_whiteout) {
223 p = rdd->first_maybe_whiteout;
224 rdd->first_maybe_whiteout = p->next_maybe_whiteout;
225 dentry = lookup_one_len(p->name, dir, p->len);
226 if (!IS_ERR(dentry)) {
227 p->is_whiteout = ovl_is_whiteout(dentry);
228 dput(dentry);
229 }
230 }
231 mutex_unlock(&dir->d_inode->i_mutex);
232 }
233 revert_creds(old_cred);
234 put_cred(override_cred);
235
236 return err;
237}
238
222static inline int ovl_dir_read(struct path *realpath, 239static inline int ovl_dir_read(struct path *realpath,
223 struct ovl_readdir_data *rdd) 240 struct ovl_readdir_data *rdd)
224{ 241{
@@ -229,7 +246,7 @@ static inline int ovl_dir_read(struct path *realpath,
229 if (IS_ERR(realfile)) 246 if (IS_ERR(realfile))
230 return PTR_ERR(realfile); 247 return PTR_ERR(realfile);
231 248
232 rdd->dir = realpath->dentry; 249 rdd->first_maybe_whiteout = NULL;
233 rdd->ctx.pos = 0; 250 rdd->ctx.pos = 0;
234 do { 251 do {
235 rdd->count = 0; 252 rdd->count = 0;
@@ -238,6 +255,10 @@ static inline int ovl_dir_read(struct path *realpath,
238 if (err >= 0) 255 if (err >= 0)
239 err = rdd->err; 256 err = rdd->err;
240 } while (!err && rdd->count); 257 } while (!err && rdd->count);
258
259 if (!err && rdd->first_maybe_whiteout)
260 err = ovl_check_whiteouts(realpath->dentry, rdd);
261
241 fput(realfile); 262 fput(realfile);
242 263
243 return err; 264 return err;
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index bf8537c7f455..8a08c582bc22 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -273,10 +273,57 @@ static void ovl_dentry_release(struct dentry *dentry)
273 } 273 }
274} 274}
275 275
276static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags)
277{
278 struct ovl_entry *oe = dentry->d_fsdata;
279 unsigned int i;
280 int ret = 1;
281
282 for (i = 0; i < oe->numlower; i++) {
283 struct dentry *d = oe->lowerstack[i].dentry;
284
285 if (d->d_flags & DCACHE_OP_REVALIDATE) {
286 ret = d->d_op->d_revalidate(d, flags);
287 if (ret < 0)
288 return ret;
289 if (!ret) {
290 if (!(flags & LOOKUP_RCU))
291 d_invalidate(d);
292 return -ESTALE;
293 }
294 }
295 }
296 return 1;
297}
298
299static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags)
300{
301 struct ovl_entry *oe = dentry->d_fsdata;
302 unsigned int i;
303 int ret = 1;
304
305 for (i = 0; i < oe->numlower; i++) {
306 struct dentry *d = oe->lowerstack[i].dentry;
307
308 if (d->d_flags & DCACHE_OP_WEAK_REVALIDATE) {
309 ret = d->d_op->d_weak_revalidate(d, flags);
310 if (ret <= 0)
311 break;
312 }
313 }
314 return ret;
315}
316
276static const struct dentry_operations ovl_dentry_operations = { 317static const struct dentry_operations ovl_dentry_operations = {
277 .d_release = ovl_dentry_release, 318 .d_release = ovl_dentry_release,
278}; 319};
279 320
321static const struct dentry_operations ovl_reval_dentry_operations = {
322 .d_release = ovl_dentry_release,
323 .d_revalidate = ovl_dentry_revalidate,
324 .d_weak_revalidate = ovl_dentry_weak_revalidate,
325};
326
280static struct ovl_entry *ovl_alloc_entry(unsigned int numlower) 327static struct ovl_entry *ovl_alloc_entry(unsigned int numlower)
281{ 328{
282 size_t size = offsetof(struct ovl_entry, lowerstack[numlower]); 329 size_t size = offsetof(struct ovl_entry, lowerstack[numlower]);
@@ -288,6 +335,20 @@ static struct ovl_entry *ovl_alloc_entry(unsigned int numlower)
288 return oe; 335 return oe;
289} 336}
290 337
338static bool ovl_dentry_remote(struct dentry *dentry)
339{
340 return dentry->d_flags &
341 (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
342}
343
344static bool ovl_dentry_weird(struct dentry *dentry)
345{
346 return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT |
347 DCACHE_MANAGE_TRANSIT |
348 DCACHE_OP_HASH |
349 DCACHE_OP_COMPARE);
350}
351
291static inline struct dentry *ovl_lookup_real(struct dentry *dir, 352static inline struct dentry *ovl_lookup_real(struct dentry *dir,
292 struct qstr *name) 353 struct qstr *name)
293{ 354{
@@ -303,6 +364,10 @@ static inline struct dentry *ovl_lookup_real(struct dentry *dir,
303 } else if (!dentry->d_inode) { 364 } else if (!dentry->d_inode) {
304 dput(dentry); 365 dput(dentry);
305 dentry = NULL; 366 dentry = NULL;
367 } else if (ovl_dentry_weird(dentry)) {
368 dput(dentry);
369 /* Don't support traversing automounts and other weirdness */
370 dentry = ERR_PTR(-EREMOTE);
306 } 371 }
307 return dentry; 372 return dentry;
308} 373}
@@ -350,6 +415,11 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
350 goto out; 415 goto out;
351 416
352 if (this) { 417 if (this) {
418 if (unlikely(ovl_dentry_remote(this))) {
419 dput(this);
420 err = -EREMOTE;
421 goto out;
422 }
353 if (ovl_is_whiteout(this)) { 423 if (ovl_is_whiteout(this)) {
354 dput(this); 424 dput(this);
355 this = NULL; 425 this = NULL;
@@ -694,25 +764,6 @@ static void ovl_unescape(char *s)
694 } 764 }
695} 765}
696 766
697static bool ovl_is_allowed_fs_type(struct dentry *root)
698{
699 const struct dentry_operations *dop = root->d_op;
700
701 /*
702 * We don't support:
703 * - automount filesystems
704 * - filesystems with revalidate (FIXME for lower layer)
705 * - filesystems with case insensitive names
706 */
707 if (dop &&
708 (dop->d_manage || dop->d_automount ||
709 dop->d_revalidate || dop->d_weak_revalidate ||
710 dop->d_compare || dop->d_hash)) {
711 return false;
712 }
713 return true;
714}
715
716static int ovl_mount_dir_noesc(const char *name, struct path *path) 767static int ovl_mount_dir_noesc(const char *name, struct path *path)
717{ 768{
718 int err = -EINVAL; 769 int err = -EINVAL;
@@ -727,7 +778,7 @@ static int ovl_mount_dir_noesc(const char *name, struct path *path)
727 goto out; 778 goto out;
728 } 779 }
729 err = -EINVAL; 780 err = -EINVAL;
730 if (!ovl_is_allowed_fs_type(path->dentry)) { 781 if (ovl_dentry_weird(path->dentry)) {
731 pr_err("overlayfs: filesystem on '%s' not supported\n", name); 782 pr_err("overlayfs: filesystem on '%s' not supported\n", name);
732 goto out_put; 783 goto out_put;
733 } 784 }
@@ -751,13 +802,21 @@ static int ovl_mount_dir(const char *name, struct path *path)
751 if (tmp) { 802 if (tmp) {
752 ovl_unescape(tmp); 803 ovl_unescape(tmp);
753 err = ovl_mount_dir_noesc(tmp, path); 804 err = ovl_mount_dir_noesc(tmp, path);
805
806 if (!err)
807 if (ovl_dentry_remote(path->dentry)) {
808 pr_err("overlayfs: filesystem on '%s' not supported as upperdir\n",
809 tmp);
810 path_put(path);
811 err = -EINVAL;
812 }
754 kfree(tmp); 813 kfree(tmp);
755 } 814 }
756 return err; 815 return err;
757} 816}
758 817
759static int ovl_lower_dir(const char *name, struct path *path, long *namelen, 818static int ovl_lower_dir(const char *name, struct path *path, long *namelen,
760 int *stack_depth) 819 int *stack_depth, bool *remote)
761{ 820{
762 int err; 821 int err;
763 struct kstatfs statfs; 822 struct kstatfs statfs;
@@ -774,6 +833,9 @@ static int ovl_lower_dir(const char *name, struct path *path, long *namelen,
774 *namelen = max(*namelen, statfs.f_namelen); 833 *namelen = max(*namelen, statfs.f_namelen);
775 *stack_depth = max(*stack_depth, path->mnt->mnt_sb->s_stack_depth); 834 *stack_depth = max(*stack_depth, path->mnt->mnt_sb->s_stack_depth);
776 835
836 if (ovl_dentry_remote(path->dentry))
837 *remote = true;
838
777 return 0; 839 return 0;
778 840
779out_put: 841out_put:
@@ -827,6 +889,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
827 unsigned int numlower; 889 unsigned int numlower;
828 unsigned int stacklen = 0; 890 unsigned int stacklen = 0;
829 unsigned int i; 891 unsigned int i;
892 bool remote = false;
830 int err; 893 int err;
831 894
832 err = -ENOMEM; 895 err = -ENOMEM;
@@ -900,7 +963,8 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
900 lower = lowertmp; 963 lower = lowertmp;
901 for (numlower = 0; numlower < stacklen; numlower++) { 964 for (numlower = 0; numlower < stacklen; numlower++) {
902 err = ovl_lower_dir(lower, &stack[numlower], 965 err = ovl_lower_dir(lower, &stack[numlower],
903 &ufs->lower_namelen, &sb->s_stack_depth); 966 &ufs->lower_namelen, &sb->s_stack_depth,
967 &remote);
904 if (err) 968 if (err)
905 goto out_put_lowerpath; 969 goto out_put_lowerpath;
906 970
@@ -958,7 +1022,10 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
958 if (!ufs->upper_mnt) 1022 if (!ufs->upper_mnt)
959 sb->s_flags |= MS_RDONLY; 1023 sb->s_flags |= MS_RDONLY;
960 1024
961 sb->s_d_op = &ovl_dentry_operations; 1025 if (remote)
1026 sb->s_d_op = &ovl_reval_dentry_operations;
1027 else
1028 sb->s_d_op = &ovl_dentry_operations;
962 1029
963 err = -ENOMEM; 1030 err = -ENOMEM;
964 oe = ovl_alloc_entry(numlower); 1031 oe = ovl_alloc_entry(numlower);