Blame view

fs/overlayfs/super.c 31.6 KB
e9be9d5e7   Miklos Szeredi   overlay filesystem
1
2
3
4
5
6
7
8
9
10
11
  /*
   *
   * Copyright (C) 2011 Novell Inc.
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 as published by
   * the Free Software Foundation.
   */
  
  #include <linux/fs.h>
  #include <linux/namei.h>
cf9a6784f   Miklos Szeredi   ovl: setattr: che...
12
  #include <linux/pagemap.h>
e9be9d5e7   Miklos Szeredi   overlay filesystem
13
14
15
16
17
18
19
  #include <linux/xattr.h>
  #include <linux/security.h>
  #include <linux/mount.h>
  #include <linux/slab.h>
  #include <linux/parser.h>
  #include <linux/module.h>
  #include <linux/sched.h>
cc2596392   Andy Whitcroft   overlayfs: add st...
20
  #include <linux/statfs.h>
f45827e84   Erez Zadok   overlayfs: implem...
21
  #include <linux/seq_file.h>
d837a49bd   Miklos Szeredi   ovl: fix POSIX AC...
22
  #include <linux/posix_acl_xattr.h>
e9be9d5e7   Miklos Szeredi   overlay filesystem
23
24
25
26
27
  #include "overlayfs.h"
  
  MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
  MODULE_DESCRIPTION("Overlay filesystem");
  MODULE_LICENSE("GPL");
f45827e84   Erez Zadok   overlayfs: implem...
28
29
30
31
  struct ovl_config {
  	char *lowerdir;
  	char *upperdir;
  	char *workdir;
8d3095f4a   Miklos Szeredi   ovl: default perm...
32
  	bool default_permissions;
f45827e84   Erez Zadok   overlayfs: implem...
33
  };
e9be9d5e7   Miklos Szeredi   overlay filesystem
34
35
36
  /* private information held for overlayfs's superblock */
  struct ovl_fs {
  	struct vfsmount *upper_mnt;
dd662667e   Miklos Szeredi   ovl: add mutli-la...
37
38
  	unsigned numlower;
  	struct vfsmount **lower_mnt;
e9be9d5e7   Miklos Szeredi   overlay filesystem
39
  	struct dentry *workdir;
cc2596392   Andy Whitcroft   overlayfs: add st...
40
  	long lower_namelen;
f45827e84   Erez Zadok   overlayfs: implem...
41
42
  	/* pathnames of lower and upper dirs, for show_options */
  	struct ovl_config config;
3fe6e52f0   Antonio Murdaca   ovl: override cre...
43
44
  	/* creds of process who forced instantiation of super block */
  	const struct cred *creator_cred;
e9be9d5e7   Miklos Szeredi   overlay filesystem
45
46
47
48
49
50
51
  };
  
  struct ovl_dir_cache;
  
  /* private information held for every overlayfs dentry */
  struct ovl_entry {
  	struct dentry *__upperdentry;
e9be9d5e7   Miklos Szeredi   overlay filesystem
52
53
54
55
56
57
58
59
  	struct ovl_dir_cache *cache;
  	union {
  		struct {
  			u64 version;
  			bool opaque;
  		};
  		struct rcu_head rcu;
  	};
dd662667e   Miklos Szeredi   ovl: add mutli-la...
60
61
  	unsigned numlower;
  	struct path lowerstack[];
e9be9d5e7   Miklos Szeredi   overlay filesystem
62
  };
a78d9f0d5   Miklos Szeredi   ovl: support mult...
63
  #define OVL_MAX_STACK 500
dd662667e   Miklos Szeredi   ovl: add mutli-la...
64
65
66
67
  static struct dentry *__ovl_dentry_lower(struct ovl_entry *oe)
  {
  	return oe->numlower ? oe->lowerstack[0].dentry : NULL;
  }
e9be9d5e7   Miklos Szeredi   overlay filesystem
68
69
70
71
  
  enum ovl_path_type ovl_path_type(struct dentry *dentry)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
1afaba1ec   Miklos Szeredi   ovl: make path-ty...
72
  	enum ovl_path_type type = 0;
e9be9d5e7   Miklos Szeredi   overlay filesystem
73
74
  
  	if (oe->__upperdentry) {
1afaba1ec   Miklos Szeredi   ovl: make path-ty...
75
  		type = __OVL_PATH_UPPER;
45d117389   Konstantin Khlebnikov   ovl: ignore lower...
76
77
78
79
80
81
82
  		/*
  		 * Non-dir dentry can hold lower dentry from previous
  		 * location. Its purity depends only on opaque flag.
  		 */
  		if (oe->numlower && S_ISDIR(dentry->d_inode->i_mode))
  			type |= __OVL_PATH_MERGE;
  		else if (!oe->opaque)
1afaba1ec   Miklos Szeredi   ovl: make path-ty...
83
  			type |= __OVL_PATH_PURE;
9d7459d83   Miklos Szeredi   ovl: multi-layer ...
84
85
86
  	} else {
  		if (oe->numlower > 1)
  			type |= __OVL_PATH_MERGE;
e9be9d5e7   Miklos Szeredi   overlay filesystem
87
  	}
1afaba1ec   Miklos Szeredi   ovl: make path-ty...
88
  	return type;
e9be9d5e7   Miklos Szeredi   overlay filesystem
89
90
91
92
  }
  
  static struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe)
  {
71d509280   Miklos Szeredi   ovl: use lockless...
93
  	return lockless_dereference(oe->__upperdentry);
e9be9d5e7   Miklos Szeredi   overlay filesystem
94
95
96
97
98
99
100
101
102
103
104
105
106
  }
  
  void ovl_path_upper(struct dentry *dentry, struct path *path)
  {
  	struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
  	struct ovl_entry *oe = dentry->d_fsdata;
  
  	path->mnt = ofs->upper_mnt;
  	path->dentry = ovl_upperdentry_dereference(oe);
  }
  
  enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path)
  {
e9be9d5e7   Miklos Szeredi   overlay filesystem
107
  	enum ovl_path_type type = ovl_path_type(dentry);
1afaba1ec   Miklos Szeredi   ovl: make path-ty...
108
  	if (!OVL_TYPE_UPPER(type))
e9be9d5e7   Miklos Szeredi   overlay filesystem
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
  		ovl_path_lower(dentry, path);
  	else
  		ovl_path_upper(dentry, path);
  
  	return type;
  }
  
  struct dentry *ovl_dentry_upper(struct dentry *dentry)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
  
  	return ovl_upperdentry_dereference(oe);
  }
  
  struct dentry *ovl_dentry_lower(struct dentry *dentry)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
dd662667e   Miklos Szeredi   ovl: add mutli-la...
126
  	return __ovl_dentry_lower(oe);
e9be9d5e7   Miklos Szeredi   overlay filesystem
127
128
129
130
131
132
133
134
135
  }
  
  struct dentry *ovl_dentry_real(struct dentry *dentry)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
  	struct dentry *realdentry;
  
  	realdentry = ovl_upperdentry_dereference(oe);
  	if (!realdentry)
dd662667e   Miklos Szeredi   ovl: add mutli-la...
136
  		realdentry = __ovl_dentry_lower(oe);
e9be9d5e7   Miklos Szeredi   overlay filesystem
137
138
139
  
  	return realdentry;
  }
39b681f80   Miklos Szeredi   ovl: store real i...
140
141
  static void ovl_inode_init(struct inode *inode, struct inode *realinode,
  			   bool is_upper)
e9be9d5e7   Miklos Szeredi   overlay filesystem
142
  {
39b681f80   Miklos Szeredi   ovl: store real i...
143
144
  	WRITE_ONCE(inode->i_private, (unsigned long) realinode |
  		   (is_upper ? OVL_ISUPPER_MASK : 0));
39a25b2b3   Vivek Goyal   ovl: define ->get...
145
  }
8d3095f4a   Miklos Szeredi   ovl: default perm...
146
147
148
149
150
151
152
153
154
155
156
  struct vfsmount *ovl_entry_mnt_real(struct ovl_entry *oe, struct inode *inode,
  				    bool is_upper)
  {
  	if (is_upper) {
  		struct ovl_fs *ofs = inode->i_sb->s_fs_info;
  
  		return ofs->upper_mnt;
  	} else {
  		return oe->numlower ? oe->lowerstack[0].mnt : NULL;
  	}
  }
e9be9d5e7   Miklos Szeredi   overlay filesystem
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  struct ovl_dir_cache *ovl_dir_cache(struct dentry *dentry)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
  
  	return oe->cache;
  }
  
  void ovl_set_dir_cache(struct dentry *dentry, struct ovl_dir_cache *cache)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
  
  	oe->cache = cache;
  }
  
  void ovl_path_lower(struct dentry *dentry, struct path *path)
  {
e9be9d5e7   Miklos Szeredi   overlay filesystem
173
  	struct ovl_entry *oe = dentry->d_fsdata;
dd662667e   Miklos Szeredi   ovl: add mutli-la...
174
  	*path = oe->numlower ? oe->lowerstack[0] : (struct path) { NULL, NULL };
e9be9d5e7   Miklos Szeredi   overlay filesystem
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
  }
  
  int ovl_want_write(struct dentry *dentry)
  {
  	struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
  	return mnt_want_write(ofs->upper_mnt);
  }
  
  void ovl_drop_write(struct dentry *dentry)
  {
  	struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
  	mnt_drop_write(ofs->upper_mnt);
  }
  
  struct dentry *ovl_workdir(struct dentry *dentry)
  {
  	struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
  	return ofs->workdir;
  }
  
  bool ovl_dentry_is_opaque(struct dentry *dentry)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
  	return oe->opaque;
  }
  
  void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
  	oe->opaque = opaque;
  }
  
  void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
