xref: /openbmc/linux/fs/overlayfs/dir.c (revision 6cf00764)
1e9be9d5eSMiklos Szeredi /*
2e9be9d5eSMiklos Szeredi  *
3e9be9d5eSMiklos Szeredi  * Copyright (C) 2011 Novell Inc.
4e9be9d5eSMiklos Szeredi  *
5e9be9d5eSMiklos Szeredi  * This program is free software; you can redistribute it and/or modify it
6e9be9d5eSMiklos Szeredi  * under the terms of the GNU General Public License version 2 as published by
7e9be9d5eSMiklos Szeredi  * the Free Software Foundation.
8e9be9d5eSMiklos Szeredi  */
9e9be9d5eSMiklos Szeredi 
10e9be9d5eSMiklos Szeredi #include <linux/fs.h>
11e9be9d5eSMiklos Szeredi #include <linux/namei.h>
12e9be9d5eSMiklos Szeredi #include <linux/xattr.h>
13e9be9d5eSMiklos Szeredi #include <linux/security.h>
14e9be9d5eSMiklos Szeredi #include <linux/cred.h>
153ea22a71SMiklos Szeredi #include <linux/module.h>
1638b25697SMiklos Szeredi #include <linux/posix_acl.h>
1738b25697SMiklos Szeredi #include <linux/posix_acl_xattr.h>
186a45b362SRichard Weinberger #include <linux/atomic.h>
19a6c60655SMiklos Szeredi #include <linux/ratelimit.h>
20e9be9d5eSMiklos Szeredi #include "overlayfs.h"
21e9be9d5eSMiklos Szeredi 
223ea22a71SMiklos Szeredi static unsigned short ovl_redirect_max = 256;
233ea22a71SMiklos Szeredi module_param_named(redirect_max, ovl_redirect_max, ushort, 0644);
243ea22a71SMiklos Szeredi MODULE_PARM_DESC(ovl_redirect_max,
253ea22a71SMiklos Szeredi 		 "Maximum length of absolute redirect xattr value");
263ea22a71SMiklos Szeredi 
27415543d5SAmir Goldstein int ovl_cleanup(struct inode *wdir, struct dentry *wdentry)
28e9be9d5eSMiklos Szeredi {
29e9be9d5eSMiklos Szeredi 	int err;
30e9be9d5eSMiklos Szeredi 
31e9be9d5eSMiklos Szeredi 	dget(wdentry);
32e36cb0b8SDavid Howells 	if (d_is_dir(wdentry))
33e9be9d5eSMiklos Szeredi 		err = ovl_do_rmdir(wdir, wdentry);
34e9be9d5eSMiklos Szeredi 	else
35e9be9d5eSMiklos Szeredi 		err = ovl_do_unlink(wdir, wdentry);
36e9be9d5eSMiklos Szeredi 	dput(wdentry);
37e9be9d5eSMiklos Szeredi 
38e9be9d5eSMiklos Szeredi 	if (err) {
39e9be9d5eSMiklos Szeredi 		pr_err("overlayfs: cleanup of '%pd2' failed (%i)\n",
40e9be9d5eSMiklos Szeredi 		       wdentry, err);
41e9be9d5eSMiklos Szeredi 	}
42415543d5SAmir Goldstein 
43415543d5SAmir Goldstein 	return err;
44e9be9d5eSMiklos Szeredi }
45e9be9d5eSMiklos Szeredi 
463d27573cSMiklos Szeredi struct dentry *ovl_lookup_temp(struct dentry *workdir)
47e9be9d5eSMiklos Szeredi {
48e9be9d5eSMiklos Szeredi 	struct dentry *temp;
49e9be9d5eSMiklos Szeredi 	char name[20];
506a45b362SRichard Weinberger 	static atomic_t temp_id = ATOMIC_INIT(0);
51e9be9d5eSMiklos Szeredi 
526a45b362SRichard Weinberger 	/* counter is allowed to wrap, since temp dentries are ephemeral */
536a45b362SRichard Weinberger 	snprintf(name, sizeof(name), "#%x", atomic_inc_return(&temp_id));
54e9be9d5eSMiklos Szeredi 
55e9be9d5eSMiklos Szeredi 	temp = lookup_one_len(name, workdir, strlen(name));
56e9be9d5eSMiklos Szeredi 	if (!IS_ERR(temp) && temp->d_inode) {
57e9be9d5eSMiklos Szeredi 		pr_err("overlayfs: workdir/%s already exists\n", name);
58e9be9d5eSMiklos Szeredi 		dput(temp);
59e9be9d5eSMiklos Szeredi 		temp = ERR_PTR(-EIO);
60e9be9d5eSMiklos Szeredi 	}
61e9be9d5eSMiklos Szeredi 
62e9be9d5eSMiklos Szeredi 	return temp;
63e9be9d5eSMiklos Szeredi }
64e9be9d5eSMiklos Szeredi 
65e9be9d5eSMiklos Szeredi /* caller holds i_mutex on workdir */
66e7dd0e71SAmir Goldstein static struct dentry *ovl_whiteout(struct dentry *workdir)
67e9be9d5eSMiklos Szeredi {
68e9be9d5eSMiklos Szeredi 	int err;
69e9be9d5eSMiklos Szeredi 	struct dentry *whiteout;
70e9be9d5eSMiklos Szeredi 	struct inode *wdir = workdir->d_inode;
71e9be9d5eSMiklos Szeredi 
723d27573cSMiklos Szeredi 	whiteout = ovl_lookup_temp(workdir);
73e9be9d5eSMiklos Szeredi 	if (IS_ERR(whiteout))
74e9be9d5eSMiklos Szeredi 		return whiteout;
75e9be9d5eSMiklos Szeredi 
76e9be9d5eSMiklos Szeredi 	err = ovl_do_whiteout(wdir, whiteout);
77e9be9d5eSMiklos Szeredi 	if (err) {
78e9be9d5eSMiklos Szeredi 		dput(whiteout);
79e9be9d5eSMiklos Szeredi 		whiteout = ERR_PTR(err);
80e9be9d5eSMiklos Szeredi 	}
81e9be9d5eSMiklos Szeredi 
82e9be9d5eSMiklos Szeredi 	return whiteout;
83e9be9d5eSMiklos Szeredi }
84e9be9d5eSMiklos Szeredi 
85e7dd0e71SAmir Goldstein /* Caller must hold i_mutex on both workdir and dir */
86e7dd0e71SAmir Goldstein int ovl_cleanup_and_whiteout(struct dentry *workdir, struct inode *dir,
87e7dd0e71SAmir Goldstein 			     struct dentry *dentry)
88e7dd0e71SAmir Goldstein {
89e7dd0e71SAmir Goldstein 	struct inode *wdir = workdir->d_inode;
90e7dd0e71SAmir Goldstein 	struct dentry *whiteout;
91e7dd0e71SAmir Goldstein 	int err;
92e7dd0e71SAmir Goldstein 	int flags = 0;
93e7dd0e71SAmir Goldstein 
94e7dd0e71SAmir Goldstein 	whiteout = ovl_whiteout(workdir);
95e7dd0e71SAmir Goldstein 	err = PTR_ERR(whiteout);
96e7dd0e71SAmir Goldstein 	if (IS_ERR(whiteout))
97e7dd0e71SAmir Goldstein 		return err;
98e7dd0e71SAmir Goldstein 
99e7dd0e71SAmir Goldstein 	if (d_is_dir(dentry))
100e7dd0e71SAmir Goldstein 		flags = RENAME_EXCHANGE;
101e7dd0e71SAmir Goldstein 
102e7dd0e71SAmir Goldstein 	err = ovl_do_rename(wdir, whiteout, dir, dentry, flags);
103e7dd0e71SAmir Goldstein 	if (err)
104e7dd0e71SAmir Goldstein 		goto kill_whiteout;
105e7dd0e71SAmir Goldstein 	if (flags)
106e7dd0e71SAmir Goldstein 		ovl_cleanup(wdir, dentry);
107e7dd0e71SAmir Goldstein 
108e7dd0e71SAmir Goldstein out:
109e7dd0e71SAmir Goldstein 	dput(whiteout);
110e7dd0e71SAmir Goldstein 	return err;
111e7dd0e71SAmir Goldstein 
112e7dd0e71SAmir Goldstein kill_whiteout:
113e7dd0e71SAmir Goldstein 	ovl_cleanup(wdir, whiteout);
114e7dd0e71SAmir Goldstein 	goto out;
115e7dd0e71SAmir Goldstein }
116e7dd0e71SAmir Goldstein 
117e9be9d5eSMiklos Szeredi int ovl_create_real(struct inode *dir, struct dentry *newdentry,
1186cf00764SAmir Goldstein 		    struct cattr *attr, struct dentry *hardlink)
119e9be9d5eSMiklos Szeredi {
120e9be9d5eSMiklos Szeredi 	int err;
121e9be9d5eSMiklos Szeredi 
122e9be9d5eSMiklos Szeredi 	if (newdentry->d_inode)
123e9be9d5eSMiklos Szeredi 		return -ESTALE;
124e9be9d5eSMiklos Szeredi 
125e9be9d5eSMiklos Szeredi 	if (hardlink) {
1266cf00764SAmir Goldstein 		err = ovl_do_link(hardlink, dir, newdentry);
127e9be9d5eSMiklos Szeredi 	} else {
12832a3d848SAl Viro 		switch (attr->mode & S_IFMT) {
129e9be9d5eSMiklos Szeredi 		case S_IFREG:
1306cf00764SAmir Goldstein 			err = ovl_do_create(dir, newdentry, attr->mode);
131e9be9d5eSMiklos Szeredi 			break;
132e9be9d5eSMiklos Szeredi 
133e9be9d5eSMiklos Szeredi 		case S_IFDIR:
1346cf00764SAmir Goldstein 			err = ovl_do_mkdir(dir, newdentry, attr->mode);
135e9be9d5eSMiklos Szeredi 			break;
136e9be9d5eSMiklos Szeredi 
137e9be9d5eSMiklos Szeredi 		case S_IFCHR:
138e9be9d5eSMiklos Szeredi 		case S_IFBLK:
139e9be9d5eSMiklos Szeredi 		case S_IFIFO:
140e9be9d5eSMiklos Szeredi 		case S_IFSOCK:
1416cf00764SAmir Goldstein 			err = ovl_do_mknod(dir, newdentry, attr->mode,
1426cf00764SAmir Goldstein 					   attr->rdev);
143e9be9d5eSMiklos Szeredi 			break;
144e9be9d5eSMiklos Szeredi 
145e9be9d5eSMiklos Szeredi 		case S_IFLNK:
1466cf00764SAmir Goldstein 			err = ovl_do_symlink(dir, newdentry, attr->link);
147e9be9d5eSMiklos Szeredi 			break;
148e9be9d5eSMiklos Szeredi 
149e9be9d5eSMiklos Szeredi 		default:
150e9be9d5eSMiklos Szeredi 			err = -EPERM;
151e9be9d5eSMiklos Szeredi 		}
152e9be9d5eSMiklos Szeredi 	}
153e9be9d5eSMiklos Szeredi 	if (!err && WARN_ON(!newdentry->d_inode)) {
154e9be9d5eSMiklos Szeredi 		/*
155e9be9d5eSMiklos Szeredi 		 * Not quite sure if non-instantiated dentry is legal or not.
156e9be9d5eSMiklos Szeredi 		 * VFS doesn't seem to care so check and warn here.
157e9be9d5eSMiklos Szeredi 		 */
158e9be9d5eSMiklos Szeredi 		err = -ENOENT;
159e9be9d5eSMiklos Szeredi 	}
160e9be9d5eSMiklos Szeredi 	return err;
161e9be9d5eSMiklos Szeredi }
162e9be9d5eSMiklos Szeredi 
16321a22878SAmir Goldstein static int ovl_set_opaque_xerr(struct dentry *dentry, struct dentry *upper,
16421a22878SAmir Goldstein 			       int xerr)
165e9be9d5eSMiklos Szeredi {
1665cf5b477SMiklos Szeredi 	int err;
1675cf5b477SMiklos Szeredi 
16821a22878SAmir Goldstein 	err = ovl_check_setxattr(dentry, upper, OVL_XATTR_OPAQUE, "y", 1, xerr);
1695cf5b477SMiklos Szeredi 	if (!err)
1705cf5b477SMiklos Szeredi 		ovl_dentry_set_opaque(dentry);
1715cf5b477SMiklos Szeredi 
1725cf5b477SMiklos Szeredi 	return err;
173e9be9d5eSMiklos Szeredi }
174e9be9d5eSMiklos Szeredi 
17521a22878SAmir Goldstein static int ovl_set_opaque(struct dentry *dentry, struct dentry *upperdentry)
17621a22878SAmir Goldstein {
17721a22878SAmir Goldstein 	/*
17821a22878SAmir Goldstein 	 * Fail with -EIO when trying to create opaque dir and upper doesn't
17921a22878SAmir Goldstein 	 * support xattrs. ovl_rename() calls ovl_set_opaque_xerr(-EXDEV) to
18021a22878SAmir Goldstein 	 * return a specific error for noxattr case.
18121a22878SAmir Goldstein 	 */
18221a22878SAmir Goldstein 	return ovl_set_opaque_xerr(dentry, upperdentry, -EIO);
18321a22878SAmir Goldstein }
18421a22878SAmir Goldstein 
18572e48481SVivek Goyal /* Common operations required to be done after creation of file on upper */
18672e48481SVivek Goyal static void ovl_instantiate(struct dentry *dentry, struct inode *inode,
18751f7e52dSMiklos Szeredi 			    struct dentry *newdentry, bool hardlink)
18872e48481SVivek Goyal {
1894edb83bbSMiklos Szeredi 	ovl_dentry_version_inc(dentry->d_parent, false);
19055acc661SMiklos Szeredi 	ovl_dentry_set_upper_alias(dentry);
19151f7e52dSMiklos Szeredi 	if (!hardlink) {
19209d8b586SMiklos Szeredi 		ovl_inode_update(inode, newdentry);
19372e48481SVivek Goyal 		ovl_copyattr(newdentry->d_inode, inode);
19451f7e52dSMiklos Szeredi 	} else {
19509d8b586SMiklos Szeredi 		WARN_ON(ovl_inode_real(inode) != d_inode(newdentry));
19609d8b586SMiklos Szeredi 		dput(newdentry);
19751f7e52dSMiklos Szeredi 		inc_nlink(inode);
19851f7e52dSMiklos Szeredi 	}
19972e48481SVivek Goyal 	d_instantiate(dentry, inode);
2005b6c9053SAmir Goldstein 	/* Force lookup of new upper hardlink to find its lower */
2015b6c9053SAmir Goldstein 	if (hardlink)
2025b6c9053SAmir Goldstein 		d_drop(dentry);
20372e48481SVivek Goyal }
20472e48481SVivek Goyal 
20597c684ccSAmir Goldstein static bool ovl_type_merge(struct dentry *dentry)
20697c684ccSAmir Goldstein {
20797c684ccSAmir Goldstein 	return OVL_TYPE_MERGE(ovl_path_type(dentry));
20897c684ccSAmir Goldstein }
20997c684ccSAmir Goldstein 
210ee1d6d37SAmir Goldstein static bool ovl_type_origin(struct dentry *dentry)
211ee1d6d37SAmir Goldstein {
212ee1d6d37SAmir Goldstein 	return OVL_TYPE_ORIGIN(ovl_path_type(dentry));
213ee1d6d37SAmir Goldstein }
214ee1d6d37SAmir Goldstein 
215e9be9d5eSMiklos Szeredi static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
21632a3d848SAl Viro 			    struct cattr *attr, struct dentry *hardlink)
217e9be9d5eSMiklos Szeredi {
218e9be9d5eSMiklos Szeredi 	struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
219e9be9d5eSMiklos Szeredi 	struct inode *udir = upperdir->d_inode;
220e9be9d5eSMiklos Szeredi 	struct dentry *newdentry;
221e9be9d5eSMiklos Szeredi 	int err;
222e9be9d5eSMiklos Szeredi 
22338b25697SMiklos Szeredi 	if (!hardlink && !IS_POSIXACL(udir))
22432a3d848SAl Viro 		attr->mode &= ~current_umask();
22538b25697SMiklos Szeredi 
2265955102cSAl Viro 	inode_lock_nested(udir, I_MUTEX_PARENT);
227e9be9d5eSMiklos Szeredi 	newdentry = lookup_one_len(dentry->d_name.name, upperdir,
228e9be9d5eSMiklos Szeredi 				   dentry->d_name.len);
229e9be9d5eSMiklos Szeredi 	err = PTR_ERR(newdentry);
230e9be9d5eSMiklos Szeredi 	if (IS_ERR(newdentry))
231e9be9d5eSMiklos Szeredi 		goto out_unlock;
2326cf00764SAmir Goldstein 	err = ovl_create_real(udir, newdentry, attr, hardlink);
233e9be9d5eSMiklos Szeredi 	if (err)
234e9be9d5eSMiklos Szeredi 		goto out_dput;
235e9be9d5eSMiklos Szeredi 
2364a99f3c8SAmir Goldstein 	if (ovl_type_merge(dentry->d_parent) && d_is_dir(newdentry)) {
23797c684ccSAmir Goldstein 		/* Setting opaque here is just an optimization, allow to fail */
23897c684ccSAmir Goldstein 		ovl_set_opaque(dentry, newdentry);
23997c684ccSAmir Goldstein 	}
24097c684ccSAmir Goldstein 
24151f7e52dSMiklos Szeredi 	ovl_instantiate(dentry, inode, newdentry, !!hardlink);
242e9be9d5eSMiklos Szeredi 	newdentry = NULL;
243e9be9d5eSMiklos Szeredi out_dput:
244e9be9d5eSMiklos Szeredi 	dput(newdentry);
245e9be9d5eSMiklos Szeredi out_unlock:
2465955102cSAl Viro 	inode_unlock(udir);
247e9be9d5eSMiklos Szeredi 	return err;
248e9be9d5eSMiklos Szeredi }
249e9be9d5eSMiklos Szeredi 
250e9be9d5eSMiklos Szeredi static struct dentry *ovl_clear_empty(struct dentry *dentry,
251e9be9d5eSMiklos Szeredi 				      struct list_head *list)
252e9be9d5eSMiklos Szeredi {
253e9be9d5eSMiklos Szeredi 	struct dentry *workdir = ovl_workdir(dentry);
254e9be9d5eSMiklos Szeredi 	struct inode *wdir = workdir->d_inode;
255e9be9d5eSMiklos Szeredi 	struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
256e9be9d5eSMiklos Szeredi 	struct inode *udir = upperdir->d_inode;
257e9be9d5eSMiklos Szeredi 	struct path upperpath;
258e9be9d5eSMiklos Szeredi 	struct dentry *upper;
259e9be9d5eSMiklos Szeredi 	struct dentry *opaquedir;
260e9be9d5eSMiklos Szeredi 	struct kstat stat;
261e9be9d5eSMiklos Szeredi 	int err;
262e9be9d5eSMiklos Szeredi 
263cc6f67bcSMiklos Szeredi 	if (WARN_ON(!workdir))
264cc6f67bcSMiklos Szeredi 		return ERR_PTR(-EROFS);
265cc6f67bcSMiklos Szeredi 
266e9be9d5eSMiklos Szeredi 	err = ovl_lock_rename_workdir(workdir, upperdir);
267e9be9d5eSMiklos Szeredi 	if (err)
268e9be9d5eSMiklos Szeredi 		goto out;
269e9be9d5eSMiklos Szeredi 
270e9be9d5eSMiklos Szeredi 	ovl_path_upper(dentry, &upperpath);
271a528d35eSDavid Howells 	err = vfs_getattr(&upperpath, &stat,
272a528d35eSDavid Howells 			  STATX_BASIC_STATS, AT_STATX_SYNC_AS_STAT);
273e9be9d5eSMiklos Szeredi 	if (err)
274e9be9d5eSMiklos Szeredi 		goto out_unlock;
275e9be9d5eSMiklos Szeredi 
276e9be9d5eSMiklos Szeredi 	err = -ESTALE;
277e9be9d5eSMiklos Szeredi 	if (!S_ISDIR(stat.mode))
278e9be9d5eSMiklos Szeredi 		goto out_unlock;
279e9be9d5eSMiklos Szeredi 	upper = upperpath.dentry;
280e9be9d5eSMiklos Szeredi 	if (upper->d_parent->d_inode != udir)
281e9be9d5eSMiklos Szeredi 		goto out_unlock;
282e9be9d5eSMiklos Szeredi 
2833d27573cSMiklos Szeredi 	opaquedir = ovl_lookup_temp(workdir);
284e9be9d5eSMiklos Szeredi 	err = PTR_ERR(opaquedir);
285e9be9d5eSMiklos Szeredi 	if (IS_ERR(opaquedir))
286e9be9d5eSMiklos Szeredi 		goto out_unlock;
287e9be9d5eSMiklos Szeredi 
28832a3d848SAl Viro 	err = ovl_create_real(wdir, opaquedir,
2896cf00764SAmir Goldstein 			      &(struct cattr){.mode = stat.mode}, NULL);
290e9be9d5eSMiklos Szeredi 	if (err)
291e9be9d5eSMiklos Szeredi 		goto out_dput;
292e9be9d5eSMiklos Szeredi 
293e9be9d5eSMiklos Szeredi 	err = ovl_copy_xattr(upper, opaquedir);
294e9be9d5eSMiklos Szeredi 	if (err)
295e9be9d5eSMiklos Szeredi 		goto out_cleanup;
296e9be9d5eSMiklos Szeredi 
2975cf5b477SMiklos Szeredi 	err = ovl_set_opaque(dentry, opaquedir);
298e9be9d5eSMiklos Szeredi 	if (err)
299e9be9d5eSMiklos Szeredi 		goto out_cleanup;
300e9be9d5eSMiklos Szeredi 
3015955102cSAl Viro 	inode_lock(opaquedir->d_inode);
302e9be9d5eSMiklos Szeredi 	err = ovl_set_attr(opaquedir, &stat);
3035955102cSAl Viro 	inode_unlock(opaquedir->d_inode);
304e9be9d5eSMiklos Szeredi 	if (err)
305e9be9d5eSMiklos Szeredi 		goto out_cleanup;
306e9be9d5eSMiklos Szeredi 
307e9be9d5eSMiklos Szeredi 	err = ovl_do_rename(wdir, opaquedir, udir, upper, RENAME_EXCHANGE);
308e9be9d5eSMiklos Szeredi 	if (err)
309e9be9d5eSMiklos Szeredi 		goto out_cleanup;
310e9be9d5eSMiklos Szeredi 
311e9be9d5eSMiklos Szeredi 	ovl_cleanup_whiteouts(upper, list);
312e9be9d5eSMiklos Szeredi 	ovl_cleanup(wdir, upper);
313e9be9d5eSMiklos Szeredi 	unlock_rename(workdir, upperdir);
314e9be9d5eSMiklos Szeredi 
315e9be9d5eSMiklos Szeredi 	/* dentry's upper doesn't match now, get rid of it */
316e9be9d5eSMiklos Szeredi 	d_drop(dentry);
317e9be9d5eSMiklos Szeredi 
318e9be9d5eSMiklos Szeredi 	return opaquedir;
319e9be9d5eSMiklos Szeredi 
320e9be9d5eSMiklos Szeredi out_cleanup:
321e9be9d5eSMiklos Szeredi 	ovl_cleanup(wdir, opaquedir);
322e9be9d5eSMiklos Szeredi out_dput:
323e9be9d5eSMiklos Szeredi 	dput(opaquedir);
324e9be9d5eSMiklos Szeredi out_unlock:
325e9be9d5eSMiklos Szeredi 	unlock_rename(workdir, upperdir);
326e9be9d5eSMiklos Szeredi out:
327e9be9d5eSMiklos Szeredi 	return ERR_PTR(err);
328e9be9d5eSMiklos Szeredi }
329e9be9d5eSMiklos Szeredi 
33038b25697SMiklos Szeredi static int ovl_set_upper_acl(struct dentry *upperdentry, const char *name,
33138b25697SMiklos Szeredi 			     const struct posix_acl *acl)
33238b25697SMiklos Szeredi {
33338b25697SMiklos Szeredi 	void *buffer;
33438b25697SMiklos Szeredi 	size_t size;
33538b25697SMiklos Szeredi 	int err;
33638b25697SMiklos Szeredi 
33738b25697SMiklos Szeredi 	if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !acl)
33838b25697SMiklos Szeredi 		return 0;
33938b25697SMiklos Szeredi 
34038b25697SMiklos Szeredi 	size = posix_acl_to_xattr(NULL, acl, NULL, 0);
34138b25697SMiklos Szeredi 	buffer = kmalloc(size, GFP_KERNEL);
34238b25697SMiklos Szeredi 	if (!buffer)
34338b25697SMiklos Szeredi 		return -ENOMEM;
34438b25697SMiklos Szeredi 
34538b25697SMiklos Szeredi 	size = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
34638b25697SMiklos Szeredi 	err = size;
34738b25697SMiklos Szeredi 	if (err < 0)
34838b25697SMiklos Szeredi 		goto out_free;
34938b25697SMiklos Szeredi 
35038b25697SMiklos Szeredi 	err = vfs_setxattr(upperdentry, name, buffer, size, XATTR_CREATE);
35138b25697SMiklos Szeredi out_free:
35238b25697SMiklos Szeredi 	kfree(buffer);
35338b25697SMiklos Szeredi 	return err;
35438b25697SMiklos Szeredi }
35538b25697SMiklos Szeredi 
356e9be9d5eSMiklos Szeredi static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
35732a3d848SAl Viro 				    struct cattr *cattr,
358e9be9d5eSMiklos Szeredi 				    struct dentry *hardlink)
359e9be9d5eSMiklos Szeredi {
360e9be9d5eSMiklos Szeredi 	struct dentry *workdir = ovl_workdir(dentry);
361e9be9d5eSMiklos Szeredi 	struct inode *wdir = workdir->d_inode;
362e9be9d5eSMiklos Szeredi 	struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
363e9be9d5eSMiklos Szeredi 	struct inode *udir = upperdir->d_inode;
364e9be9d5eSMiklos Szeredi 	struct dentry *upper;
365e9be9d5eSMiklos Szeredi 	struct dentry *newdentry;
366e9be9d5eSMiklos Szeredi 	int err;
36738b25697SMiklos Szeredi 	struct posix_acl *acl, *default_acl;
368e9be9d5eSMiklos Szeredi 
369cc6f67bcSMiklos Szeredi 	if (WARN_ON(!workdir))
370cc6f67bcSMiklos Szeredi 		return -EROFS;
371cc6f67bcSMiklos Szeredi 
37238b25697SMiklos Szeredi 	if (!hardlink) {
37338b25697SMiklos Szeredi 		err = posix_acl_create(dentry->d_parent->d_inode,
37432a3d848SAl Viro 				       &cattr->mode, &default_acl, &acl);
37538b25697SMiklos Szeredi 		if (err)
37638b25697SMiklos Szeredi 			return err;
37738b25697SMiklos Szeredi 	}
37838b25697SMiklos Szeredi 
379e9be9d5eSMiklos Szeredi 	err = ovl_lock_rename_workdir(workdir, upperdir);
380e9be9d5eSMiklos Szeredi 	if (err)
381e9be9d5eSMiklos Szeredi 		goto out;
382e9be9d5eSMiklos Szeredi 
3833d27573cSMiklos Szeredi 	newdentry = ovl_lookup_temp(workdir);
384e9be9d5eSMiklos Szeredi 	err = PTR_ERR(newdentry);
385e9be9d5eSMiklos Szeredi 	if (IS_ERR(newdentry))
386e9be9d5eSMiklos Szeredi 		goto out_unlock;
387e9be9d5eSMiklos Szeredi 
388e9be9d5eSMiklos Szeredi 	upper = lookup_one_len(dentry->d_name.name, upperdir,
389e9be9d5eSMiklos Szeredi 			       dentry->d_name.len);
390e9be9d5eSMiklos Szeredi 	err = PTR_ERR(upper);
391e9be9d5eSMiklos Szeredi 	if (IS_ERR(upper))
392e9be9d5eSMiklos Szeredi 		goto out_dput;
393e9be9d5eSMiklos Szeredi 
3946cf00764SAmir Goldstein 	err = ovl_create_real(wdir, newdentry, cattr, hardlink);
395e9be9d5eSMiklos Szeredi 	if (err)
396e9be9d5eSMiklos Szeredi 		goto out_dput2;
397e9be9d5eSMiklos Szeredi 
398bb0d2b8aSMiklos Szeredi 	/*
399bb0d2b8aSMiklos Szeredi 	 * mode could have been mutilated due to umask (e.g. sgid directory)
400bb0d2b8aSMiklos Szeredi 	 */
40151f7e52dSMiklos Szeredi 	if (!hardlink &&
40232a3d848SAl Viro 	    !S_ISLNK(cattr->mode) &&
40332a3d848SAl Viro 	    newdentry->d_inode->i_mode != cattr->mode) {
404bb0d2b8aSMiklos Szeredi 		struct iattr attr = {
405bb0d2b8aSMiklos Szeredi 			.ia_valid = ATTR_MODE,
40632a3d848SAl Viro 			.ia_mode = cattr->mode,
407bb0d2b8aSMiklos Szeredi 		};
408bb0d2b8aSMiklos Szeredi 		inode_lock(newdentry->d_inode);
409bb0d2b8aSMiklos Szeredi 		err = notify_change(newdentry, &attr, NULL);
410bb0d2b8aSMiklos Szeredi 		inode_unlock(newdentry->d_inode);
411bb0d2b8aSMiklos Szeredi 		if (err)
412bb0d2b8aSMiklos Szeredi 			goto out_cleanup;
413bb0d2b8aSMiklos Szeredi 	}
41438b25697SMiklos Szeredi 	if (!hardlink) {
41538b25697SMiklos Szeredi 		err = ovl_set_upper_acl(newdentry, XATTR_NAME_POSIX_ACL_ACCESS,
41638b25697SMiklos Szeredi 					acl);
41738b25697SMiklos Szeredi 		if (err)
41838b25697SMiklos Szeredi 			goto out_cleanup;
41938b25697SMiklos Szeredi 
42038b25697SMiklos Szeredi 		err = ovl_set_upper_acl(newdentry, XATTR_NAME_POSIX_ACL_DEFAULT,
42138b25697SMiklos Szeredi 					default_acl);
42238b25697SMiklos Szeredi 		if (err)
42338b25697SMiklos Szeredi 			goto out_cleanup;
42438b25697SMiklos Szeredi 	}
425bb0d2b8aSMiklos Szeredi 
42632a3d848SAl Viro 	if (!hardlink && S_ISDIR(cattr->mode)) {
4275cf5b477SMiklos Szeredi 		err = ovl_set_opaque(dentry, newdentry);
428e9be9d5eSMiklos Szeredi 		if (err)
429e9be9d5eSMiklos Szeredi 			goto out_cleanup;
430e9be9d5eSMiklos Szeredi 
431e9be9d5eSMiklos Szeredi 		err = ovl_do_rename(wdir, newdentry, udir, upper,
432e9be9d5eSMiklos Szeredi 				    RENAME_EXCHANGE);
433e9be9d5eSMiklos Szeredi 		if (err)
434e9be9d5eSMiklos Szeredi 			goto out_cleanup;
435e9be9d5eSMiklos Szeredi 
436e9be9d5eSMiklos Szeredi 		ovl_cleanup(wdir, upper);
437e9be9d5eSMiklos Szeredi 	} else {
438e9be9d5eSMiklos Szeredi 		err = ovl_do_rename(wdir, newdentry, udir, upper, 0);
439e9be9d5eSMiklos Szeredi 		if (err)
440e9be9d5eSMiklos Szeredi 			goto out_cleanup;
441e9be9d5eSMiklos Szeredi 	}
44251f7e52dSMiklos Szeredi 	ovl_instantiate(dentry, inode, newdentry, !!hardlink);
443e9be9d5eSMiklos Szeredi 	newdentry = NULL;
444e9be9d5eSMiklos Szeredi out_dput2:
445e9be9d5eSMiklos Szeredi 	dput(upper);
446e9be9d5eSMiklos Szeredi out_dput:
447e9be9d5eSMiklos Szeredi 	dput(newdentry);
448e9be9d5eSMiklos Szeredi out_unlock:
449e9be9d5eSMiklos Szeredi 	unlock_rename(workdir, upperdir);
450e9be9d5eSMiklos Szeredi out:
45138b25697SMiklos Szeredi 	if (!hardlink) {
45238b25697SMiklos Szeredi 		posix_acl_release(acl);
45338b25697SMiklos Szeredi 		posix_acl_release(default_acl);
45438b25697SMiklos Szeredi 	}
455e9be9d5eSMiklos Szeredi 	return err;
456e9be9d5eSMiklos Szeredi 
457e9be9d5eSMiklos Szeredi out_cleanup:
458e9be9d5eSMiklos Szeredi 	ovl_cleanup(wdir, newdentry);
459e9be9d5eSMiklos Szeredi 	goto out_dput2;
460e9be9d5eSMiklos Szeredi }
461e9be9d5eSMiklos Szeredi 
46251f7e52dSMiklos Szeredi static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
463ea3dad18SAmir Goldstein 			      struct cattr *attr, struct dentry *hardlink,
464ea3dad18SAmir Goldstein 			      bool origin)
465e9be9d5eSMiklos Szeredi {
466e9be9d5eSMiklos Szeredi 	int err;
4671175b6b8SVivek Goyal 	const struct cred *old_cred;
4681175b6b8SVivek Goyal 	struct cred *override_cred;
469ea3dad18SAmir Goldstein 	struct dentry *parent = dentry->d_parent;
470e9be9d5eSMiklos Szeredi 
471ea3dad18SAmir Goldstein 	err = ovl_copy_up(parent);
472e9be9d5eSMiklos Szeredi 	if (err)
47351f7e52dSMiklos Szeredi 		return err;
474bb0d2b8aSMiklos Szeredi 
4753fe6e52fSAntonio Murdaca 	old_cred = ovl_override_creds(dentry->d_sb);
476ea3dad18SAmir Goldstein 
477ea3dad18SAmir Goldstein 	/*
478ea3dad18SAmir Goldstein 	 * When linking a file with copy up origin into a new parent, mark the
479ea3dad18SAmir Goldstein 	 * new parent dir "impure".
480ea3dad18SAmir Goldstein 	 */
481ea3dad18SAmir Goldstein 	if (origin) {
482ea3dad18SAmir Goldstein 		err = ovl_set_impure(parent, ovl_dentry_upper(parent));
483ea3dad18SAmir Goldstein 		if (err)
484ea3dad18SAmir Goldstein 			goto out_revert_creds;
485ea3dad18SAmir Goldstein 	}
486ea3dad18SAmir Goldstein 
487d0e13f5bSMiklos Szeredi 	err = -ENOMEM;
488d0e13f5bSMiklos Szeredi 	override_cred = prepare_creds();
489d0e13f5bSMiklos Szeredi 	if (override_cred) {
490bb0d2b8aSMiklos Szeredi 		override_cred->fsuid = inode->i_uid;
491bb0d2b8aSMiklos Szeredi 		override_cred->fsgid = inode->i_gid;
4922602625bSVivek Goyal 		if (!hardlink) {
4932602625bSVivek Goyal 			err = security_dentry_create_files_as(dentry,
49432a3d848SAl Viro 					attr->mode, &dentry->d_name, old_cred,
4952602625bSVivek Goyal 					override_cred);
4962602625bSVivek Goyal 			if (err) {
4972602625bSVivek Goyal 				put_cred(override_cred);
4982602625bSVivek Goyal 				goto out_revert_creds;
4992602625bSVivek Goyal 			}
5002602625bSVivek Goyal 		}
501d0e13f5bSMiklos Szeredi 		put_cred(override_creds(override_cred));
502d0e13f5bSMiklos Szeredi 		put_cred(override_cred);
503e9be9d5eSMiklos Szeredi 
504c412ce49SMiklos Szeredi 		if (!ovl_dentry_is_whiteout(dentry))
50532a3d848SAl Viro 			err = ovl_create_upper(dentry, inode, attr,
5061175b6b8SVivek Goyal 						hardlink);
5071175b6b8SVivek Goyal 		else
50832a3d848SAl Viro 			err = ovl_create_over_whiteout(dentry, inode, attr,
50932a3d848SAl Viro 							hardlink);
510d0e13f5bSMiklos Szeredi 	}
5112602625bSVivek Goyal out_revert_creds:
512e9be9d5eSMiklos Szeredi 	revert_creds(old_cred);
513e9be9d5eSMiklos Szeredi 	return err;
514e9be9d5eSMiklos Szeredi }
515e9be9d5eSMiklos Szeredi 
516e9be9d5eSMiklos Szeredi static int ovl_create_object(struct dentry *dentry, int mode, dev_t rdev,
517e9be9d5eSMiklos Szeredi 			     const char *link)
518e9be9d5eSMiklos Szeredi {
519e9be9d5eSMiklos Szeredi 	int err;
52051f7e52dSMiklos Szeredi 	struct inode *inode;
52132a3d848SAl Viro 	struct cattr attr = {
52251f7e52dSMiklos Szeredi 		.rdev = rdev,
52332a3d848SAl Viro 		.link = link,
52451f7e52dSMiklos Szeredi 	};
525e9be9d5eSMiklos Szeredi 
526e9be9d5eSMiklos Szeredi 	err = ovl_want_write(dentry);
52751f7e52dSMiklos Szeredi 	if (err)
52851f7e52dSMiklos Szeredi 		goto out;
529e9be9d5eSMiklos Szeredi 
53051f7e52dSMiklos Szeredi 	err = -ENOMEM;
531ca4c8a3aSMiklos Szeredi 	inode = ovl_new_inode(dentry->d_sb, mode, rdev);
53251f7e52dSMiklos Szeredi 	if (!inode)
53351f7e52dSMiklos Szeredi 		goto out_drop_write;
53451f7e52dSMiklos Szeredi 
53551f7e52dSMiklos Szeredi 	inode_init_owner(inode, dentry->d_parent->d_inode, mode);
53632a3d848SAl Viro 	attr.mode = inode->i_mode;
53751f7e52dSMiklos Szeredi 
538ea3dad18SAmir Goldstein 	err = ovl_create_or_link(dentry, inode, &attr, NULL, false);
53951f7e52dSMiklos Szeredi 	if (err)
54051f7e52dSMiklos Szeredi 		iput(inode);
54151f7e52dSMiklos Szeredi 
54251f7e52dSMiklos Szeredi out_drop_write:
54351f7e52dSMiklos Szeredi 	ovl_drop_write(dentry);
54451f7e52dSMiklos Szeredi out:
545e9be9d5eSMiklos Szeredi 	return err;
546e9be9d5eSMiklos Szeredi }
547e9be9d5eSMiklos Szeredi 
548e9be9d5eSMiklos Szeredi static int ovl_create(struct inode *dir, struct dentry *dentry, umode_t mode,
549e9be9d5eSMiklos Szeredi 		      bool excl)
550e9be9d5eSMiklos Szeredi {
551e9be9d5eSMiklos Szeredi 	return ovl_create_object(dentry, (mode & 07777) | S_IFREG, 0, NULL);
552e9be9d5eSMiklos Szeredi }
553e9be9d5eSMiklos Szeredi 
554e9be9d5eSMiklos Szeredi static int ovl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
555e9be9d5eSMiklos Szeredi {
556e9be9d5eSMiklos Szeredi 	return ovl_create_object(dentry, (mode & 07777) | S_IFDIR, 0, NULL);
557e9be9d5eSMiklos Szeredi }
558e9be9d5eSMiklos Szeredi 
559e9be9d5eSMiklos Szeredi static int ovl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
560e9be9d5eSMiklos Szeredi 		     dev_t rdev)
561e9be9d5eSMiklos Szeredi {
562e9be9d5eSMiklos Szeredi 	/* Don't allow creation of "whiteout" on overlay */
563e9be9d5eSMiklos Szeredi 	if (S_ISCHR(mode) && rdev == WHITEOUT_DEV)
564e9be9d5eSMiklos Szeredi 		return -EPERM;
565e9be9d5eSMiklos Szeredi 
566e9be9d5eSMiklos Szeredi 	return ovl_create_object(dentry, mode, rdev, NULL);
567e9be9d5eSMiklos Szeredi }
568e9be9d5eSMiklos Szeredi 
569e9be9d5eSMiklos Szeredi static int ovl_symlink(struct inode *dir, struct dentry *dentry,
570e9be9d5eSMiklos Szeredi 		       const char *link)
571e9be9d5eSMiklos Szeredi {
572e9be9d5eSMiklos Szeredi 	return ovl_create_object(dentry, S_IFLNK, 0, link);
573e9be9d5eSMiklos Szeredi }
574e9be9d5eSMiklos Szeredi 
575e9be9d5eSMiklos Szeredi static int ovl_link(struct dentry *old, struct inode *newdir,
576e9be9d5eSMiklos Szeredi 		    struct dentry *new)
577e9be9d5eSMiklos Szeredi {
578e9be9d5eSMiklos Szeredi 	int err;
5795f8415d6SAmir Goldstein 	bool locked = false;
58051f7e52dSMiklos Szeredi 	struct inode *inode;
581e9be9d5eSMiklos Szeredi 
582e9be9d5eSMiklos Szeredi 	err = ovl_want_write(old);
583e9be9d5eSMiklos Szeredi 	if (err)
584e9be9d5eSMiklos Szeredi 		goto out;
585e9be9d5eSMiklos Szeredi 
586e9be9d5eSMiklos Szeredi 	err = ovl_copy_up(old);
587e9be9d5eSMiklos Szeredi 	if (err)
588e9be9d5eSMiklos Szeredi 		goto out_drop_write;
589e9be9d5eSMiklos Szeredi 
5905f8415d6SAmir Goldstein 	err = ovl_nlink_start(old, &locked);
5915f8415d6SAmir Goldstein 	if (err)
5925f8415d6SAmir Goldstein 		goto out_drop_write;
5935f8415d6SAmir Goldstein 
59451f7e52dSMiklos Szeredi 	inode = d_inode(old);
59551f7e52dSMiklos Szeredi 	ihold(inode);
59651f7e52dSMiklos Szeredi 
597ea3dad18SAmir Goldstein 	err = ovl_create_or_link(new, inode, NULL, ovl_dentry_upper(old),
598ea3dad18SAmir Goldstein 				 ovl_type_origin(old));
59951f7e52dSMiklos Szeredi 	if (err)
60051f7e52dSMiklos Szeredi 		iput(inode);
601e9be9d5eSMiklos Szeredi 
6025f8415d6SAmir Goldstein 	ovl_nlink_end(old, locked);
603e9be9d5eSMiklos Szeredi out_drop_write:
604e9be9d5eSMiklos Szeredi 	ovl_drop_write(old);
605e9be9d5eSMiklos Szeredi out:
606e9be9d5eSMiklos Szeredi 	return err;
607e9be9d5eSMiklos Szeredi }
608e9be9d5eSMiklos Szeredi 
6099020df37SMiklos Szeredi static bool ovl_matches_upper(struct dentry *dentry, struct dentry *upper)
6109020df37SMiklos Szeredi {
6119020df37SMiklos Szeredi 	return d_inode(ovl_dentry_upper(dentry)) == d_inode(upper);
6129020df37SMiklos Szeredi }
6139020df37SMiklos Szeredi 
6146d0a8a90SAmir Goldstein static int ovl_remove_and_whiteout(struct dentry *dentry,
6156d0a8a90SAmir Goldstein 				   struct list_head *list)
616e9be9d5eSMiklos Szeredi {
617e9be9d5eSMiklos Szeredi 	struct dentry *workdir = ovl_workdir(dentry);
618e9be9d5eSMiklos Szeredi 	struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
619e9be9d5eSMiklos Szeredi 	struct dentry *upper;
620e9be9d5eSMiklos Szeredi 	struct dentry *opaquedir = NULL;
621e9be9d5eSMiklos Szeredi 	int err;
622e9be9d5eSMiklos Szeredi 
623cc6f67bcSMiklos Szeredi 	if (WARN_ON(!workdir))
624cc6f67bcSMiklos Szeredi 		return -EROFS;
625cc6f67bcSMiklos Szeredi 
6266d0a8a90SAmir Goldstein 	if (!list_empty(list)) {
6276d0a8a90SAmir Goldstein 		opaquedir = ovl_clear_empty(dentry, list);
628e9be9d5eSMiklos Szeredi 		err = PTR_ERR(opaquedir);
629e9be9d5eSMiklos Szeredi 		if (IS_ERR(opaquedir))
630e9be9d5eSMiklos Szeredi 			goto out;
631e9be9d5eSMiklos Szeredi 	}
632e9be9d5eSMiklos Szeredi 
633e9be9d5eSMiklos Szeredi 	err = ovl_lock_rename_workdir(workdir, upperdir);
634e9be9d5eSMiklos Szeredi 	if (err)
635e9be9d5eSMiklos Szeredi 		goto out_dput;
636e9be9d5eSMiklos Szeredi 
637e9be9d5eSMiklos Szeredi 	upper = lookup_one_len(dentry->d_name.name, upperdir,
638e9be9d5eSMiklos Szeredi 			       dentry->d_name.len);
639e9be9d5eSMiklos Szeredi 	err = PTR_ERR(upper);
640e9be9d5eSMiklos Szeredi 	if (IS_ERR(upper))
641cfc9fde0SMaxim Patlasov 		goto out_unlock;
642e9be9d5eSMiklos Szeredi 
643e9be9d5eSMiklos Szeredi 	err = -ESTALE;
644cfc9fde0SMaxim Patlasov 	if ((opaquedir && upper != opaquedir) ||
645cfc9fde0SMaxim Patlasov 	    (!opaquedir && ovl_dentry_upper(dentry) &&
6469020df37SMiklos Szeredi 	     !ovl_matches_upper(dentry, upper))) {
647cfc9fde0SMaxim Patlasov 		goto out_dput_upper;
648cfc9fde0SMaxim Patlasov 	}
649e9be9d5eSMiklos Szeredi 
650e7dd0e71SAmir Goldstein 	err = ovl_cleanup_and_whiteout(workdir, d_inode(upperdir), upper);
651e9be9d5eSMiklos Szeredi 	if (err)
652e7dd0e71SAmir Goldstein 		goto out_d_drop;
653cfc9fde0SMaxim Patlasov 
6544edb83bbSMiklos Szeredi 	ovl_dentry_version_inc(dentry->d_parent, true);
655e9be9d5eSMiklos Szeredi out_d_drop:
656e9be9d5eSMiklos Szeredi 	d_drop(dentry);
657cfc9fde0SMaxim Patlasov out_dput_upper:
658cfc9fde0SMaxim Patlasov 	dput(upper);
659e9be9d5eSMiklos Szeredi out_unlock:
660e9be9d5eSMiklos Szeredi 	unlock_rename(workdir, upperdir);
661e9be9d5eSMiklos Szeredi out_dput:
662e9be9d5eSMiklos Szeredi 	dput(opaquedir);
663e9be9d5eSMiklos Szeredi out:
664e9be9d5eSMiklos Szeredi 	return err;
665e9be9d5eSMiklos Szeredi }
666e9be9d5eSMiklos Szeredi 
6676d0a8a90SAmir Goldstein static int ovl_remove_upper(struct dentry *dentry, bool is_dir,
6686d0a8a90SAmir Goldstein 			    struct list_head *list)
669e9be9d5eSMiklos Szeredi {
670e9be9d5eSMiklos Szeredi 	struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
671e9be9d5eSMiklos Szeredi 	struct inode *dir = upperdir->d_inode;
67211f37104SMiklos Szeredi 	struct dentry *upper;
673d1595119SAmir Goldstein 	struct dentry *opaquedir = NULL;
674e9be9d5eSMiklos Szeredi 	int err;
675e9be9d5eSMiklos Szeredi 
6766d0a8a90SAmir Goldstein 	if (!list_empty(list)) {
6776d0a8a90SAmir Goldstein 		opaquedir = ovl_clear_empty(dentry, list);
678d1595119SAmir Goldstein 		err = PTR_ERR(opaquedir);
679d1595119SAmir Goldstein 		if (IS_ERR(opaquedir))
680d1595119SAmir Goldstein 			goto out;
681d1595119SAmir Goldstein 	}
682d1595119SAmir Goldstein 
6835955102cSAl Viro 	inode_lock_nested(dir, I_MUTEX_PARENT);
68411f37104SMiklos Szeredi 	upper = lookup_one_len(dentry->d_name.name, upperdir,
68511f37104SMiklos Szeredi 			       dentry->d_name.len);
68611f37104SMiklos Szeredi 	err = PTR_ERR(upper);
68711f37104SMiklos Szeredi 	if (IS_ERR(upper))
68811f37104SMiklos Szeredi 		goto out_unlock;
68911f37104SMiklos Szeredi 
690e9be9d5eSMiklos Szeredi 	err = -ESTALE;
691d1595119SAmir Goldstein 	if ((opaquedir && upper != opaquedir) ||
6929020df37SMiklos Szeredi 	    (!opaquedir && !ovl_matches_upper(dentry, upper)))
693d1595119SAmir Goldstein 		goto out_dput_upper;
694d1595119SAmir Goldstein 
695e9be9d5eSMiklos Szeredi 	if (is_dir)
696e9be9d5eSMiklos Szeredi 		err = vfs_rmdir(dir, upper);
697e9be9d5eSMiklos Szeredi 	else
698e9be9d5eSMiklos Szeredi 		err = vfs_unlink(dir, upper, NULL);
6994edb83bbSMiklos Szeredi 	ovl_dentry_version_inc(dentry->d_parent, ovl_type_origin(dentry));
700e9be9d5eSMiklos Szeredi 
701e9be9d5eSMiklos Szeredi 	/*
702e9be9d5eSMiklos Szeredi 	 * Keeping this dentry hashed would mean having to release
703e9be9d5eSMiklos Szeredi 	 * upperpath/lowerpath, which could only be done if we are the
704e9be9d5eSMiklos Szeredi 	 * sole user of this dentry.  Too tricky...  Just unhash for
705e9be9d5eSMiklos Szeredi 	 * now.
706e9be9d5eSMiklos Szeredi 	 */
707ce9113bbSRui Wang 	if (!err)
708e9be9d5eSMiklos Szeredi 		d_drop(dentry);
709d1595119SAmir Goldstein out_dput_upper:
710d1595119SAmir Goldstein 	dput(upper);
71111f37104SMiklos Szeredi out_unlock:
7125955102cSAl Viro 	inode_unlock(dir);
713d1595119SAmir Goldstein 	dput(opaquedir);
714d1595119SAmir Goldstein out:
715e9be9d5eSMiklos Szeredi 	return err;
716e9be9d5eSMiklos Szeredi }
717e9be9d5eSMiklos Szeredi 
7186d0a8a90SAmir Goldstein static bool ovl_pure_upper(struct dentry *dentry)
7196d0a8a90SAmir Goldstein {
7206d0a8a90SAmir Goldstein 	return !ovl_dentry_lower(dentry) &&
7216d0a8a90SAmir Goldstein 	       !ovl_test_flag(OVL_WHITEOUTS, d_inode(dentry));
7226d0a8a90SAmir Goldstein }
7236d0a8a90SAmir Goldstein 
724e9be9d5eSMiklos Szeredi static int ovl_do_remove(struct dentry *dentry, bool is_dir)
725e9be9d5eSMiklos Szeredi {
726e9be9d5eSMiklos Szeredi 	int err;
7275f8415d6SAmir Goldstein 	bool locked = false;
7281175b6b8SVivek Goyal 	const struct cred *old_cred;
7296d0a8a90SAmir Goldstein 	bool lower_positive = ovl_lower_positive(dentry);
7306d0a8a90SAmir Goldstein 	LIST_HEAD(list);
7316d0a8a90SAmir Goldstein 
7326d0a8a90SAmir Goldstein 	/* No need to clean pure upper removed by vfs_rmdir() */
7336d0a8a90SAmir Goldstein 	if (is_dir && (lower_positive || !ovl_pure_upper(dentry))) {
7346d0a8a90SAmir Goldstein 		err = ovl_check_empty_dir(dentry, &list);
7356d0a8a90SAmir Goldstein 		if (err)
7366d0a8a90SAmir Goldstein 			goto out;
7376d0a8a90SAmir Goldstein 	}
7381175b6b8SVivek Goyal 
739e9be9d5eSMiklos Szeredi 	err = ovl_want_write(dentry);
740e9be9d5eSMiklos Szeredi 	if (err)
741e9be9d5eSMiklos Szeredi 		goto out;
742e9be9d5eSMiklos Szeredi 
743e9be9d5eSMiklos Szeredi 	err = ovl_copy_up(dentry->d_parent);
744e9be9d5eSMiklos Szeredi 	if (err)
745e9be9d5eSMiklos Szeredi 		goto out_drop_write;
746e9be9d5eSMiklos Szeredi 
7475f8415d6SAmir Goldstein 	err = ovl_nlink_start(dentry, &locked);
7485f8415d6SAmir Goldstein 	if (err)
7495f8415d6SAmir Goldstein 		goto out_drop_write;
7501175b6b8SVivek Goyal 
7511175b6b8SVivek Goyal 	old_cred = ovl_override_creds(dentry->d_sb);
7526d0a8a90SAmir Goldstein 	if (!lower_positive)
7536d0a8a90SAmir Goldstein 		err = ovl_remove_upper(dentry, is_dir, &list);
7541175b6b8SVivek Goyal 	else
7556d0a8a90SAmir Goldstein 		err = ovl_remove_and_whiteout(dentry, &list);
756e9be9d5eSMiklos Szeredi 	revert_creds(old_cred);
757dbc816d0SMiklos Szeredi 	if (!err) {
758dbc816d0SMiklos Szeredi 		if (is_dir)
759dbc816d0SMiklos Szeredi 			clear_nlink(dentry->d_inode);
760dbc816d0SMiklos Szeredi 		else
76151f7e52dSMiklos Szeredi 			drop_nlink(dentry->d_inode);
762dbc816d0SMiklos Szeredi 	}
7635f8415d6SAmir Goldstein 	ovl_nlink_end(dentry, locked);
764e9be9d5eSMiklos Szeredi out_drop_write:
765e9be9d5eSMiklos Szeredi 	ovl_drop_write(dentry);
766e9be9d5eSMiklos Szeredi out:
7676d0a8a90SAmir Goldstein 	ovl_cache_free(&list);
768e9be9d5eSMiklos Szeredi 	return err;
769e9be9d5eSMiklos Szeredi }
770e9be9d5eSMiklos Szeredi 
771e9be9d5eSMiklos Szeredi static int ovl_unlink(struct inode *dir, struct dentry *dentry)
772e9be9d5eSMiklos Szeredi {
773e9be9d5eSMiklos Szeredi 	return ovl_do_remove(dentry, false);
774e9be9d5eSMiklos Szeredi }
775e9be9d5eSMiklos Szeredi 
776e9be9d5eSMiklos Szeredi static int ovl_rmdir(struct inode *dir, struct dentry *dentry)
777e9be9d5eSMiklos Szeredi {
778e9be9d5eSMiklos Szeredi 	return ovl_do_remove(dentry, true);
779e9be9d5eSMiklos Szeredi }
780e9be9d5eSMiklos Szeredi 
781370e55acSMiklos Szeredi static bool ovl_type_merge_or_lower(struct dentry *dentry)
782370e55acSMiklos Szeredi {
783370e55acSMiklos Szeredi 	enum ovl_path_type type = ovl_path_type(dentry);
784370e55acSMiklos Szeredi 
785370e55acSMiklos Szeredi 	return OVL_TYPE_MERGE(type) || !OVL_TYPE_UPPER(type);
786370e55acSMiklos Szeredi }
787370e55acSMiklos Szeredi 
788a6c60655SMiklos Szeredi static bool ovl_can_move(struct dentry *dentry)
789a6c60655SMiklos Szeredi {
790a6c60655SMiklos Szeredi 	return ovl_redirect_dir(dentry->d_sb) ||
791a6c60655SMiklos Szeredi 		!d_is_dir(dentry) || !ovl_type_merge_or_lower(dentry);
792a6c60655SMiklos Szeredi }
793a6c60655SMiklos Szeredi 
794a6c60655SMiklos Szeredi static char *ovl_get_redirect(struct dentry *dentry, bool samedir)
795a6c60655SMiklos Szeredi {
796a6c60655SMiklos Szeredi 	char *buf, *ret;
797a6c60655SMiklos Szeredi 	struct dentry *d, *tmp;
7983ea22a71SMiklos Szeredi 	int buflen = ovl_redirect_max + 1;
799a6c60655SMiklos Szeredi 
800a6c60655SMiklos Szeredi 	if (samedir) {
801a6c60655SMiklos Szeredi 		ret = kstrndup(dentry->d_name.name, dentry->d_name.len,
802a6c60655SMiklos Szeredi 			       GFP_KERNEL);
803a6c60655SMiklos Szeredi 		goto out;
804a6c60655SMiklos Szeredi 	}
805a6c60655SMiklos Szeredi 
8060ee931c4SMichal Hocko 	buf = ret = kmalloc(buflen, GFP_KERNEL);
807a6c60655SMiklos Szeredi 	if (!buf)
808a6c60655SMiklos Szeredi 		goto out;
809a6c60655SMiklos Szeredi 
810a6c60655SMiklos Szeredi 	buflen--;
811a6c60655SMiklos Szeredi 	buf[buflen] = '\0';
812a6c60655SMiklos Szeredi 	for (d = dget(dentry); !IS_ROOT(d);) {
813a6c60655SMiklos Szeredi 		const char *name;
814a6c60655SMiklos Szeredi 		int thislen;
815a6c60655SMiklos Szeredi 
816a6c60655SMiklos Szeredi 		spin_lock(&d->d_lock);
817a6c60655SMiklos Szeredi 		name = ovl_dentry_get_redirect(d);
818a6c60655SMiklos Szeredi 		if (name) {
819a6c60655SMiklos Szeredi 			thislen = strlen(name);
820a6c60655SMiklos Szeredi 		} else {
821a6c60655SMiklos Szeredi 			name = d->d_name.name;
822a6c60655SMiklos Szeredi 			thislen = d->d_name.len;
823a6c60655SMiklos Szeredi 		}
824a6c60655SMiklos Szeredi 
825a6c60655SMiklos Szeredi 		/* If path is too long, fall back to userspace move */
826a6c60655SMiklos Szeredi 		if (thislen + (name[0] != '/') > buflen) {
827a6c60655SMiklos Szeredi 			ret = ERR_PTR(-EXDEV);
828a6c60655SMiklos Szeredi 			spin_unlock(&d->d_lock);
829a6c60655SMiklos Szeredi 			goto out_put;
830a6c60655SMiklos Szeredi 		}
831a6c60655SMiklos Szeredi 
832a6c60655SMiklos Szeredi 		buflen -= thislen;
833a6c60655SMiklos Szeredi 		memcpy(&buf[buflen], name, thislen);
834a6c60655SMiklos Szeredi 		tmp = dget_dlock(d->d_parent);
835a6c60655SMiklos Szeredi 		spin_unlock(&d->d_lock);
836a6c60655SMiklos Szeredi 
837a6c60655SMiklos Szeredi 		dput(d);
838a6c60655SMiklos Szeredi 		d = tmp;
839a6c60655SMiklos Szeredi 
840a6c60655SMiklos Szeredi 		/* Absolute redirect: finished */
841a6c60655SMiklos Szeredi 		if (buf[buflen] == '/')
842a6c60655SMiklos Szeredi 			break;
843a6c60655SMiklos Szeredi 		buflen--;
844a6c60655SMiklos Szeredi 		buf[buflen] = '/';
845a6c60655SMiklos Szeredi 	}
846a6c60655SMiklos Szeredi 	ret = kstrdup(&buf[buflen], GFP_KERNEL);
847a6c60655SMiklos Szeredi out_put:
848a6c60655SMiklos Szeredi 	dput(d);
849a6c60655SMiklos Szeredi 	kfree(buf);
850a6c60655SMiklos Szeredi out:
851a6c60655SMiklos Szeredi 	return ret ? ret : ERR_PTR(-ENOMEM);
852a6c60655SMiklos Szeredi }
853a6c60655SMiklos Szeredi 
854a6c60655SMiklos Szeredi static int ovl_set_redirect(struct dentry *dentry, bool samedir)
855a6c60655SMiklos Szeredi {
856a6c60655SMiklos Szeredi 	int err;
857a6c60655SMiklos Szeredi 	const char *redirect = ovl_dentry_get_redirect(dentry);
858a6c60655SMiklos Szeredi 
859a6c60655SMiklos Szeredi 	if (redirect && (samedir || redirect[0] == '/'))
860a6c60655SMiklos Szeredi 		return 0;
861a6c60655SMiklos Szeredi 
862a6c60655SMiklos Szeredi 	redirect = ovl_get_redirect(dentry, samedir);
863a6c60655SMiklos Szeredi 	if (IS_ERR(redirect))
864a6c60655SMiklos Szeredi 		return PTR_ERR(redirect);
865a6c60655SMiklos Szeredi 
86621a22878SAmir Goldstein 	err = ovl_check_setxattr(dentry, ovl_dentry_upper(dentry),
86721a22878SAmir Goldstein 				 OVL_XATTR_REDIRECT,
86821a22878SAmir Goldstein 				 redirect, strlen(redirect), -EXDEV);
869a6c60655SMiklos Szeredi 	if (!err) {
870a6c60655SMiklos Szeredi 		spin_lock(&dentry->d_lock);
871a6c60655SMiklos Szeredi 		ovl_dentry_set_redirect(dentry, redirect);
872a6c60655SMiklos Szeredi 		spin_unlock(&dentry->d_lock);
873a6c60655SMiklos Szeredi 	} else {
874a6c60655SMiklos Szeredi 		kfree(redirect);
875da2e6b7eSAmir Goldstein 		pr_warn_ratelimited("overlayfs: failed to set redirect (%i)\n",
876da2e6b7eSAmir Goldstein 				    err);
877a6c60655SMiklos Szeredi 		/* Fall back to userspace copy-up */
878a6c60655SMiklos Szeredi 		err = -EXDEV;
879a6c60655SMiklos Szeredi 	}
880a6c60655SMiklos Szeredi 	return err;
881a6c60655SMiklos Szeredi }
882a6c60655SMiklos Szeredi 
8836c02cb59SMiklos Szeredi static int ovl_rename(struct inode *olddir, struct dentry *old,
884e9be9d5eSMiklos Szeredi 		      struct inode *newdir, struct dentry *new,
885e9be9d5eSMiklos Szeredi 		      unsigned int flags)
886e9be9d5eSMiklos Szeredi {
887e9be9d5eSMiklos Szeredi 	int err;
8885f8415d6SAmir Goldstein 	bool locked = false;
889e9be9d5eSMiklos Szeredi 	struct dentry *old_upperdir;
890e9be9d5eSMiklos Szeredi 	struct dentry *new_upperdir;
891e9be9d5eSMiklos Szeredi 	struct dentry *olddentry;
892e9be9d5eSMiklos Szeredi 	struct dentry *newdentry;
893e9be9d5eSMiklos Szeredi 	struct dentry *trap;
894e9be9d5eSMiklos Szeredi 	bool old_opaque;
895e9be9d5eSMiklos Szeredi 	bool new_opaque;
896e9be9d5eSMiklos Szeredi 	bool cleanup_whiteout = false;
897e9be9d5eSMiklos Szeredi 	bool overwrite = !(flags & RENAME_EXCHANGE);
898e36cb0b8SDavid Howells 	bool is_dir = d_is_dir(old);
899370e55acSMiklos Szeredi 	bool new_is_dir = d_is_dir(new);
900a6c60655SMiklos Szeredi 	bool samedir = olddir == newdir;
901e9be9d5eSMiklos Szeredi 	struct dentry *opaquedir = NULL;
902e9be9d5eSMiklos Szeredi 	const struct cred *old_cred = NULL;
9036d0a8a90SAmir Goldstein 	LIST_HEAD(list);
904e9be9d5eSMiklos Szeredi 
905e9be9d5eSMiklos Szeredi 	err = -EINVAL;
906e9be9d5eSMiklos Szeredi 	if (flags & ~(RENAME_EXCHANGE | RENAME_NOREPLACE))
907e9be9d5eSMiklos Szeredi 		goto out;
908e9be9d5eSMiklos Szeredi 
909e9be9d5eSMiklos Szeredi 	flags &= ~RENAME_NOREPLACE;
910e9be9d5eSMiklos Szeredi 
911e9be9d5eSMiklos Szeredi 	/* Don't copy up directory trees */
912e9be9d5eSMiklos Szeredi 	err = -EXDEV;
913a6c60655SMiklos Szeredi 	if (!ovl_can_move(old))
914e9be9d5eSMiklos Szeredi 		goto out;
915a6c60655SMiklos Szeredi 	if (!overwrite && !ovl_can_move(new))
916e9be9d5eSMiklos Szeredi 		goto out;
917e9be9d5eSMiklos Szeredi 
9186d0a8a90SAmir Goldstein 	if (overwrite && new_is_dir && !ovl_pure_upper(new)) {
9196d0a8a90SAmir Goldstein 		err = ovl_check_empty_dir(new, &list);
9206d0a8a90SAmir Goldstein 		if (err)
9216d0a8a90SAmir Goldstein 			goto out;
9226d0a8a90SAmir Goldstein 	}
9236d0a8a90SAmir Goldstein 
9246d0a8a90SAmir Goldstein 	if (overwrite) {
9256d0a8a90SAmir Goldstein 		if (ovl_lower_positive(old)) {
9266d0a8a90SAmir Goldstein 			if (!ovl_dentry_is_whiteout(new)) {
9276d0a8a90SAmir Goldstein 				/* Whiteout source */
9286d0a8a90SAmir Goldstein 				flags |= RENAME_WHITEOUT;
9296d0a8a90SAmir Goldstein 			} else {
9306d0a8a90SAmir Goldstein 				/* Switch whiteouts */
9316d0a8a90SAmir Goldstein 				flags |= RENAME_EXCHANGE;
9326d0a8a90SAmir Goldstein 			}
9336d0a8a90SAmir Goldstein 		} else if (is_dir && ovl_dentry_is_whiteout(new)) {
9346d0a8a90SAmir Goldstein 			flags |= RENAME_EXCHANGE;
9356d0a8a90SAmir Goldstein 			cleanup_whiteout = true;
9366d0a8a90SAmir Goldstein 		}
9376d0a8a90SAmir Goldstein 	}
9386d0a8a90SAmir Goldstein 
939e9be9d5eSMiklos Szeredi 	err = ovl_want_write(old);
940e9be9d5eSMiklos Szeredi 	if (err)
941e9be9d5eSMiklos Szeredi 		goto out;
942e9be9d5eSMiklos Szeredi 
943e9be9d5eSMiklos Szeredi 	err = ovl_copy_up(old);
944e9be9d5eSMiklos Szeredi 	if (err)
945e9be9d5eSMiklos Szeredi 		goto out_drop_write;
946e9be9d5eSMiklos Szeredi 
947e9be9d5eSMiklos Szeredi 	err = ovl_copy_up(new->d_parent);
948e9be9d5eSMiklos Szeredi 	if (err)
949e9be9d5eSMiklos Szeredi 		goto out_drop_write;
950e9be9d5eSMiklos Szeredi 	if (!overwrite) {
951e9be9d5eSMiklos Szeredi 		err = ovl_copy_up(new);
952e9be9d5eSMiklos Szeredi 		if (err)
953e9be9d5eSMiklos Szeredi 			goto out_drop_write;
9545f8415d6SAmir Goldstein 	} else {
9555f8415d6SAmir Goldstein 		err = ovl_nlink_start(new, &locked);
9565f8415d6SAmir Goldstein 		if (err)
9575f8415d6SAmir Goldstein 			goto out_drop_write;
958e9be9d5eSMiklos Szeredi 	}
959e9be9d5eSMiklos Szeredi 
9603fe6e52fSAntonio Murdaca 	old_cred = ovl_override_creds(old->d_sb);
961e9be9d5eSMiklos Szeredi 
9626d0a8a90SAmir Goldstein 	if (!list_empty(&list)) {
9636d0a8a90SAmir Goldstein 		opaquedir = ovl_clear_empty(new, &list);
964e9be9d5eSMiklos Szeredi 		err = PTR_ERR(opaquedir);
965e9be9d5eSMiklos Szeredi 		if (IS_ERR(opaquedir)) {
966e9be9d5eSMiklos Szeredi 			opaquedir = NULL;
967e9be9d5eSMiklos Szeredi 			goto out_revert_creds;
968e9be9d5eSMiklos Szeredi 		}
969e9be9d5eSMiklos Szeredi 	}
970e9be9d5eSMiklos Szeredi 
971e9be9d5eSMiklos Szeredi 	old_upperdir = ovl_dentry_upper(old->d_parent);
972e9be9d5eSMiklos Szeredi 	new_upperdir = ovl_dentry_upper(new->d_parent);
973e9be9d5eSMiklos Szeredi 
974ee1d6d37SAmir Goldstein 	if (!samedir) {
975ee1d6d37SAmir Goldstein 		/*
976ee1d6d37SAmir Goldstein 		 * When moving a merge dir or non-dir with copy up origin into
977f3a15685SAmir Goldstein 		 * a new parent, we are marking the new parent dir "impure".
978f3a15685SAmir Goldstein 		 * When ovl_iterate() iterates an "impure" upper dir, it will
979f3a15685SAmir Goldstein 		 * lookup the origin inodes of the entries to fill d_ino.
980ee1d6d37SAmir Goldstein 		 */
981f3a15685SAmir Goldstein 		if (ovl_type_origin(old)) {
982ee1d6d37SAmir Goldstein 			err = ovl_set_impure(new->d_parent, new_upperdir);
983ee1d6d37SAmir Goldstein 			if (err)
984ee1d6d37SAmir Goldstein 				goto out_revert_creds;
985ee1d6d37SAmir Goldstein 		}
986f3a15685SAmir Goldstein 		if (!overwrite && ovl_type_origin(new)) {
987ee1d6d37SAmir Goldstein 			err = ovl_set_impure(old->d_parent, old_upperdir);
988ee1d6d37SAmir Goldstein 			if (err)
989ee1d6d37SAmir Goldstein 				goto out_revert_creds;
990ee1d6d37SAmir Goldstein 		}
991ee1d6d37SAmir Goldstein 	}
992ee1d6d37SAmir Goldstein 
993e9be9d5eSMiklos Szeredi 	trap = lock_rename(new_upperdir, old_upperdir);
994e9be9d5eSMiklos Szeredi 
99511f37104SMiklos Szeredi 	olddentry = lookup_one_len(old->d_name.name, old_upperdir,
99611f37104SMiklos Szeredi 				   old->d_name.len);
99711f37104SMiklos Szeredi 	err = PTR_ERR(olddentry);
99811f37104SMiklos Szeredi 	if (IS_ERR(olddentry))
99911f37104SMiklos Szeredi 		goto out_unlock;
100011f37104SMiklos Szeredi 
100111f37104SMiklos Szeredi 	err = -ESTALE;
10029020df37SMiklos Szeredi 	if (!ovl_matches_upper(old, olddentry))
100311f37104SMiklos Szeredi 		goto out_dput_old;
100411f37104SMiklos Szeredi 
1005e9be9d5eSMiklos Szeredi 	newdentry = lookup_one_len(new->d_name.name, new_upperdir,
1006e9be9d5eSMiklos Szeredi 				   new->d_name.len);
1007e9be9d5eSMiklos Szeredi 	err = PTR_ERR(newdentry);
1008e9be9d5eSMiklos Szeredi 	if (IS_ERR(newdentry))
100911f37104SMiklos Szeredi 		goto out_dput_old;
1010e9be9d5eSMiklos Szeredi 
10113ee23ff1SMiklos Szeredi 	old_opaque = ovl_dentry_is_opaque(old);
10123ee23ff1SMiklos Szeredi 	new_opaque = ovl_dentry_is_opaque(new);
10133ee23ff1SMiklos Szeredi 
1014e9be9d5eSMiklos Szeredi 	err = -ESTALE;
101509d8b586SMiklos Szeredi 	if (d_inode(new) && ovl_dentry_upper(new)) {
101611f37104SMiklos Szeredi 		if (opaquedir) {
101711f37104SMiklos Szeredi 			if (newdentry != opaquedir)
1018e9be9d5eSMiklos Szeredi 				goto out_dput;
101911f37104SMiklos Szeredi 		} else {
10209020df37SMiklos Szeredi 			if (!ovl_matches_upper(new, newdentry))
1021e9be9d5eSMiklos Szeredi 				goto out_dput;
102211f37104SMiklos Szeredi 		}
102311f37104SMiklos Szeredi 	} else {
102411f37104SMiklos Szeredi 		if (!d_is_negative(newdentry) &&
102511f37104SMiklos Szeredi 		    (!new_opaque || !ovl_is_whiteout(newdentry)))
102611f37104SMiklos Szeredi 			goto out_dput;
102711f37104SMiklos Szeredi 	}
102811f37104SMiklos Szeredi 
1029e9be9d5eSMiklos Szeredi 	if (olddentry == trap)
1030e9be9d5eSMiklos Szeredi 		goto out_dput;
1031e9be9d5eSMiklos Szeredi 	if (newdentry == trap)
1032e9be9d5eSMiklos Szeredi 		goto out_dput;
1033e9be9d5eSMiklos Szeredi 
1034804032faSMiklos Szeredi 	if (WARN_ON(olddentry->d_inode == newdentry->d_inode))
1035804032faSMiklos Szeredi 		goto out_dput;
1036804032faSMiklos Szeredi 
10375cf5b477SMiklos Szeredi 	err = 0;
1038a6c60655SMiklos Szeredi 	if (is_dir) {
10395cf5b477SMiklos Szeredi 		if (ovl_type_merge_or_lower(old))
1040a6c60655SMiklos Szeredi 			err = ovl_set_redirect(old, samedir);
104197c684ccSAmir Goldstein 		else if (!old_opaque && ovl_type_merge(new->d_parent))
104221a22878SAmir Goldstein 			err = ovl_set_opaque_xerr(old, olddentry, -EXDEV);
1043a6c60655SMiklos Szeredi 		if (err)
1044a6c60655SMiklos Szeredi 			goto out_dput;
1045a6c60655SMiklos Szeredi 	}
1046a6c60655SMiklos Szeredi 	if (!overwrite && new_is_dir) {
10475cf5b477SMiklos Szeredi 		if (ovl_type_merge_or_lower(new))
1048a6c60655SMiklos Szeredi 			err = ovl_set_redirect(new, samedir);
104997c684ccSAmir Goldstein 		else if (!new_opaque && ovl_type_merge(old->d_parent))
105021a22878SAmir Goldstein 			err = ovl_set_opaque_xerr(new, newdentry, -EXDEV);
1051a6c60655SMiklos Szeredi 		if (err)
1052a6c60655SMiklos Szeredi 			goto out_dput;
1053a6c60655SMiklos Szeredi 	}
1054e9be9d5eSMiklos Szeredi 
1055e9be9d5eSMiklos Szeredi 	err = ovl_do_rename(old_upperdir->d_inode, olddentry,
10563ee23ff1SMiklos Szeredi 			    new_upperdir->d_inode, newdentry, flags);
10573ee23ff1SMiklos Szeredi 	if (err)
1058e9be9d5eSMiklos Szeredi 		goto out_dput;
1059e9be9d5eSMiklos Szeredi 
1060e9be9d5eSMiklos Szeredi 	if (cleanup_whiteout)
1061e9be9d5eSMiklos Szeredi 		ovl_cleanup(old_upperdir->d_inode, newdentry);
1062e9be9d5eSMiklos Szeredi 
1063f681eb1dSAmir Goldstein 	if (overwrite && d_inode(new)) {
1064f681eb1dSAmir Goldstein 		if (new_is_dir)
1065f681eb1dSAmir Goldstein 			clear_nlink(d_inode(new));
1066f681eb1dSAmir Goldstein 		else
1067f681eb1dSAmir Goldstein 			drop_nlink(d_inode(new));
1068f681eb1dSAmir Goldstein 	}
1069f681eb1dSAmir Goldstein 
1070f30536f0SAmir Goldstein 	ovl_dentry_version_inc(old->d_parent, ovl_type_origin(old) ||
1071f30536f0SAmir Goldstein 			       (!overwrite && ovl_type_origin(new)));
1072f30536f0SAmir Goldstein 	ovl_dentry_version_inc(new->d_parent, ovl_type_origin(old) ||
1073f30536f0SAmir Goldstein 			       (d_inode(new) && ovl_type_origin(new)));
1074e9be9d5eSMiklos Szeredi 
1075e9be9d5eSMiklos Szeredi out_dput:
1076e9be9d5eSMiklos Szeredi 	dput(newdentry);
107711f37104SMiklos Szeredi out_dput_old:
107811f37104SMiklos Szeredi 	dput(olddentry);
1079e9be9d5eSMiklos Szeredi out_unlock:
1080e9be9d5eSMiklos Szeredi 	unlock_rename(new_upperdir, old_upperdir);
1081e9be9d5eSMiklos Szeredi out_revert_creds:
1082e9be9d5eSMiklos Szeredi 	revert_creds(old_cred);
10835f8415d6SAmir Goldstein 	ovl_nlink_end(new, locked);
1084e9be9d5eSMiklos Szeredi out_drop_write:
1085e9be9d5eSMiklos Szeredi 	ovl_drop_write(old);
1086e9be9d5eSMiklos Szeredi out:
1087e9be9d5eSMiklos Szeredi 	dput(opaquedir);
10886d0a8a90SAmir Goldstein 	ovl_cache_free(&list);
1089e9be9d5eSMiklos Szeredi 	return err;
1090e9be9d5eSMiklos Szeredi }
1091e9be9d5eSMiklos Szeredi 
1092e9be9d5eSMiklos Szeredi const struct inode_operations ovl_dir_inode_operations = {
1093e9be9d5eSMiklos Szeredi 	.lookup		= ovl_lookup,
1094e9be9d5eSMiklos Szeredi 	.mkdir		= ovl_mkdir,
1095e9be9d5eSMiklos Szeredi 	.symlink	= ovl_symlink,
1096e9be9d5eSMiklos Szeredi 	.unlink		= ovl_unlink,
1097e9be9d5eSMiklos Szeredi 	.rmdir		= ovl_rmdir,
10986c02cb59SMiklos Szeredi 	.rename		= ovl_rename,
1099e9be9d5eSMiklos Szeredi 	.link		= ovl_link,
1100e9be9d5eSMiklos Szeredi 	.setattr	= ovl_setattr,
1101e9be9d5eSMiklos Szeredi 	.create		= ovl_create,
1102e9be9d5eSMiklos Szeredi 	.mknod		= ovl_mknod,
1103e9be9d5eSMiklos Szeredi 	.permission	= ovl_permission,
11045b712091SMiklos Szeredi 	.getattr	= ovl_getattr,
1105e9be9d5eSMiklos Szeredi 	.listxattr	= ovl_listxattr,
110639a25b2bSVivek Goyal 	.get_acl	= ovl_get_acl,
1107d719e8f2SMiklos Szeredi 	.update_time	= ovl_update_time,
1108e9be9d5eSMiklos Szeredi };
1109