5955102c9   Al Viro   wrappers for ->i_...
210
  	WARN_ON(!inode_is_locked(upperdentry->d_parent->d_inode));
e9be9d5e7   Miklos Szeredi   overlay filesystem
211
  	WARN_ON(oe->__upperdentry);
e9be9d5e7   Miklos Szeredi   overlay filesystem
212
213
214
215
216
217
218
  	/*
  	 * Make sure upperdentry is consistent before making it visible to
  	 * ovl_upperdentry_dereference().
  	 */
  	smp_wmb();
  	oe->__upperdentry = upperdentry;
  }
39b681f80   Miklos Szeredi   ovl: store real i...
219
220
221
  void ovl_inode_update(struct inode *inode, struct inode *upperinode)
  {
  	WARN_ON(!upperinode);
51f7e52dc   Miklos Szeredi   ovl: share inode ...
222
  	WARN_ON(!inode_unhashed(inode));
39b681f80   Miklos Szeredi   ovl: store real i...
223
224
  	WRITE_ONCE(inode->i_private,
  		   (unsigned long) upperinode | OVL_ISUPPER_MASK);
51f7e52dc   Miklos Szeredi   ovl: share inode ...
225
226
  	if (!S_ISDIR(upperinode->i_mode))
  		__insert_inode_hash(inode, (unsigned long) upperinode);
39b681f80   Miklos Szeredi   ovl: store real i...
227
  }
e9be9d5e7   Miklos Szeredi   overlay filesystem
228
229
230
  void ovl_dentry_version_inc(struct dentry *dentry)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
5955102c9   Al Viro   wrappers for ->i_...
231
  	WARN_ON(!inode_is_locked(dentry->d_inode));
e9be9d5e7   Miklos Szeredi   overlay filesystem
232
233
234
235
236
237
  	oe->version++;
  }
  
  u64 ovl_dentry_version_get(struct dentry *dentry)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
5955102c9   Al Viro   wrappers for ->i_...
238
  	WARN_ON(!inode_is_locked(dentry->d_inode));
e9be9d5e7   Miklos Szeredi   overlay filesystem
239
240
241
242
243
244
245
246
247
  	return oe->version;
  }
  
  bool ovl_is_whiteout(struct dentry *dentry)
  {
  	struct inode *inode = dentry->d_inode;
  
  	return inode && IS_WHITEOUT(inode);
  }
3fe6e52f0   Antonio Murdaca   ovl: override cre...
248
249
250
251
252
253
  const struct cred *ovl_override_creds(struct super_block *sb)
  {
  	struct ovl_fs *ofs = sb->s_fs_info;
  
  	return override_creds(ofs->creator_cred);
  }
e9be9d5e7   Miklos Szeredi   overlay filesystem
254
255
256
257
  static bool ovl_is_opaquedir(struct dentry *dentry)
  {
  	int res;
  	char val;
e9be9d5e7   Miklos Szeredi   overlay filesystem
258

2b6bc7f48   Miklos Szeredi   ovl: lookup: do g...
259
  	if (!d_is_dir(dentry))
e9be9d5e7   Miklos Szeredi   overlay filesystem
260
  		return false;
2b6bc7f48   Miklos Szeredi   ovl: lookup: do g...
261
  	res = vfs_getxattr(dentry, OVL_XATTR_OPAQUE, &val, 1);
e9be9d5e7   Miklos Szeredi   overlay filesystem
262
263
264
265
266
267
268
269
270
271
272
  	if (res == 1 && val == 'y')
  		return true;
  
  	return false;
  }
  
  static void ovl_dentry_release(struct dentry *dentry)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
  
  	if (oe) {
dd662667e   Miklos Szeredi   ovl: add mutli-la...
273
  		unsigned int i;
e9be9d5e7   Miklos Szeredi   overlay filesystem
274
  		dput(oe->__upperdentry);
dd662667e   Miklos Szeredi   ovl: add mutli-la...
275
276
  		for (i = 0; i < oe->numlower; i++)
  			dput(oe->lowerstack[i].dentry);
e9be9d5e7   Miklos Szeredi   overlay filesystem
277
278
279
  		kfree_rcu(oe, rcu);
  	}
  }
2d902671c   Miklos Szeredi   vfs: merge .d_sel...
280
281
282
  static struct dentry *ovl_d_real(struct dentry *dentry,
  				 const struct inode *inode,
  				 unsigned int open_flags)
d101a1259   Miklos Szeredi   fs: add file_dent...
283
284
285
286
287
288
289
290
  {
  	struct dentry *real;
  
  	if (d_is_dir(dentry)) {
  		if (!inode || inode == d_inode(dentry))
  			return dentry;
  		goto bug;
  	}
2d902671c   Miklos Szeredi   vfs: merge .d_sel...
291
292
293
294
295
296
297
298
299
  	if (d_is_negative(dentry))
  		return dentry;
  
  	if (open_flags) {
  		int err = ovl_open_maybe_copy_up(dentry, open_flags);
  
  		if (err)
  			return ERR_PTR(err);
  	}
d101a1259   Miklos Szeredi   fs: add file_dent...
300
301
302
303
304
305
306
  	real = ovl_dentry_upper(dentry);
  	if (real && (!inode || inode == d_inode(real)))
  		return real;
  
  	real = ovl_dentry_lower(dentry);
  	if (!real)
  		goto bug;
c4fcfc161   Miklos Szeredi   ovl: fix d_real()...
307
308
  	/* Handle recursion */
  	real = d_real(real, inode, open_flags);
d101a1259   Miklos Szeredi   fs: add file_dent...
309
310
  	if (!inode || inode == d_inode(real))
  		return real;
d101a1259   Miklos Szeredi   fs: add file_dent...
311
  bug:
656189d20   Miklos Szeredi   ovl: fix warning
312
313
  	WARN(1, "ovl_d_real(%pd4, %s:%lu): real dentry not found
  ", dentry,
d101a1259   Miklos Szeredi   fs: add file_dent...
314
315
316
  	     inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0);
  	return dentry;
  }
7c03b5d45   Miklos Szeredi   ovl: allow distri...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
  static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
  	unsigned int i;
  	int ret = 1;
  
  	for (i = 0; i < oe->numlower; i++) {
  		struct dentry *d = oe->lowerstack[i].dentry;
  
  		if (d->d_flags & DCACHE_OP_REVALIDATE) {
  			ret = d->d_op->d_revalidate(d, flags);
  			if (ret < 0)
  				return ret;
  			if (!ret) {
  				if (!(flags & LOOKUP_RCU))
  					d_invalidate(d);
  				return -ESTALE;
  			}
  		}
  	}
  	return 1;
  }
  
  static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
  	unsigned int i;
  	int ret = 1;
  
  	for (i = 0; i < oe->numlower; i++) {
  		struct dentry *d = oe->lowerstack[i].dentry;
  
  		if (d->d_flags & DCACHE_OP_WEAK_REVALIDATE) {
  			ret = d->d_op->d_weak_revalidate(d, flags);
  			if (ret <= 0)
  				break;
  		}
  	}
  	return ret;
  }
e9be9d5e7   Miklos Szeredi   overlay filesystem
357
358
  static const struct dentry_operations ovl_dentry_operations = {
  	.d_release = ovl_dentry_release,
d101a1259   Miklos Szeredi   fs: add file_dent...
359
  	.d_real = ovl_d_real,
e9be9d5e7   Miklos Szeredi   overlay filesystem
360
  };
7c03b5d45   Miklos Szeredi   ovl: allow distri...
361
362
  static const struct dentry_operations ovl_reval_dentry_operations = {
  	.d_release = ovl_dentry_release,
d101a1259   Miklos Szeredi   fs: add file_dent...
363
  	.d_real = ovl_d_real,
7c03b5d45   Miklos Szeredi   ovl: allow distri...
364
365
366
  	.d_revalidate = ovl_dentry_revalidate,
  	.d_weak_revalidate = ovl_dentry_weak_revalidate,
  };
dd662667e   Miklos Szeredi   ovl: add mutli-la...
367
  static struct ovl_entry *ovl_alloc_entry(unsigned int numlower)
e9be9d5e7   Miklos Szeredi   overlay filesystem
368
  {
dd662667e   Miklos Szeredi   ovl: add mutli-la...
369
370
371
372
373
374
375
  	size_t size = offsetof(struct ovl_entry, lowerstack[numlower]);
  	struct ovl_entry *oe = kzalloc(size, GFP_KERNEL);
  
  	if (oe)
  		oe->numlower = numlower;
  
  	return oe;
e9be9d5e7   Miklos Szeredi   overlay filesystem
376
  }
7c03b5d45   Miklos Szeredi   ovl: allow distri...
377
378
379
  static bool ovl_dentry_remote(struct dentry *dentry)
  {
  	return dentry->d_flags &
76bc8e284   Miklos Szeredi   ovl: disallow ove...
380
381
  		(DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE |
  		 DCACHE_OP_REAL);
7c03b5d45   Miklos Szeredi   ovl: allow distri...
382
383
384
385
386
387
388
389
390
  }
  
  static bool ovl_dentry_weird(struct dentry *dentry)
  {
  	return dentry->d_flags & (DCACHE_NEED_AUTOMOUNT |
  				  DCACHE_MANAGE_TRANSIT |
  				  DCACHE_OP_HASH |
  				  DCACHE_OP_COMPARE);
  }
2b6bc7f48   Miklos Szeredi   ovl: lookup: do g...
391
  static inline struct dentry *ovl_lookup_real(struct dentry *dir,
29c42e80b   Al Viro   qstr: constify in...
392
  					     const struct qstr *name)
e9be9d5e7   Miklos Szeredi   overlay filesystem
393
394
  {
  	struct dentry *dentry;
c1b2cc1a7   Miklos Szeredi   ovl: check mounte...
395
  	dentry = lookup_one_len_unlocked(name->name, dir, name->len);
e9be9d5e7   Miklos Szeredi   overlay filesystem
396
397
398
399
400
401
402
  
  	if (IS_ERR(dentry)) {
  		if (PTR_ERR(dentry) == -ENOENT)
  			dentry = NULL;
  	} else if (!dentry->d_inode) {
  		dput(dentry);
  		dentry = NULL;
7c03b5d45   Miklos Szeredi   ovl: allow distri...
403
  	} else if (ovl_dentry_weird(dentry)) {
a6f15d9a7   Miklos Szeredi   ovl: don't traver...
404
  		dput(dentry);
7c03b5d45   Miklos Szeredi   ovl: allow distri...
405
  		/* Don't support traversing automounts and other weirdness */
a6f15d9a7   Miklos Szeredi   ovl: don't traver...
406
  		dentry = ERR_PTR(-EREMOTE);
e9be9d5e7   Miklos Szeredi   overlay filesystem
407
408
409
  	}
  	return dentry;
  }
5ef88da56   Miklos Szeredi   ovl: helper to it...
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
  /*
   * Returns next layer in stack starting from top.
   * Returns -1 if this is the last layer.
   */
  int ovl_path_next(int idx, struct dentry *dentry, struct path *path)
  {
  	struct ovl_entry *oe = dentry->d_fsdata;
  
  	BUG_ON(idx < 0);
  	if (idx == 0) {
  		ovl_path_upper(dentry, path);
  		if (path->dentry)
  			return oe->numlower ? 1 : -1;
  		idx++;
  	}
  	BUG_ON(idx > oe->numlower);
  	*path = oe->lowerstack[idx - 1];
  
  	return (idx < oe->numlower) ? idx + 1 : -1;
  }
e9be9d5e7   Miklos Szeredi   overlay filesystem
430
431
432
433
  struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
  			  unsigned int flags)
  {
  	struct ovl_entry *oe;
2b6bc7f48   Miklos Szeredi   ovl: lookup: do g...
434
  	const struct cred *old_cred;
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
435
436
437
438
  	struct ovl_entry *poe = dentry->d_parent->d_fsdata;
  	struct path *stack = NULL;
  	struct dentry *upperdir, *upperdentry = NULL;
  	unsigned int ctr = 0;
e9be9d5e7   Miklos Szeredi   overlay filesystem
439
  	struct inode *inode = NULL;
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
440
441
442
  	bool upperopaque = false;
  	struct dentry *this, *prev = NULL;
  	unsigned int i;
e9be9d5e7   Miklos Szeredi   overlay filesystem
443
  	int err;
2b6bc7f48   Miklos Szeredi   ovl: lookup: do g...
444
  	old_cred = ovl_override_creds(dentry->d_sb);
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
445
  	upperdir = ovl_upperdentry_dereference(poe);
e9be9d5e7   Miklos Szeredi   overlay filesystem
446
  	if (upperdir) {
2b6bc7f48   Miklos Szeredi   ovl: lookup: do g...
447
  		this = ovl_lookup_real(upperdir, &dentry->d_name);
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
448
449
450
  		err = PTR_ERR(this);
  		if (IS_ERR(this))
  			goto out;
3e01cee3b   Miklos Szeredi   ovl: check whiteo...
451
  		if (this) {
7c03b5d45   Miklos Szeredi   ovl: allow distri...
452
453
454
455
456
  			if (unlikely(ovl_dentry_remote(this))) {
  				dput(this);
  				err = -EREMOTE;
  				goto out;
  			}
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
457
458
459
460
  			if (ovl_is_whiteout(this)) {
  				dput(this);
  				this = NULL;
  				upperopaque = true;
3e01cee3b   Miklos Szeredi   ovl: check whiteo...
461
  			} else if (poe->numlower && ovl_is_opaquedir(this)) {
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
462
  				upperopaque = true;
e9be9d5e7   Miklos Szeredi   overlay filesystem
463
464
  			}
  		}
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
465
  		upperdentry = prev = this;
e9be9d5e7   Miklos Szeredi   overlay filesystem
466
  	}
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
467
468
469
470
471
472
  
  	if (!upperopaque && poe->numlower) {
  		err = -ENOMEM;
  		stack = kcalloc(poe->numlower, sizeof(struct path), GFP_KERNEL);
  		if (!stack)
  			goto out_put_upper;
e9be9d5e7   Miklos Szeredi   overlay filesystem
473
  	}
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
474
475
476
  	for (i = 0; !upperopaque && i < poe->numlower; i++) {
  		bool opaque = false;
  		struct path lowerpath = poe->lowerstack[i];
2b6bc7f48   Miklos Szeredi   ovl: lookup: do g...
477
  		this = ovl_lookup_real(lowerpath.dentry, &dentry->d_name);
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
478
  		err = PTR_ERR(this);
09e10322b   Miklos Szeredi   ovl: lookup ENAME...
479
480
481
482
483
484
  		if (IS_ERR(this)) {
  			/*
  			 * If it's positive, then treat ENAMETOOLONG as ENOENT.
  			 */
  			if (err == -ENAMETOOLONG && (upperdentry || ctr))
  				continue;
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
485
  			goto out_put;
09e10322b   Miklos Szeredi   ovl: lookup ENAME...
486
  		}
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
487
488
  		if (!this)
  			continue;
3e01cee3b   Miklos Szeredi   ovl: check whiteo...
489
490
491
492
  		if (ovl_is_whiteout(this)) {
  			dput(this);
  			break;
  		}
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
493
  		/*
3e01cee3b   Miklos Szeredi   ovl: check whiteo...
494
495
  		 * Only makes sense to check opaque dir if this is not the
  		 * lowermost layer.
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
496
  		 */
3e01cee3b   Miklos Szeredi   ovl: check whiteo...
497
498
  		if (i < poe->numlower - 1 && ovl_is_opaquedir(this))
  			opaque = true;
a425c037f   hujianyang   ovl: Fix opaque r...
499
500
501
502
503
504
505
  
  		if (prev && (!S_ISDIR(prev->d_inode->i_mode) ||
  			     !S_ISDIR(this->d_inode->i_mode))) {
  			/*
  			 * FIXME: check for upper-opaqueness maybe better done
  			 * in remove code.
  			 */
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
506
507
508
509
510
  			if (prev == upperdentry)
  				upperopaque = true;
  			dput(this);
  			break;
  		}
a425c037f   hujianyang   ovl: Fix opaque r...
511
512
513
514
515
  		/*
  		 * If this is a non-directory then stop here.
  		 */
  		if (!S_ISDIR(this->d_inode->i_mode))
  			opaque = true;
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
516
517
518
519
520
521
  		stack[ctr].dentry = this;
  		stack[ctr].mnt = lowerpath.mnt;
  		ctr++;
  		prev = this;
  		if (opaque)
  			break;
e9be9d5e7   Miklos Szeredi   overlay filesystem
522
  	}
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
523
524
525
526
527
528
  	oe = ovl_alloc_entry(ctr);
  	err = -ENOMEM;
  	if (!oe)
  		goto out_put;
  
  	if (upperdentry || ctr) {
e9be9d5e7   Miklos Szeredi   overlay filesystem
529
  		struct dentry *realdentry;
39b681f80   Miklos Szeredi   ovl: store real i...
530
  		struct inode *realinode;
e9be9d5e7   Miklos Szeredi   overlay filesystem
531

3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
532
  		realdentry = upperdentry ? upperdentry : stack[0].dentry;
39b681f80   Miklos Szeredi   ovl: store real i...
533
  		realinode = d_inode(realdentry);
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
534

e9be9d5e7   Miklos Szeredi   overlay filesystem
535
  		err = -ENOMEM;
51f7e52dc   Miklos Szeredi   ovl: share inode ...
536
537
538
539
540
541
542
  		if (upperdentry && !d_is_dir(upperdentry)) {
  			inode = ovl_get_inode(dentry->d_sb, realinode);
  		} else {
  			inode = ovl_new_inode(dentry->d_sb, realinode->i_mode);
  			if (inode)
  				ovl_inode_init(inode, realinode, !!upperdentry);
  		}
e9be9d5e7   Miklos Szeredi   overlay filesystem
543
  		if (!inode)
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
544
  			goto out_free_oe;
e9be9d5e7   Miklos Szeredi   overlay filesystem
545
546
  		ovl_copyattr(realdentry->d_inode, inode);
  	}
2b6bc7f48   Miklos Szeredi   ovl: lookup: do g...
547
  	revert_creds(old_cred);
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
548
  	oe->opaque = upperopaque;
e9be9d5e7   Miklos Szeredi   overlay filesystem
549
  	oe->__upperdentry = upperdentry;
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
550
551
  	memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr);
  	kfree(stack);
e9be9d5e7   Miklos Szeredi   overlay filesystem
552
553
554
555
  	dentry->d_fsdata = oe;
  	d_add(dentry, inode);
  
  	return NULL;
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
556
  out_free_oe:
e9be9d5e7   Miklos Szeredi   overlay filesystem
557
  	kfree(oe);
3d3c6b893   Miklos Szeredi   ovl: multi-layer ...
558
559
560
561
562
563
  out_put:
  	for (i = 0; i < ctr; i++)
  		dput(stack[i].dentry);
  	kfree(stack);
  out_put_upper:
  	dput(upperdentry);
e9be9d5e7   Miklos Szeredi   overlay filesystem
564
  out:
2b6bc7f48   Miklos Szeredi   ovl: lookup: do g...
565
  	revert_creds(old_cred);
e9be9d5e7   Miklos Szeredi   overlay filesystem
566
567
568
569
570
  	return ERR_PTR(err);
  }
  
  struct file *ovl_path_open(struct path *path, int flags)
  {
d719e8f26   Miklos Szeredi   ovl: update atime...
571
  	return dentry_open(path, flags | O_NOATIME, current_cred());
e9be9d5e7   Miklos Szeredi   overlay filesystem
572
573
574
575
576
  }
  
  static void ovl_put_super(struct super_block *sb)
  {
  	struct ovl_fs *ufs = sb->s_fs_info;
dd662667e   Miklos Szeredi   ovl: add mutli-la...
577
  	unsigned i;
e9be9d5e7   Miklos Szeredi   overlay filesystem
578
579
580
  
  	dput(ufs->workdir);
  	mntput(ufs->upper_mnt);
dd662667e   Miklos Szeredi   ovl: add mutli-la...
581
582
  	for (i = 0; i < ufs->numlower; i++)
  		mntput(ufs->lower_mnt[i]);
5ffdbe8bf   Konstantin Khlebnikov   ovl: free lower_m...
583
  	kfree(ufs->lower_mnt);
e9be9d5e7   Miklos Szeredi   overlay filesystem
584

f45827e84   Erez Zadok   overlayfs: implem...
585
586
587
  	kfree(ufs->config.lowerdir);
  	kfree(ufs->config.upperdir);
  	kfree(ufs->config.workdir);
3fe6e52f0   Antonio Murdaca   ovl: override cre...
588
  	put_cred(ufs->creator_cred);
e9be9d5e7   Miklos Szeredi   overlay filesystem
589
590
  	kfree(ufs);
  }
cc2596392   Andy Whitcroft   overlayfs: add st...
591
592
593
594
595
596
  /**
   * ovl_statfs
   * @sb: The overlayfs super block
   * @buf: The struct kstatfs to fill in with stats
   *
   * Get the filesystem statistics.  As writes always target the upper layer
4ebc58182   Miklos Szeredi   ovl: allow statfs...
597
   * filesystem pass the statfs to the upper filesystem (if it exists)
cc2596392   Andy Whitcroft   overlayfs: add st...
598
599
600
601
602
603
604
   */
  static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf)
  {
  	struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
  	struct dentry *root_dentry = dentry->d_sb->s_root;
  	struct path path;
  	int err;
4ebc58182   Miklos Szeredi   ovl: allow statfs...
605
  	ovl_path_real(root_dentry, &path);
cc2596392   Andy Whitcroft   overlayfs: add st...
606
607
608
609
610
611
612
613
614
  
  	err = vfs_statfs(&path, buf);
  	if (!err) {
  		buf->f_namelen = max(buf->f_namelen, ofs->lower_namelen);
  		buf->f_type = OVERLAYFS_SUPER_MAGIC;
  	}
  
  	return err;
  }
f45827e84   Erez Zadok   overlayfs: implem...
615
616
617
618
619
620
621
622
623
624
  /**
   * ovl_show_options
   *
   * Prints the mount options for a given superblock.
   * Returns zero; does not fail.
   */
  static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
  {
  	struct super_block *sb = dentry->d_sb;
  	struct ovl_fs *ufs = sb->s_fs_info;
a068acf2e   Kees Cook   fs: create and us...
625
  	seq_show_option(m, "lowerdir", ufs->config.lowerdir);
53a08cb9b   Miklos Szeredi   ovl: make upperdi...
626
  	if (ufs->config.upperdir) {
a068acf2e   Kees Cook   fs: create and us...
627
628
  		seq_show_option(m, "upperdir", ufs->config.upperdir);
  		seq_show_option(m, "workdir", ufs->config.workdir);
53a08cb9b   Miklos Szeredi   ovl: make upperdi...
629
  	}
8d3095f4a   Miklos Szeredi   ovl: default perm...
630
631
  	if (ufs->config.default_permissions)
  		seq_puts(m, ",default_permissions");
f45827e84   Erez Zadok   overlayfs: implem...
632
633
  	return 0;
  }
3cdf6fe91   Seunghun Lee   ovl: Prevent rw r...
634
635
636
  static int ovl_remount(struct super_block *sb, int *flags, char *data)
  {
  	struct ovl_fs *ufs = sb->s_fs_info;
cc6f67bca   Miklos Szeredi   ovl: mount read-o...
637
  	if (!(*flags & MS_RDONLY) && (!ufs->upper_mnt || !ufs->workdir))
3cdf6fe91   Seunghun Lee   ovl: Prevent rw r...
638
639
640
641
  		return -EROFS;
  
  	return 0;
  }
e9be9d5e7   Miklos Szeredi   overlay filesystem
642
643
  static const struct super_operations ovl_super_operations = {
  	.put_super	= ovl_put_super,
cc2596392   Andy Whitcroft   overlayfs: add st...
644
  	.statfs		= ovl_statfs,
f45827e84   Erez Zadok   overlayfs: implem...
645
  	.show_options	= ovl_show_options,
3cdf6fe91   Seunghun Lee   ovl: Prevent rw r...
646
  	.remount_fs	= ovl_remount,
eead4f2dc   Miklos Szeredi   ovl: use generic_...
647
  	.drop_inode	= generic_delete_inode,
e9be9d5e7   Miklos Szeredi   overlay filesystem
648
649
650
651
652
653
  };
  
  enum {
  	OPT_LOWERDIR,
  	OPT_UPPERDIR,
  	OPT_WORKDIR,
8d3095f4a   Miklos Szeredi   ovl: default perm...
654
  	OPT_DEFAULT_PERMISSIONS,
e9be9d5e7   Miklos Szeredi   overlay filesystem
655
656
657
658
659
660
661
  	OPT_ERR,
  };
  
  static const match_table_t ovl_tokens = {
  	{OPT_LOWERDIR,			"lowerdir=%s"},
  	{OPT_UPPERDIR,			"upperdir=%s"},
  	{OPT_WORKDIR,			"workdir=%s"},
8d3095f4a   Miklos Szeredi   ovl: default perm...
662
  	{OPT_DEFAULT_PERMISSIONS,	"default_permissions"},
e9be9d5e7   Miklos Szeredi   overlay filesystem
663
664
  	{OPT_ERR,			NULL}
  };
91c779471   Miklos Szeredi   ovl: allow filena...
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
  static char *ovl_next_opt(char **s)
  {
  	char *sbegin = *s;
  	char *p;
  
  	if (sbegin == NULL)
  		return NULL;
  
  	for (p = sbegin; *p; p++) {
  		if (*p == '\\') {
  			p++;
  			if (!*p)
  				break;
  		} else if (*p == ',') {
  			*p = '\0';
  			*s = p + 1;
  			return sbegin;
  		}
  	}
  	*s = NULL;
  	return sbegin;
  }
e9be9d5e7   Miklos Szeredi   overlay filesystem
687
688
689
  static int ovl_parse_opt(char *opt, struct ovl_config *config)
  {
  	char *p;
91c779471   Miklos Szeredi   ovl: allow filena...
690
  	while ((p = ovl_next_opt(&opt)) != NULL) {
e9be9d5e7   Miklos Szeredi   overlay filesystem
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
  		int token;
  		substring_t args[MAX_OPT_ARGS];
  
  		if (!*p)
  			continue;
  
  		token = match_token(p, ovl_tokens, args);
  		switch (token) {
  		case OPT_UPPERDIR:
  			kfree(config->upperdir);
  			config->upperdir = match_strdup(&args[0]);
  			if (!config->upperdir)
  				return -ENOMEM;
  			break;
  
  		case OPT_LOWERDIR:
  			kfree(config->lowerdir);
  			config->lowerdir = match_strdup(&args[0]);
  			if (!config->lowerdir)
  				return -ENOMEM;
  			break;
  
  		case OPT_WORKDIR:
  			kfree(config->workdir);
  			config->workdir = match_strdup(&args[0]);
  			if (!config->workdir)
  				return -ENOMEM;
  			break;
8d3095f4a   Miklos Szeredi   ovl: default perm...
719
720
721
  		case OPT_DEFAULT_PERMISSIONS:
  			config->default_permissions = true;
  			break;
e9be9d5e7   Miklos Szeredi   overlay filesystem
722
  		default:
bead55ef7   hujianyang   ovl: print error ...
723
724
  			pr_err("overlayfs: unrecognized mount option \"%s\" or missing value
  ", p);
e9be9d5e7   Miklos Szeredi   overlay filesystem
725
726
727
  			return -EINVAL;
  		}
  	}
71cbad7e6   hujianyang   ovl: upper fs sho...
728
729
730
731
732
733
734
735
736
  
  	/* Workdir is useless in non-upper mount */
  	if (!config->upperdir && config->workdir) {
  		pr_info("overlayfs: option \"workdir=%s\" is useless in a non-upper mount, ignore
  ",
  			config->workdir);
  		kfree(config->workdir);
  		config->workdir = NULL;
  	}
e9be9d5e7   Miklos Szeredi   overlay filesystem
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
  	return 0;
  }
  
  #define OVL_WORKDIR_NAME "work"
  
  static struct dentry *ovl_workdir_create(struct vfsmount *mnt,
  					 struct dentry *dentry)
  {
  	struct inode *dir = dentry->d_inode;
  	struct dentry *work;
  	int err;
  	bool retried = false;
  
  	err = mnt_want_write(mnt);
  	if (err)
  		return ERR_PTR(err);
5955102c9   Al Viro   wrappers for ->i_...
753
  	inode_lock_nested(dir, I_MUTEX_PARENT);
e9be9d5e7   Miklos Szeredi   overlay filesystem
754
755
756
757
758
759
760
761
  retry:
  	work = lookup_one_len(OVL_WORKDIR_NAME, dentry,
  			      strlen(OVL_WORKDIR_NAME));
  
  	if (!IS_ERR(work)) {
  		struct kstat stat = {
  			.mode = S_IFDIR | 0,
  		};
c11b9fdd6   Miklos Szeredi   ovl: remove posix...
762
763
764
765
  		struct iattr attr = {
  			.ia_valid = ATTR_MODE,
  			.ia_mode = stat.mode,
  		};
e9be9d5e7   Miklos Szeredi   overlay filesystem
766
767
768
769
770
771
772
  
  		if (work->d_inode) {
  			err = -EEXIST;
  			if (retried)
  				goto out_dput;
  
  			retried = true;
eea2fb485   Miklos Szeredi   ovl: proper clean...
773
  			ovl_workdir_cleanup(dir, mnt, work, 0);
e9be9d5e7   Miklos Szeredi   overlay filesystem
774
775
776
777
778
779
780
  			dput(work);
  			goto retry;
  		}
  
  		err = ovl_create_real(dir, work, &stat, NULL, NULL, true);
  		if (err)
  			goto out_dput;
c11b9fdd6   Miklos Szeredi   ovl: remove posix...
781

cb348edb6   Miklos Szeredi   ovl: explain erro...
782
783
784
785
786
787
788
789
790
791
792
793
794
  		/*
  		 * Try to remove POSIX ACL xattrs from workdir.  We are good if:
  		 *
  		 * a) success (there was a POSIX ACL xattr and was removed)
  		 * b) -ENODATA (there was no POSIX ACL xattr)
  		 * c) -EOPNOTSUPP (POSIX ACL xattrs are not supported)
  		 *
  		 * There are various other error values that could effectively
  		 * mean that the xattr doesn't exist (e.g. -ERANGE is returned
  		 * if the xattr name is too long), but the set of filesystems
  		 * allowed as upper are limited to "normal" ones, where checking
  		 * for the above two errors is sufficient.
  		 */
c11b9fdd6   Miklos Szeredi   ovl: remove posix...
795
  		err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_DEFAULT);
e1ff3dd1a   Miklos Szeredi   ovl: fix workdir ...
796
  		if (err && err != -ENODATA && err != -EOPNOTSUPP)
c11b9fdd6   Miklos Szeredi   ovl: remove posix...
797
798
799
  			goto out_dput;
  
  		err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_ACCESS);
e1ff3dd1a   Miklos Szeredi   ovl: fix workdir ...
800
  		if (err && err != -ENODATA && err != -EOPNOTSUPP)
c11b9fdd6   Miklos Szeredi   ovl: remove posix...
801
802
803
804
805
806
807
808
  			goto out_dput;
  
  		/* Clear any inherited mode bits */
  		inode_lock(work->d_inode);
  		err = notify_change(work, &attr, NULL);
  		inode_unlock(work->d_inode);
  		if (err)
  			goto out_dput;
e9be9d5e7   Miklos Szeredi   overlay filesystem
809
810
  	}
  out_unlock:
5955102c9   Al Viro   wrappers for ->i_...
811
  	inode_unlock(dir);
e9be9d5e7   Miklos Szeredi   overlay filesystem
812
813
814
815
816
817
818
819
820
  	mnt_drop_write(mnt);
  
  	return work;
  
  out_dput:
  	dput(work);
  	work = ERR_PTR(err);
  	goto out_unlock;
  }
91c779471   Miklos Szeredi   ovl: allow filena...
821
822
823
824
825
826
827
828
829
830
831
832
  static void ovl_unescape(char *s)
  {
  	char *d = s;
  
  	for (;; s++, d++) {
  		if (*s == '\\')
  			s++;
  		*d = *s;
  		if (!*s)
  			break;
  	}
  }
ab508822c   Miklos Szeredi   ovl: improve moun...
833
834
  static int ovl_mount_dir_noesc(const char *name, struct path *path)
  {
a78d9f0d5   Miklos Szeredi   ovl: support mult...
835
  	int err = -EINVAL;
ab508822c   Miklos Szeredi   ovl: improve moun...
836

a78d9f0d5   Miklos Szeredi   ovl: support mult...
837
838
839
840
841
  	if (!*name) {
  		pr_err("overlayfs: empty lowerdir
  ");
  		goto out;
  	}
ab508822c   Miklos Szeredi   ovl: improve moun...
842
843
844
845
846
847
848
  	err = kern_path(name, LOOKUP_FOLLOW, path);
  	if (err) {
  		pr_err("overlayfs: failed to resolve '%s': %i
  ", name, err);
  		goto out;
  	}
  	err = -EINVAL;
7c03b5d45   Miklos Szeredi   ovl: allow distri...
849
  	if (ovl_dentry_weird(path->dentry)) {
ab508822c   Miklos Szeredi   ovl: improve moun...
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
  		pr_err("overlayfs: filesystem on '%s' not supported
  ", name);
  		goto out_put;
  	}
  	if (!S_ISDIR(path->dentry->d_inode->i_mode)) {
  		pr_err("overlayfs: '%s' not a directory
  ", name);
  		goto out_put;
  	}
  	return 0;
  
  out_put:
  	path_put(path);
  out:
  	return err;
  }
  
  static int ovl_mount_dir(const char *name, struct path *path)
  {
  	int err = -ENOMEM;
  	char *tmp = kstrdup(name, GFP_KERNEL);
  
  	if (tmp) {
  		ovl_unescape(tmp);
  		err = ovl_mount_dir_noesc(tmp, path);
7c03b5d45   Miklos Szeredi   ovl: allow distri...
875
876
877
878
879
880
881
882
883
  
  		if (!err)
  			if (ovl_dentry_remote(path->dentry)) {
  				pr_err("overlayfs: filesystem on '%s' not supported as upperdir
  ",
  				       tmp);
  				path_put(path);
  				err = -EINVAL;
  			}
ab508822c   Miklos Szeredi   ovl: improve moun...
884
885
886
887
888
889
  		kfree(tmp);
  	}
  	return err;
  }
  
  static int ovl_lower_dir(const char *name, struct path *path, long *namelen,
7c03b5d45   Miklos Szeredi   ovl: allow distri...
890
  			 int *stack_depth, bool *remote)
ab508822c   Miklos Szeredi   ovl: improve moun...
891
892
893
  {
  	int err;
  	struct kstatfs statfs;
a78d9f0d5   Miklos Szeredi   ovl: support mult...
894
  	err = ovl_mount_dir_noesc(name, path);
ab508822c   Miklos Szeredi   ovl: improve moun...
895
896
897
898
899
900
901
902
903
904
905
  	if (err)
  		goto out;
  
  	err = vfs_statfs(path, &statfs);
  	if (err) {
  		pr_err("overlayfs: statfs failed on '%s'
  ", name);
  		goto out_put;
  	}
  	*namelen = max(*namelen, statfs.f_namelen);
  	*stack_depth = max(*stack_depth, path->mnt->mnt_sb->s_stack_depth);
7c03b5d45   Miklos Szeredi   ovl: allow distri...
906
907
  	if (ovl_dentry_remote(path->dentry))
  		*remote = true;
ab508822c   Miklos Szeredi   ovl: improve moun...
908
909
910
911
912
913
914
  	return 0;
  
  out_put:
  	path_put(path);
  out:
  	return err;
  }
e9be9d5e7   Miklos Szeredi   overlay filesystem
915
916
917
918
919
920
921
922
923
924
925
  /* Workdir should not be subdir of upperdir and vice versa */
  static bool ovl_workdir_ok(struct dentry *workdir, struct dentry *upperdir)
  {
  	bool ok = false;
  
  	if (workdir != upperdir) {
  		ok = (lock_rename(workdir, upperdir) == NULL);
  		unlock_rename(workdir, upperdir);
  	}
  	return ok;
  }
a78d9f0d5   Miklos Szeredi   ovl: support mult...
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
  static unsigned int ovl_split_lowerdirs(char *str)
  {
  	unsigned int ctr = 1;
  	char *s, *d;
  
  	for (s = d = str;; s++, d++) {
  		if (*s == '\\') {
  			s++;
  		} else if (*s == ':') {
  			*d = '\0';
  			ctr++;
  			continue;
  		}
  		*d = *s;
  		if (!*s)
  			break;
  	}
  	return ctr;
  }
0c97be22f   Andreas Gruenbacher   ovl: Get rid of o...
945
  static int __maybe_unused
0eb45fc3b   Andreas Gruenbacher   ovl: Switch to ge...
946
947
948
949
950
951
952
953
  ovl_posix_acl_xattr_get(const struct xattr_handler *handler,
  			struct dentry *dentry, struct inode *inode,
  			const char *name, void *buffer, size_t size)
  {
  	return ovl_xattr_get(dentry, handler->name, buffer, size);
  }
  
  static int __maybe_unused
0c97be22f   Andreas Gruenbacher   ovl: Get rid of o...
954
955
956
957
  ovl_posix_acl_xattr_set(const struct xattr_handler *handler,
  			struct dentry *dentry, struct inode *inode,
  			const char *name, const void *value,
  			size_t size, int flags)
d837a49bd   Miklos Szeredi   ovl: fix POSIX AC...
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
  {
  	struct dentry *workdir = ovl_workdir(dentry);
  	struct inode *realinode = ovl_inode_real(inode, NULL);
  	struct posix_acl *acl = NULL;
  	int err;
  
  	/* Check that everything is OK before copy-up */
  	if (value) {
  		acl = posix_acl_from_xattr(&init_user_ns, value, size);
  		if (IS_ERR(acl))
  			return PTR_ERR(acl);
  	}
  	err = -EOPNOTSUPP;
  	if (!IS_POSIXACL(d_inode(workdir)))
  		goto out_acl_release;
  	if (!realinode->i_op->set_acl)
  		goto out_acl_release;
  	if (handler->flags == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) {
  		err = acl ? -EACCES : 0;
  		goto out_acl_release;
  	}
  	err = -EPERM;
  	if (!inode_owner_or_capable(inode))
  		goto out_acl_release;
  
  	posix_acl_release(acl);
fd3220d37   Miklos Szeredi   ovl: update S_ISG...
984
985
986
987
988
989
990
991
992
993
994
995
996
997
  	/*
  	 * Check if sgid bit needs to be cleared (actual setacl operation will
  	 * be done with mounter's capabilities and so that won't do it for us).
  	 */
  	if (unlikely(inode->i_mode & S_ISGID) &&
  	    handler->flags == ACL_TYPE_ACCESS &&
  	    !in_group_p(inode->i_gid) &&
  	    !capable_wrt_inode_uidgid(inode, CAP_FSETID)) {
  		struct iattr iattr = { .ia_valid = ATTR_KILL_SGID };
  
  		err = ovl_setattr(dentry, &iattr);
  		if (err)
  			return err;
  	}
ce31513a9   Miklos Szeredi   ovl: copyattr aft...
998
999
1000
1001
1002
  	err = ovl_xattr_set(dentry, handler->name, value, size, flags);
  	if (!err)
  		ovl_copyattr(ovl_inode_real(inode, NULL), inode);
  
  	return err;
d837a49bd   Miklos Szeredi   ovl: fix POSIX AC...
1003
1004
1005
1006
1007
  
  out_acl_release:
  	posix_acl_release(acl);
  	return err;
  }
0eb45fc3b   Andreas Gruenbacher   ovl: Switch to ge...
1008
1009
1010
1011
1012
1013
  static int ovl_own_xattr_get(const struct xattr_handler *handler,
  			     struct dentry *dentry, struct inode *inode,
  			     const char *name, void *buffer, size_t size)
  {
  	return -EPERM;
  }
d837a49bd   Miklos Szeredi   ovl: fix POSIX AC...
1014
1015
1016
1017
1018
1019
1020
  static int ovl_own_xattr_set(const struct xattr_handler *handler,
  			     struct dentry *dentry, struct inode *inode,
  			     const char *name, const void *value,
  			     size_t size, int flags)
  {
  	return -EPERM;
  }
0eb45fc3b   Andreas Gruenbacher   ovl: Switch to ge...
1021
1022
1023
1024
1025
1026
  static int ovl_other_xattr_get(const struct xattr_handler *handler,
  			       struct dentry *dentry, struct inode *inode,
  			       const char *name, void *buffer, size_t size)
  {
  	return ovl_xattr_get(dentry, name, buffer, size);
  }
0e585ccc1   Andreas Gruenbacher   ovl: Switch to ge...
1027
1028
1029
1030
1031
1032
1033
  static int ovl_other_xattr_set(const struct xattr_handler *handler,
  			       struct dentry *dentry, struct inode *inode,
  			       const char *name, const void *value,
  			       size_t size, int flags)
  {
  	return ovl_xattr_set(dentry, name, value, size, flags);
  }
0c97be22f   Andreas Gruenbacher   ovl: Get rid of o...
1034
1035
  static const struct xattr_handler __maybe_unused
  ovl_posix_acl_access_xattr_handler = {
d837a49bd   Miklos Szeredi   ovl: fix POSIX AC...
1036
1037
  	.name = XATTR_NAME_POSIX_ACL_ACCESS,
  	.flags = ACL_TYPE_ACCESS,
0eb45fc3b   Andreas Gruenbacher   ovl: Switch to ge...
1038
  	.get = ovl_posix_acl_xattr_get,
d837a49bd   Miklos Szeredi   ovl: fix POSIX AC...
1039
1040
  	.set = ovl_posix_acl_xattr_set,
  };
0c97be22f   Andreas Gruenbacher   ovl: Get rid of o...
1041
1042
  static const struct xattr_handler __maybe_unused
  ovl_posix_acl_default_xattr_handler = {
d837a49bd   Miklos Szeredi   ovl: fix POSIX AC...
1043
1044
  	.name = XATTR_NAME_POSIX_ACL_DEFAULT,
  	.flags = ACL_TYPE_DEFAULT,
0eb45fc3b   Andreas Gruenbacher   ovl: Switch to ge...
1045
  	.get = ovl_posix_acl_xattr_get,
d837a49bd   Miklos Szeredi   ovl: fix POSIX AC...
1046
1047
1048
1049
1050
  	.set = ovl_posix_acl_xattr_set,
  };
  
  static const struct xattr_handler ovl_own_xattr_handler = {
  	.prefix	= OVL_XATTR_PREFIX,
0eb45fc3b   Andreas Gruenbacher   ovl: Switch to ge...
1051
  	.get = ovl_own_xattr_get,
d837a49bd   Miklos Szeredi   ovl: fix POSIX AC...
1052
1053
1054
1055
1056
  	.set = ovl_own_xattr_set,
  };
  
  static const struct xattr_handler ovl_other_xattr_handler = {
  	.prefix	= "", /* catch all */
0eb45fc3b   Andreas Gruenbacher   ovl: Switch to ge...
1057
  	.get = ovl_other_xattr_get,
d837a49bd   Miklos Szeredi   ovl: fix POSIX AC...
1058
1059
1060
1061
  	.set = ovl_other_xattr_set,
  };
  
  static const struct xattr_handler *ovl_xattr_handlers[] = {
0c97be22f   Andreas Gruenbacher   ovl: Get rid of o...
1062
  #ifdef CONFIG_FS_POSIX_ACL
d837a49bd   Miklos Szeredi   ovl: fix POSIX AC...
1063
1064
  	&ovl_posix_acl_access_xattr_handler,
  	&ovl_posix_acl_default_xattr_handler,
0c97be22f   Andreas Gruenbacher   ovl: Get rid of o...
1065
  #endif
d837a49bd   Miklos Szeredi   ovl: fix POSIX AC...
1066
1067
1068
1069
  	&ovl_own_xattr_handler,
  	&ovl_other_xattr_handler,
  	NULL
  };
e9be9d5e7   Miklos Szeredi   overlay filesystem
1070
1071
  static int ovl_fill_super(struct super_block *sb, void *data, int silent)
  {
53a08cb9b   Miklos Szeredi   ovl: make upperdi...
1072
1073
  	struct path upperpath = { NULL, NULL };
  	struct path workpath = { NULL, NULL };
e9be9d5e7   Miklos Szeredi   overlay filesystem
1074
  	struct dentry *root_dentry;
39b681f80   Miklos Szeredi   ovl: store real i...
1075
  	struct inode *realinode;
e9be9d5e7   Miklos Szeredi   overlay filesystem
1076
1077
  	struct ovl_entry *oe;
  	struct ovl_fs *ufs;
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1078
1079
1080
1081
1082
  	struct path *stack = NULL;
  	char *lowertmp;
  	char *lower;
  	unsigned int numlower;
  	unsigned int stacklen = 0;
dd662667e   Miklos Szeredi   ovl: add mutli-la...
1083
  	unsigned int i;
7c03b5d45   Miklos Szeredi   ovl: allow distri...
1084
  	bool remote = false;
e9be9d5e7   Miklos Szeredi   overlay filesystem
1085
  	int err;
f45827e84   Erez Zadok   overlayfs: implem...
1086
1087
1088
  	err = -ENOMEM;
  	ufs = kzalloc(sizeof(struct ovl_fs), GFP_KERNEL);
  	if (!ufs)
e9be9d5e7   Miklos Szeredi   overlay filesystem
1089
  		goto out;
f45827e84   Erez Zadok   overlayfs: implem...
1090
1091
1092
  	err = ovl_parse_opt((char *) data, &ufs->config);
  	if (err)
  		goto out_free_config;
e9be9d5e7   Miklos Szeredi   overlay filesystem
1093
  	err = -EINVAL;
53a08cb9b   Miklos Szeredi   ovl: make upperdi...
1094
  	if (!ufs->config.lowerdir) {
07f2af7bf   Konstantin Khlebnikov   ovl: honor flag M...
1095
1096
1097
  		if (!silent)
  			pr_err("overlayfs: missing 'lowerdir'
  ");
e9be9d5e7   Miklos Szeredi   overlay filesystem
1098
1099
  		goto out_free_config;
  	}
53a08cb9b   Miklos Szeredi   ovl: make upperdi...
1100
  	sb->s_stack_depth = 0;
cf9a6784f   Miklos Szeredi   ovl: setattr: che...
1101
  	sb->s_maxbytes = MAX_LFS_FILESIZE;
53a08cb9b   Miklos Szeredi   ovl: make upperdi...
1102
  	if (ufs->config.upperdir) {
53a08cb9b   Miklos Szeredi   ovl: make upperdi...
1103
1104
1105
1106
1107
  		if (!ufs->config.workdir) {
  			pr_err("overlayfs: missing 'workdir'
  ");
  			goto out_free_config;
  		}
e9be9d5e7   Miklos Szeredi   overlay filesystem
1108

53a08cb9b   Miklos Szeredi   ovl: make upperdi...
1109
1110
1111
  		err = ovl_mount_dir(ufs->config.upperdir, &upperpath);
  		if (err)
  			goto out_free_config;
e9be9d5e7   Miklos Szeredi   overlay filesystem
1112

71cbad7e6   hujianyang   ovl: upper fs sho...
1113
1114
1115
1116
1117
1118
1119
  		/* Upper fs should not be r/o */
  		if (upperpath.mnt->mnt_sb->s_flags & MS_RDONLY) {
  			pr_err("overlayfs: upper fs is r/o, try multi-lower layers mount
  ");
  			err = -EINVAL;
  			goto out_put_upperpath;
  		}
53a08cb9b   Miklos Szeredi   ovl: make upperdi...
1120
1121
1122
  		err = ovl_mount_dir(ufs->config.workdir, &workpath);
  		if (err)
  			goto out_put_upperpath;
2f83fd8c2   hujianyang   ovl: Fix kernel p...
1123
  		err = -EINVAL;
53a08cb9b   Miklos Szeredi   ovl: make upperdi...
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
  		if (upperpath.mnt != workpath.mnt) {
  			pr_err("overlayfs: workdir and upperdir must reside under the same mount
  ");
  			goto out_put_workpath;
  		}
  		if (!ovl_workdir_ok(workpath.dentry, upperpath.dentry)) {
  			pr_err("overlayfs: workdir and upperdir must be separate subtrees
  ");
  			goto out_put_workpath;
  		}
  		sb->s_stack_depth = upperpath.mnt->mnt_sb->s_stack_depth;
cc2596392   Andy Whitcroft   overlayfs: add st...
1135
  	}
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1136
1137
1138
  	err = -ENOMEM;
  	lowertmp = kstrdup(ufs->config.lowerdir, GFP_KERNEL);
  	if (!lowertmp)
ab508822c   Miklos Szeredi   ovl: improve moun...
1139
  		goto out_put_workpath;
69c433ed2   Miklos Szeredi   fs: limit filesys...
1140
1141
  
  	err = -EINVAL;
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1142
  	stacklen = ovl_split_lowerdirs(lowertmp);
6be4506e3   hujianyang   ovl: check lowerd...
1143
  	if (stacklen > OVL_MAX_STACK) {
fd36570a8   Colin Ian King   ovl: fix spelling...
1144
1145
  		pr_err("overlayfs: too many lower directories, limit is %d
  ",
6be4506e3   hujianyang   ovl: check lowerd...
1146
  		       OVL_MAX_STACK);
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1147
  		goto out_free_lowertmp;
6be4506e3   hujianyang   ovl: check lowerd...
1148
1149
1150
1151
1152
  	} else if (!ufs->config.upperdir && stacklen == 1) {
  		pr_err("overlayfs: at least 2 lowerdir are needed while upperdir nonexistent
  ");
  		goto out_free_lowertmp;
  	}
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1153
1154
1155
1156
1157
1158
1159
1160
  
  	stack = kcalloc(stacklen, sizeof(struct path), GFP_KERNEL);
  	if (!stack)
  		goto out_free_lowertmp;
  
  	lower = lowertmp;
  	for (numlower = 0; numlower < stacklen; numlower++) {
  		err = ovl_lower_dir(lower, &stack[numlower],
7c03b5d45   Miklos Szeredi   ovl: allow distri...
1161
1162
  				    &ufs->lower_namelen, &sb->s_stack_depth,
  				    &remote);
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1163
1164
1165
1166
1167
1168
1169
  		if (err)
  			goto out_put_lowerpath;
  
  		lower = strchr(lower, '\0') + 1;
  	}
  
  	err = -EINVAL;
ab508822c   Miklos Szeredi   ovl: improve moun...
1170
  	sb->s_stack_depth++;
69c433ed2   Miklos Szeredi   fs: limit filesys...
1171
1172
1173
  	if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
  		pr_err("overlayfs: maximum fs stacking depth exceeded
  ");
3b7a9a249   Miklos Szeredi   ovl: mount: chang...
1174
  		goto out_put_lowerpath;
69c433ed2   Miklos Szeredi   fs: limit filesys...
1175
  	}
53a08cb9b   Miklos Szeredi   ovl: make upperdi...
1176
1177
1178
1179
1180
1181
1182
1183
  	if (ufs->config.upperdir) {
  		ufs->upper_mnt = clone_private_mount(&upperpath);
  		err = PTR_ERR(ufs->upper_mnt);
  		if (IS_ERR(ufs->upper_mnt)) {
  			pr_err("overlayfs: failed to clone upperpath
  ");
  			goto out_put_lowerpath;
  		}
d719e8f26   Miklos Szeredi   ovl: update atime...
1184
1185
1186
1187
  		/* Don't inherit atime flags */
  		ufs->upper_mnt->mnt_flags &= ~(MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME);
  
  		sb->s_time_gran = ufs->upper_mnt->mnt_sb->s_time_gran;
3b7a9a249   Miklos Szeredi   ovl: mount: chang...
1188

53a08cb9b   Miklos Szeredi   ovl: make upperdi...
1189
1190
1191
  		ufs->workdir = ovl_workdir_create(ufs->upper_mnt, workpath.dentry);
  		err = PTR_ERR(ufs->workdir);
  		if (IS_ERR(ufs->workdir)) {
cc6f67bca   Miklos Szeredi   ovl: mount read-o...
1192
1193
1194
1195
1196
  			pr_warn("overlayfs: failed to create directory %s/%s (errno: %i); mounting read-only
  ",
  				ufs->config.workdir, OVL_WORKDIR_NAME, -err);
  			sb->s_flags |= MS_RDONLY;
  			ufs->workdir = NULL;
53a08cb9b   Miklos Szeredi   ovl: make upperdi...
1197
  		}
45aebeaf4   Vivek Goyal   ovl: Ensure upper...
1198
1199
1200
1201
  
  		/*
  		 * Upper should support d_type, else whiteouts are visible.
  		 * Given workdir and upper are on same fs, we can do
21765194c   Vivek Goyal   ovl: Do d_type ch...
1202
1203
  		 * iterate_dir() on workdir. This check requires successful
  		 * creation of workdir in previous step.
45aebeaf4   Vivek Goyal   ovl: Ensure upper...
1204
  		 */
21765194c   Vivek Goyal   ovl: Do d_type ch...
1205
1206
1207
1208
  		if (ufs->workdir) {
  			err = ovl_check_d_type_supported(&workpath);
  			if (err < 0)
  				goto out_put_workdir;
45aebeaf4   Vivek Goyal   ovl: Ensure upper...
1209

e7c0b5991   Vivek Goyal   ovl: warn instead...
1210
1211
1212
1213
1214
1215
1216
1217
  			/*
  			 * We allowed this configuration and don't want to
  			 * break users over kernel upgrade. So warn instead
  			 * of erroring out.
  			 */
  			if (!err)
  				pr_warn("overlayfs: upper fs needs to support d_type.
  ");
45aebeaf4   Vivek Goyal   ovl: Ensure upper...
1218
  		}
e9be9d5e7   Miklos Szeredi   overlay filesystem
1219
  	}
2f83fd8c2   hujianyang   ovl: Fix kernel p...
1220
  	err = -ENOMEM;
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1221
  	ufs->lower_mnt = kcalloc(numlower, sizeof(struct vfsmount *), GFP_KERNEL);
dd662667e   Miklos Szeredi   ovl: add mutli-la...
1222
  	if (ufs->lower_mnt == NULL)
3b7a9a249   Miklos Szeredi   ovl: mount: chang...
1223
  		goto out_put_workdir;
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1224
1225
  	for (i = 0; i < numlower; i++) {
  		struct vfsmount *mnt = clone_private_mount(&stack[i]);
dd662667e   Miklos Szeredi   ovl: add mutli-la...
1226

2f83fd8c2   hujianyang   ovl: Fix kernel p...
1227
  		err = PTR_ERR(mnt);
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1228
1229
1230
1231
1232
1233
1234
1235
1236
  		if (IS_ERR(mnt)) {
  			pr_err("overlayfs: failed to clone lowerpath
  ");
  			goto out_put_lower_mnt;
  		}
  		/*
  		 * Make lower_mnt R/O.  That way fchmod/fchown on lower file
  		 * will fail instead of modifying lower fs.
  		 */
d719e8f26   Miklos Szeredi   ovl: update atime...
1237
  		mnt->mnt_flags |= MNT_READONLY | MNT_NOATIME;
dd662667e   Miklos Szeredi   ovl: add mutli-la...
1238

a78d9f0d5   Miklos Szeredi   ovl: support mult...
1239
1240
1241
  		ufs->lower_mnt[ufs->numlower] = mnt;
  		ufs->numlower++;
  	}
e9be9d5e7   Miklos Szeredi   overlay filesystem
1242

71cbad7e6   hujianyang   ovl: upper fs sho...
1243
1244
  	/* If the upper fs is nonexistent, we mark overlayfs r/o too */
  	if (!ufs->upper_mnt)
e9be9d5e7   Miklos Szeredi   overlay filesystem
1245
  		sb->s_flags |= MS_RDONLY;
7c03b5d45   Miklos Szeredi   ovl: allow distri...
1246
1247
1248
1249
  	if (remote)
  		sb->s_d_op = &ovl_reval_dentry_operations;
  	else
  		sb->s_d_op = &ovl_dentry_operations;
e9be9d5e7   Miklos Szeredi   overlay filesystem
1250

3fe6e52f0   Antonio Murdaca   ovl: override cre...
1251
1252
1253
  	ufs->creator_cred = prepare_creds();
  	if (!ufs->creator_cred)
  		goto out_put_lower_mnt;
e9be9d5e7   Miklos Szeredi   overlay filesystem
1254
  	err = -ENOMEM;
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1255
  	oe = ovl_alloc_entry(numlower);
3b7a9a249   Miklos Szeredi   ovl: mount: chang...
1256
  	if (!oe)
3fe6e52f0   Antonio Murdaca   ovl: override cre...
1257
  		goto out_put_cred;
e9be9d5e7   Miklos Szeredi   overlay filesystem
1258

655042cc1   Vivek Goyal   overlayfs: Fix se...
1259
1260
1261
1262
1263
  	sb->s_magic = OVERLAYFS_SUPER_MAGIC;
  	sb->s_op = &ovl_super_operations;
  	sb->s_xattr = ovl_xattr_handlers;
  	sb->s_fs_info = ufs;
  	sb->s_flags |= MS_POSIXACL | MS_NOREMOTELOCK;
39b681f80   Miklos Szeredi   ovl: store real i...
1264
  	root_dentry = d_make_root(ovl_new_inode(sb, S_IFDIR));
e9be9d5e7   Miklos Szeredi   overlay filesystem
1265
  	if (!root_dentry)
3b7a9a249   Miklos Szeredi   ovl: mount: chang...
1266
  		goto out_free_oe;
e9be9d5e7   Miklos Szeredi   overlay filesystem
1267
1268
  
  	mntput(upperpath.mnt);
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1269
1270
  	for (i = 0; i < numlower; i++)
  		mntput(stack[i].mnt);
e9be9d5e7   Miklos Szeredi   overlay filesystem
1271
  	path_put(&workpath);
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1272
  	kfree(lowertmp);
e9be9d5e7   Miklos Szeredi   overlay filesystem
1273
1274
  
  	oe->__upperdentry = upperpath.dentry;
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1275
1276
1277
1278
  	for (i = 0; i < numlower; i++) {
  		oe->lowerstack[i].dentry = stack[i].dentry;
  		oe->lowerstack[i].mnt = ufs->lower_mnt[i];
  	}
0f95502ad   Konstantin Khlebnikov   ovl: free stack o...
1279
  	kfree(stack);
e9be9d5e7   Miklos Szeredi   overlay filesystem
1280
1281
  
  	root_dentry->d_fsdata = oe;
39b681f80   Miklos Szeredi   ovl: store real i...
1282
1283
1284
  	realinode = d_inode(ovl_dentry_real(root_dentry));
  	ovl_inode_init(d_inode(root_dentry), realinode, !!upperpath.dentry);
  	ovl_copyattr(realinode, d_inode(root_dentry));
ed06e0697   Miklos Szeredi   ovl: root: copy attr
1285

e9be9d5e7   Miklos Szeredi   overlay filesystem
1286
  	sb->s_root = root_dentry;
e9be9d5e7   Miklos Szeredi   overlay filesystem
1287
1288
  
  	return 0;
3b7a9a249   Miklos Szeredi   ovl: mount: chang...
1289
1290
  out_free_oe:
  	kfree(oe);
3fe6e52f0   Antonio Murdaca   ovl: override cre...
1291
1292
  out_put_cred:
  	put_cred(ufs->creator_cred);
e9be9d5e7   Miklos Szeredi   overlay filesystem
1293
  out_put_lower_mnt:
dd662667e   Miklos Szeredi   ovl: add mutli-la...
1294
1295
1296
  	for (i = 0; i < ufs->numlower; i++)
  		mntput(ufs->lower_mnt[i]);
  	kfree(ufs->lower_mnt);
3b7a9a249   Miklos Szeredi   ovl: mount: chang...
1297
1298
  out_put_workdir:
  	dput(ufs->workdir);
e9be9d5e7   Miklos Szeredi   overlay filesystem
1299
  	mntput(ufs->upper_mnt);
e9be9d5e7   Miklos Szeredi   overlay filesystem
1300
  out_put_lowerpath:
a78d9f0d5   Miklos Szeredi   ovl: support mult...
1301
1302
1303
1304
1305
  	for (i = 0; i < numlower; i++)
  		path_put(&stack[i]);
  	kfree(stack);
  out_free_lowertmp:
  	kfree(lowertmp);
3b7a9a249   Miklos Szeredi   ovl: mount: chang...
1306
1307
  out_put_workpath:
  	path_put(&workpath);
e9be9d5e7   Miklos Szeredi   overlay filesystem
1308
1309
  out_put_upperpath:
  	path_put(&upperpath);
e9be9d5e7   Miklos Szeredi   overlay filesystem
1310
  out_free_config:
f45827e84   Erez Zadok   overlayfs: implem...
1311
1312
1313
1314
  	kfree(ufs->config.lowerdir);
  	kfree(ufs->config.upperdir);
  	kfree(ufs->config.workdir);
  	kfree(ufs);
e9be9d5e7   Miklos Szeredi   overlay filesystem
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
  out:
  	return err;
  }
  
  static struct dentry *ovl_mount(struct file_system_type *fs_type, int flags,
  				const char *dev_name, void *raw_data)
  {
  	return mount_nodev(fs_type, flags, raw_data, ovl_fill_super);
  }
  
  static struct file_system_type ovl_fs_type = {
  	.owner		= THIS_MODULE,
ef94b1864   Miklos Szeredi   ovl: rename files...
1327
  	.name		= "overlay",
e9be9d5e7   Miklos Szeredi   overlay filesystem
1328
1329
1330
  	.mount		= ovl_mount,
  	.kill_sb	= kill_anon_super,
  };
ef94b1864   Miklos Szeredi   ovl: rename files...
1331
  MODULE_ALIAS_FS("overlay");
e9be9d5e7   Miklos Szeredi   overlay filesystem
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
  
  static int __init ovl_init(void)
  {
  	return register_filesystem(&ovl_fs_type);
  }
  
  static void __exit ovl_exit(void)
  {
  	unregister_filesystem(&ovl_fs_type);
  }
  
  module_init(ovl_init);
  module_exit(ovl_exit);