xref: /freebsd-src/sys/contrib/openzfs/module/os/linux/zfs/zpl_inode.c (revision 7a7741af18d6c8a804cc643cb7ecda9d730c6aa6)
1eda14cbcSMatt Macy /*
2eda14cbcSMatt Macy  * CDDL HEADER START
3eda14cbcSMatt Macy  *
4eda14cbcSMatt Macy  * The contents of this file are subject to the terms of the
5eda14cbcSMatt Macy  * Common Development and Distribution License (the "License").
6eda14cbcSMatt Macy  * You may not use this file except in compliance with the License.
7eda14cbcSMatt Macy  *
8eda14cbcSMatt Macy  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9271171e0SMartin Matuska  * or https://opensource.org/licenses/CDDL-1.0.
10eda14cbcSMatt Macy  * See the License for the specific language governing permissions
11eda14cbcSMatt Macy  * and limitations under the License.
12eda14cbcSMatt Macy  *
13eda14cbcSMatt Macy  * When distributing Covered Code, include this CDDL HEADER in each
14eda14cbcSMatt Macy  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15eda14cbcSMatt Macy  * If applicable, add the following below this CDDL HEADER, with the
16eda14cbcSMatt Macy  * fields enclosed by brackets "[]" replaced with your own identifying
17eda14cbcSMatt Macy  * information: Portions Copyright [yyyy] [name of copyright owner]
18eda14cbcSMatt Macy  *
19eda14cbcSMatt Macy  * CDDL HEADER END
20eda14cbcSMatt Macy  */
21eda14cbcSMatt Macy /*
22eda14cbcSMatt Macy  * Copyright (c) 2011, Lawrence Livermore National Security, LLC.
23eda14cbcSMatt Macy  * Copyright (c) 2015 by Chunwei Chen. All rights reserved.
24eda14cbcSMatt Macy  */
25eda14cbcSMatt Macy 
26eda14cbcSMatt Macy 
27dbd5678dSMartin Matuska #include <sys/sysmacros.h>
28eda14cbcSMatt Macy #include <sys/zfs_ctldir.h>
29eda14cbcSMatt Macy #include <sys/zfs_vfsops.h>
30eda14cbcSMatt Macy #include <sys/zfs_vnops.h>
31eda14cbcSMatt Macy #include <sys/zfs_znode.h>
32eda14cbcSMatt Macy #include <sys/dmu_objset.h>
33eda14cbcSMatt Macy #include <sys/vfs.h>
34eda14cbcSMatt Macy #include <sys/zpl.h>
35eda14cbcSMatt Macy #include <sys/file.h>
36eda14cbcSMatt Macy 
37eda14cbcSMatt Macy static struct dentry *
38eda14cbcSMatt Macy zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
39eda14cbcSMatt Macy {
40eda14cbcSMatt Macy 	cred_t *cr = CRED();
41eda14cbcSMatt Macy 	struct inode *ip;
42eda14cbcSMatt Macy 	znode_t *zp;
43eda14cbcSMatt Macy 	int error;
44eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
45eda14cbcSMatt Macy 	pathname_t *ppn = NULL;
46eda14cbcSMatt Macy 	pathname_t pn;
47eda14cbcSMatt Macy 	int zfs_flags = 0;
48eda14cbcSMatt Macy 	zfsvfs_t *zfsvfs = dentry->d_sb->s_fs_info;
49*7a7741afSMartin Matuska 	dsl_dataset_t *ds = dmu_objset_ds(zfsvfs->z_os);
50*7a7741afSMartin Matuska 	size_t dlen = dlen(dentry);
51eda14cbcSMatt Macy 
52*7a7741afSMartin Matuska 	/*
53*7a7741afSMartin Matuska 	 * If z_longname is disabled, disallow create or rename of names
54*7a7741afSMartin Matuska 	 * longer than ZAP_MAXNAMELEN.
55*7a7741afSMartin Matuska 	 *
56*7a7741afSMartin Matuska 	 * This is needed in cases where longname was enabled first and some
57*7a7741afSMartin Matuska 	 * files/dirs with names > ZAP_MAXNAMELEN were created. And later
58*7a7741afSMartin Matuska 	 * longname was disabled. In such a case allow access to existing
59*7a7741afSMartin Matuska 	 * longnames. But disallow creation newer longnamed entities.
60*7a7741afSMartin Matuska 	 */
61*7a7741afSMartin Matuska 	if (!zfsvfs->z_longname && (dlen >= ZAP_MAXNAMELEN)) {
62*7a7741afSMartin Matuska 		/*
63*7a7741afSMartin Matuska 		 * If this is for create or rename fail it.
64*7a7741afSMartin Matuska 		 */
65*7a7741afSMartin Matuska 		if (!dsl_dataset_feature_is_active(ds, SPA_FEATURE_LONGNAME) ||
66*7a7741afSMartin Matuska 		    (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)))
67eda14cbcSMatt Macy 			return (ERR_PTR(-ENAMETOOLONG));
68*7a7741afSMartin Matuska 	}
69*7a7741afSMartin Matuska 	if (dlen >= ZAP_MAXNAMELEN_NEW) {
70*7a7741afSMartin Matuska 		return (ERR_PTR(-ENAMETOOLONG));
71*7a7741afSMartin Matuska 	}
72eda14cbcSMatt Macy 
73eda14cbcSMatt Macy 	crhold(cr);
74eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
75eda14cbcSMatt Macy 
76eda14cbcSMatt Macy 	/* If we are a case insensitive fs, we need the real name */
77eda14cbcSMatt Macy 	if (zfsvfs->z_case == ZFS_CASE_INSENSITIVE) {
78eda14cbcSMatt Macy 		zfs_flags = FIGNORECASE;
79eda14cbcSMatt Macy 		pn_alloc(&pn);
80eda14cbcSMatt Macy 		ppn = &pn;
81eda14cbcSMatt Macy 	}
82eda14cbcSMatt Macy 
83eda14cbcSMatt Macy 	error = -zfs_lookup(ITOZ(dir), dname(dentry), &zp,
84eda14cbcSMatt Macy 	    zfs_flags, cr, NULL, ppn);
85eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
86eda14cbcSMatt Macy 	ASSERT3S(error, <=, 0);
87eda14cbcSMatt Macy 	crfree(cr);
88eda14cbcSMatt Macy 
89eda14cbcSMatt Macy 	spin_lock(&dentry->d_lock);
90eda14cbcSMatt Macy 	dentry->d_time = jiffies;
91eda14cbcSMatt Macy 	spin_unlock(&dentry->d_lock);
92eda14cbcSMatt Macy 
93eda14cbcSMatt Macy 	if (error) {
94eda14cbcSMatt Macy 		/*
95eda14cbcSMatt Macy 		 * If we have a case sensitive fs, we do not want to
96eda14cbcSMatt Macy 		 * insert negative entries, so return NULL for ENOENT.
97eda14cbcSMatt Macy 		 * Fall through if the error is not ENOENT. Also free memory.
98eda14cbcSMatt Macy 		 */
99eda14cbcSMatt Macy 		if (ppn) {
100eda14cbcSMatt Macy 			pn_free(ppn);
101eda14cbcSMatt Macy 			if (error == -ENOENT)
102eda14cbcSMatt Macy 				return (NULL);
103eda14cbcSMatt Macy 		}
104eda14cbcSMatt Macy 
105eda14cbcSMatt Macy 		if (error == -ENOENT)
106eda14cbcSMatt Macy 			return (d_splice_alias(NULL, dentry));
107eda14cbcSMatt Macy 		else
108eda14cbcSMatt Macy 			return (ERR_PTR(error));
109eda14cbcSMatt Macy 	}
110eda14cbcSMatt Macy 	ip = ZTOI(zp);
111eda14cbcSMatt Macy 
112eda14cbcSMatt Macy 	/*
113eda14cbcSMatt Macy 	 * If we are case insensitive, call the correct function
114eda14cbcSMatt Macy 	 * to install the name.
115eda14cbcSMatt Macy 	 */
116eda14cbcSMatt Macy 	if (ppn) {
117eda14cbcSMatt Macy 		struct dentry *new_dentry;
118eda14cbcSMatt Macy 		struct qstr ci_name;
119eda14cbcSMatt Macy 
120eda14cbcSMatt Macy 		if (strcmp(dname(dentry), pn.pn_buf) == 0) {
121eda14cbcSMatt Macy 			new_dentry = d_splice_alias(ip,  dentry);
122eda14cbcSMatt Macy 		} else {
123eda14cbcSMatt Macy 			ci_name.name = pn.pn_buf;
124eda14cbcSMatt Macy 			ci_name.len = strlen(pn.pn_buf);
125eda14cbcSMatt Macy 			new_dentry = d_add_ci(dentry, ip, &ci_name);
126eda14cbcSMatt Macy 		}
127eda14cbcSMatt Macy 		pn_free(ppn);
128eda14cbcSMatt Macy 		return (new_dentry);
129eda14cbcSMatt Macy 	} else {
130eda14cbcSMatt Macy 		return (d_splice_alias(ip, dentry));
131eda14cbcSMatt Macy 	}
132eda14cbcSMatt Macy }
133eda14cbcSMatt Macy 
134eda14cbcSMatt Macy void
135dbd5678dSMartin Matuska zpl_vap_init(vattr_t *vap, struct inode *dir, umode_t mode, cred_t *cr,
136d411c1d6SMartin Matuska     zidmap_t *mnt_ns)
137eda14cbcSMatt Macy {
138eda14cbcSMatt Macy 	vap->va_mask = ATTR_MODE;
139eda14cbcSMatt Macy 	vap->va_mode = mode;
140eda14cbcSMatt Macy 
141d411c1d6SMartin Matuska 	vap->va_uid = zfs_vfsuid_to_uid(mnt_ns,
142dbd5678dSMartin Matuska 	    zfs_i_user_ns(dir), crgetuid(cr));
143dbd5678dSMartin Matuska 
144dbd5678dSMartin Matuska 	if (dir->i_mode & S_ISGID) {
145eda14cbcSMatt Macy 		vap->va_gid = KGID_TO_SGID(dir->i_gid);
146eda14cbcSMatt Macy 		if (S_ISDIR(mode))
147eda14cbcSMatt Macy 			vap->va_mode |= S_ISGID;
148eda14cbcSMatt Macy 	} else {
149d411c1d6SMartin Matuska 		vap->va_gid = zfs_vfsgid_to_gid(mnt_ns,
150dbd5678dSMartin Matuska 		    zfs_i_user_ns(dir), crgetgid(cr));
151eda14cbcSMatt Macy 	}
152eda14cbcSMatt Macy }
153eda14cbcSMatt Macy 
154*7a7741afSMartin Matuska static inline bool
155*7a7741afSMartin Matuska is_nametoolong(struct dentry *dentry)
156*7a7741afSMartin Matuska {
157*7a7741afSMartin Matuska 	zfsvfs_t *zfsvfs = dentry->d_sb->s_fs_info;
158*7a7741afSMartin Matuska 	size_t dlen = dlen(dentry);
159*7a7741afSMartin Matuska 
160*7a7741afSMartin Matuska 	return ((!zfsvfs->z_longname && dlen >= ZAP_MAXNAMELEN) ||
161*7a7741afSMartin Matuska 	    dlen >= ZAP_MAXNAMELEN_NEW);
162*7a7741afSMartin Matuska }
163*7a7741afSMartin Matuska 
164eda14cbcSMatt Macy static int
165f9693befSMartin Matuska #ifdef HAVE_IOPS_CREATE_USERNS
166f9693befSMartin Matuska zpl_create(struct user_namespace *user_ns, struct inode *dir,
167f9693befSMartin Matuska     struct dentry *dentry, umode_t mode, bool flag)
168d411c1d6SMartin Matuska #elif defined(HAVE_IOPS_CREATE_IDMAP)
169d411c1d6SMartin Matuska zpl_create(struct mnt_idmap *user_ns, struct inode *dir,
170d411c1d6SMartin Matuska     struct dentry *dentry, umode_t mode, bool flag)
171f9693befSMartin Matuska #else
172eda14cbcSMatt Macy zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
173f9693befSMartin Matuska #endif
174eda14cbcSMatt Macy {
175eda14cbcSMatt Macy 	cred_t *cr = CRED();
176eda14cbcSMatt Macy 	znode_t *zp;
177eda14cbcSMatt Macy 	vattr_t *vap;
178eda14cbcSMatt Macy 	int error;
179eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
180d411c1d6SMartin Matuska #if !(defined(HAVE_IOPS_CREATE_USERNS) || defined(HAVE_IOPS_CREATE_IDMAP))
181d411c1d6SMartin Matuska 	zidmap_t *user_ns = kcred->user_ns;
182dbd5678dSMartin Matuska #endif
183eda14cbcSMatt Macy 
184*7a7741afSMartin Matuska 	if (is_nametoolong(dentry)) {
185*7a7741afSMartin Matuska 		return (-ENAMETOOLONG);
186*7a7741afSMartin Matuska 	}
187*7a7741afSMartin Matuska 
188eda14cbcSMatt Macy 	crhold(cr);
189eda14cbcSMatt Macy 	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
190dbd5678dSMartin Matuska 	zpl_vap_init(vap, dir, mode, cr, user_ns);
191eda14cbcSMatt Macy 
192eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
193eda14cbcSMatt Macy 	error = -zfs_create(ITOZ(dir), dname(dentry), vap, 0,
194dbd5678dSMartin Matuska 	    mode, &zp, cr, 0, NULL, user_ns);
195eda14cbcSMatt Macy 	if (error == 0) {
196eda14cbcSMatt Macy 		error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
197eda14cbcSMatt Macy 		if (error == 0)
198eda14cbcSMatt Macy 			error = zpl_init_acl(ZTOI(zp), dir);
199eda14cbcSMatt Macy 
20016038816SMartin Matuska 		if (error) {
201eda14cbcSMatt Macy 			(void) zfs_remove(ITOZ(dir), dname(dentry), cr, 0);
20216038816SMartin Matuska 			remove_inode_hash(ZTOI(zp));
20316038816SMartin Matuska 			iput(ZTOI(zp));
20416038816SMartin Matuska 		} else {
20516038816SMartin Matuska 			d_instantiate(dentry, ZTOI(zp));
20616038816SMartin Matuska 		}
207eda14cbcSMatt Macy 	}
208eda14cbcSMatt Macy 
209eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
210eda14cbcSMatt Macy 	kmem_free(vap, sizeof (vattr_t));
211eda14cbcSMatt Macy 	crfree(cr);
212eda14cbcSMatt Macy 	ASSERT3S(error, <=, 0);
213eda14cbcSMatt Macy 
214eda14cbcSMatt Macy 	return (error);
215eda14cbcSMatt Macy }
216eda14cbcSMatt Macy 
217eda14cbcSMatt Macy static int
218f9693befSMartin Matuska #ifdef HAVE_IOPS_MKNOD_USERNS
219f9693befSMartin Matuska zpl_mknod(struct user_namespace *user_ns, struct inode *dir,
220f9693befSMartin Matuska     struct dentry *dentry, umode_t mode,
221d411c1d6SMartin Matuska #elif defined(HAVE_IOPS_MKNOD_IDMAP)
222d411c1d6SMartin Matuska zpl_mknod(struct mnt_idmap *user_ns, struct inode *dir,
223d411c1d6SMartin Matuska     struct dentry *dentry, umode_t mode,
224f9693befSMartin Matuska #else
225eda14cbcSMatt Macy zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
226f9693befSMartin Matuska #endif
227eda14cbcSMatt Macy     dev_t rdev)
228eda14cbcSMatt Macy {
229eda14cbcSMatt Macy 	cred_t *cr = CRED();
230eda14cbcSMatt Macy 	znode_t *zp;
231eda14cbcSMatt Macy 	vattr_t *vap;
232eda14cbcSMatt Macy 	int error;
233eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
234d411c1d6SMartin Matuska #if !(defined(HAVE_IOPS_MKNOD_USERNS) || defined(HAVE_IOPS_MKNOD_IDMAP))
235d411c1d6SMartin Matuska 	zidmap_t *user_ns = kcred->user_ns;
236dbd5678dSMartin Matuska #endif
237eda14cbcSMatt Macy 
238*7a7741afSMartin Matuska 	if (is_nametoolong(dentry)) {
239*7a7741afSMartin Matuska 		return (-ENAMETOOLONG);
240*7a7741afSMartin Matuska 	}
241*7a7741afSMartin Matuska 
242eda14cbcSMatt Macy 	/*
243eda14cbcSMatt Macy 	 * We currently expect Linux to supply rdev=0 for all sockets
244eda14cbcSMatt Macy 	 * and fifos, but we want to know if this behavior ever changes.
245eda14cbcSMatt Macy 	 */
246eda14cbcSMatt Macy 	if (S_ISSOCK(mode) || S_ISFIFO(mode))
247eda14cbcSMatt Macy 		ASSERT(rdev == 0);
248eda14cbcSMatt Macy 
249eda14cbcSMatt Macy 	crhold(cr);
250eda14cbcSMatt Macy 	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
251dbd5678dSMartin Matuska 	zpl_vap_init(vap, dir, mode, cr, user_ns);
252eda14cbcSMatt Macy 	vap->va_rdev = rdev;
253eda14cbcSMatt Macy 
254eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
255eda14cbcSMatt Macy 	error = -zfs_create(ITOZ(dir), dname(dentry), vap, 0,
256dbd5678dSMartin Matuska 	    mode, &zp, cr, 0, NULL, user_ns);
257eda14cbcSMatt Macy 	if (error == 0) {
258eda14cbcSMatt Macy 		error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
259eda14cbcSMatt Macy 		if (error == 0)
260eda14cbcSMatt Macy 			error = zpl_init_acl(ZTOI(zp), dir);
261eda14cbcSMatt Macy 
26216038816SMartin Matuska 		if (error) {
263eda14cbcSMatt Macy 			(void) zfs_remove(ITOZ(dir), dname(dentry), cr, 0);
26416038816SMartin Matuska 			remove_inode_hash(ZTOI(zp));
26516038816SMartin Matuska 			iput(ZTOI(zp));
26616038816SMartin Matuska 		} else {
26716038816SMartin Matuska 			d_instantiate(dentry, ZTOI(zp));
26816038816SMartin Matuska 		}
269eda14cbcSMatt Macy 	}
270eda14cbcSMatt Macy 
271eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
272eda14cbcSMatt Macy 	kmem_free(vap, sizeof (vattr_t));
273eda14cbcSMatt Macy 	crfree(cr);
274eda14cbcSMatt Macy 	ASSERT3S(error, <=, 0);
275eda14cbcSMatt Macy 
276eda14cbcSMatt Macy 	return (error);
277eda14cbcSMatt Macy }
278eda14cbcSMatt Macy 
279eda14cbcSMatt Macy static int
280d411c1d6SMartin Matuska #ifdef HAVE_TMPFILE_IDMAP
281d411c1d6SMartin Matuska zpl_tmpfile(struct mnt_idmap *userns, struct inode *dir,
282d411c1d6SMartin Matuska     struct file *file, umode_t mode)
283d411c1d6SMartin Matuska #elif !defined(HAVE_TMPFILE_DENTRY)
28415f0b8c3SMartin Matuska zpl_tmpfile(struct user_namespace *userns, struct inode *dir,
28515f0b8c3SMartin Matuska     struct file *file, umode_t mode)
28615f0b8c3SMartin Matuska #else
28716038816SMartin Matuska #ifdef HAVE_TMPFILE_USERNS
28816038816SMartin Matuska zpl_tmpfile(struct user_namespace *userns, struct inode *dir,
28916038816SMartin Matuska     struct dentry *dentry, umode_t mode)
29016038816SMartin Matuska #else
291eda14cbcSMatt Macy zpl_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
29216038816SMartin Matuska #endif
29315f0b8c3SMartin Matuska #endif
294eda14cbcSMatt Macy {
295eda14cbcSMatt Macy 	cred_t *cr = CRED();
296eda14cbcSMatt Macy 	struct inode *ip;
297eda14cbcSMatt Macy 	vattr_t *vap;
298eda14cbcSMatt Macy 	int error;
299eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
300d411c1d6SMartin Matuska #if !(defined(HAVE_TMPFILE_USERNS) || defined(HAVE_TMPFILE_IDMAP))
301d411c1d6SMartin Matuska 	zidmap_t *userns = kcred->user_ns;
302dbd5678dSMartin Matuska #endif
303eda14cbcSMatt Macy 
304eda14cbcSMatt Macy 	crhold(cr);
305eda14cbcSMatt Macy 	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
306eda14cbcSMatt Macy 	/*
307eda14cbcSMatt Macy 	 * The VFS does not apply the umask, therefore it is applied here
308eda14cbcSMatt Macy 	 * when POSIX ACLs are not enabled.
309eda14cbcSMatt Macy 	 */
310eda14cbcSMatt Macy 	if (!IS_POSIXACL(dir))
311eda14cbcSMatt Macy 		mode &= ~current_umask();
312dbd5678dSMartin Matuska 	zpl_vap_init(vap, dir, mode, cr, userns);
313eda14cbcSMatt Macy 
314eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
315dbd5678dSMartin Matuska 	error = -zfs_tmpfile(dir, vap, 0, mode, &ip, cr, 0, NULL, userns);
316eda14cbcSMatt Macy 	if (error == 0) {
317eda14cbcSMatt Macy 		/* d_tmpfile will do drop_nlink, so we should set it first */
318eda14cbcSMatt Macy 		set_nlink(ip, 1);
31915f0b8c3SMartin Matuska #ifndef HAVE_TMPFILE_DENTRY
32015f0b8c3SMartin Matuska 		d_tmpfile(file, ip);
32115f0b8c3SMartin Matuska 
32215f0b8c3SMartin Matuska 		error = zpl_xattr_security_init(ip, dir,
32315f0b8c3SMartin Matuska 		    &file->f_path.dentry->d_name);
32415f0b8c3SMartin Matuska #else
325eda14cbcSMatt Macy 		d_tmpfile(dentry, ip);
326eda14cbcSMatt Macy 
327eda14cbcSMatt Macy 		error = zpl_xattr_security_init(ip, dir, &dentry->d_name);
32815f0b8c3SMartin Matuska #endif
329eda14cbcSMatt Macy 		if (error == 0)
330eda14cbcSMatt Macy 			error = zpl_init_acl(ip, dir);
33115f0b8c3SMartin Matuska #ifndef HAVE_TMPFILE_DENTRY
33215f0b8c3SMartin Matuska 		error = finish_open_simple(file, error);
33315f0b8c3SMartin Matuska #endif
334eda14cbcSMatt Macy 		/*
335eda14cbcSMatt Macy 		 * don't need to handle error here, file is already in
336eda14cbcSMatt Macy 		 * unlinked set.
337eda14cbcSMatt Macy 		 */
338eda14cbcSMatt Macy 	}
339eda14cbcSMatt Macy 
340eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
341eda14cbcSMatt Macy 	kmem_free(vap, sizeof (vattr_t));
342eda14cbcSMatt Macy 	crfree(cr);
343eda14cbcSMatt Macy 	ASSERT3S(error, <=, 0);
344eda14cbcSMatt Macy 
345eda14cbcSMatt Macy 	return (error);
346eda14cbcSMatt Macy }
347eda14cbcSMatt Macy 
348eda14cbcSMatt Macy static int
349eda14cbcSMatt Macy zpl_unlink(struct inode *dir, struct dentry *dentry)
350eda14cbcSMatt Macy {
351eda14cbcSMatt Macy 	cred_t *cr = CRED();
352eda14cbcSMatt Macy 	int error;
353eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
354eda14cbcSMatt Macy 	zfsvfs_t *zfsvfs = dentry->d_sb->s_fs_info;
355eda14cbcSMatt Macy 
356eda14cbcSMatt Macy 	crhold(cr);
357eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
358eda14cbcSMatt Macy 	error = -zfs_remove(ITOZ(dir), dname(dentry), cr, 0);
359eda14cbcSMatt Macy 
360eda14cbcSMatt Macy 	/*
361eda14cbcSMatt Macy 	 * For a CI FS we must invalidate the dentry to prevent the
362eda14cbcSMatt Macy 	 * creation of negative entries.
363eda14cbcSMatt Macy 	 */
364eda14cbcSMatt Macy 	if (error == 0 && zfsvfs->z_case == ZFS_CASE_INSENSITIVE)
365eda14cbcSMatt Macy 		d_invalidate(dentry);
366eda14cbcSMatt Macy 
367eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
368eda14cbcSMatt Macy 	crfree(cr);
369eda14cbcSMatt Macy 	ASSERT3S(error, <=, 0);
370eda14cbcSMatt Macy 
371eda14cbcSMatt Macy 	return (error);
372eda14cbcSMatt Macy }
373eda14cbcSMatt Macy 
374eda14cbcSMatt Macy static int
375f9693befSMartin Matuska #ifdef HAVE_IOPS_MKDIR_USERNS
376f9693befSMartin Matuska zpl_mkdir(struct user_namespace *user_ns, struct inode *dir,
377f9693befSMartin Matuska     struct dentry *dentry, umode_t mode)
378d411c1d6SMartin Matuska #elif defined(HAVE_IOPS_MKDIR_IDMAP)
379d411c1d6SMartin Matuska zpl_mkdir(struct mnt_idmap *user_ns, struct inode *dir,
380d411c1d6SMartin Matuska     struct dentry *dentry, umode_t mode)
381f9693befSMartin Matuska #else
382eda14cbcSMatt Macy zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
383f9693befSMartin Matuska #endif
384eda14cbcSMatt Macy {
385eda14cbcSMatt Macy 	cred_t *cr = CRED();
386eda14cbcSMatt Macy 	vattr_t *vap;
387eda14cbcSMatt Macy 	znode_t *zp;
388eda14cbcSMatt Macy 	int error;
389eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
390d411c1d6SMartin Matuska #if !(defined(HAVE_IOPS_MKDIR_USERNS) || defined(HAVE_IOPS_MKDIR_IDMAP))
391d411c1d6SMartin Matuska 	zidmap_t *user_ns = kcred->user_ns;
392dbd5678dSMartin Matuska #endif
393eda14cbcSMatt Macy 
394*7a7741afSMartin Matuska 	if (is_nametoolong(dentry)) {
395*7a7741afSMartin Matuska 		return (-ENAMETOOLONG);
396*7a7741afSMartin Matuska 	}
397*7a7741afSMartin Matuska 
398eda14cbcSMatt Macy 	crhold(cr);
399eda14cbcSMatt Macy 	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
400dbd5678dSMartin Matuska 	zpl_vap_init(vap, dir, mode | S_IFDIR, cr, user_ns);
401eda14cbcSMatt Macy 
402eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
403dbd5678dSMartin Matuska 	error = -zfs_mkdir(ITOZ(dir), dname(dentry), vap, &zp, cr, 0, NULL,
404dbd5678dSMartin Matuska 	    user_ns);
405eda14cbcSMatt Macy 	if (error == 0) {
406eda14cbcSMatt Macy 		error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
407eda14cbcSMatt Macy 		if (error == 0)
408eda14cbcSMatt Macy 			error = zpl_init_acl(ZTOI(zp), dir);
409eda14cbcSMatt Macy 
41016038816SMartin Matuska 		if (error) {
411eda14cbcSMatt Macy 			(void) zfs_rmdir(ITOZ(dir), dname(dentry), NULL, cr, 0);
41216038816SMartin Matuska 			remove_inode_hash(ZTOI(zp));
41316038816SMartin Matuska 			iput(ZTOI(zp));
41416038816SMartin Matuska 		} else {
41516038816SMartin Matuska 			d_instantiate(dentry, ZTOI(zp));
41616038816SMartin Matuska 		}
417eda14cbcSMatt Macy 	}
418eda14cbcSMatt Macy 
419eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
420eda14cbcSMatt Macy 	kmem_free(vap, sizeof (vattr_t));
421eda14cbcSMatt Macy 	crfree(cr);
422eda14cbcSMatt Macy 	ASSERT3S(error, <=, 0);
423eda14cbcSMatt Macy 
424eda14cbcSMatt Macy 	return (error);
425eda14cbcSMatt Macy }
426eda14cbcSMatt Macy 
427eda14cbcSMatt Macy static int
428eda14cbcSMatt Macy zpl_rmdir(struct inode *dir, struct dentry *dentry)
429eda14cbcSMatt Macy {
430eda14cbcSMatt Macy 	cred_t *cr = CRED();
431eda14cbcSMatt Macy 	int error;
432eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
433eda14cbcSMatt Macy 	zfsvfs_t *zfsvfs = dentry->d_sb->s_fs_info;
434eda14cbcSMatt Macy 
435eda14cbcSMatt Macy 	crhold(cr);
436eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
437eda14cbcSMatt Macy 	error = -zfs_rmdir(ITOZ(dir), dname(dentry), NULL, cr, 0);
438eda14cbcSMatt Macy 
439eda14cbcSMatt Macy 	/*
440eda14cbcSMatt Macy 	 * For a CI FS we must invalidate the dentry to prevent the
441eda14cbcSMatt Macy 	 * creation of negative entries.
442eda14cbcSMatt Macy 	 */
443eda14cbcSMatt Macy 	if (error == 0 && zfsvfs->z_case == ZFS_CASE_INSENSITIVE)
444eda14cbcSMatt Macy 		d_invalidate(dentry);
445eda14cbcSMatt Macy 
446eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
447eda14cbcSMatt Macy 	crfree(cr);
448eda14cbcSMatt Macy 	ASSERT3S(error, <=, 0);
449eda14cbcSMatt Macy 
450eda14cbcSMatt Macy 	return (error);
451eda14cbcSMatt Macy }
452eda14cbcSMatt Macy 
453eda14cbcSMatt Macy static int
454f9693befSMartin Matuska #ifdef HAVE_USERNS_IOPS_GETATTR
455f9693befSMartin Matuska zpl_getattr_impl(struct user_namespace *user_ns,
456f9693befSMartin Matuska     const struct path *path, struct kstat *stat, u32 request_mask,
457f9693befSMartin Matuska     unsigned int query_flags)
458d411c1d6SMartin Matuska #elif defined(HAVE_IDMAP_IOPS_GETATTR)
459d411c1d6SMartin Matuska zpl_getattr_impl(struct mnt_idmap *user_ns,
460d411c1d6SMartin Matuska     const struct path *path, struct kstat *stat, u32 request_mask,
461d411c1d6SMartin Matuska     unsigned int query_flags)
462f9693befSMartin Matuska #else
463eda14cbcSMatt Macy zpl_getattr_impl(const struct path *path, struct kstat *stat, u32 request_mask,
464eda14cbcSMatt Macy     unsigned int query_flags)
465f9693befSMartin Matuska #endif
466eda14cbcSMatt Macy {
467eda14cbcSMatt Macy 	int error;
468eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
4692faf504dSMartin Matuska 	struct inode *ip = path->dentry->d_inode;
4702faf504dSMartin Matuska 	znode_t *zp __maybe_unused = ITOZ(ip);
471eda14cbcSMatt Macy 
472eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
473eda14cbcSMatt Macy 
474eda14cbcSMatt Macy 	/*
4752faf504dSMartin Matuska 	 * XXX query_flags currently ignored.
476eda14cbcSMatt Macy 	 */
477eda14cbcSMatt Macy 
478abcdc1b9SMartin Matuska #ifdef HAVE_GENERIC_FILLATTR_IDMAP_REQMASK
479abcdc1b9SMartin Matuska 	error = -zfs_getattr_fast(user_ns, request_mask, ip, stat);
480abcdc1b9SMartin Matuska #elif (defined(HAVE_USERNS_IOPS_GETATTR) || defined(HAVE_IDMAP_IOPS_GETATTR))
4812faf504dSMartin Matuska 	error = -zfs_getattr_fast(user_ns, ip, stat);
482f9693befSMartin Matuska #else
4832faf504dSMartin Matuska 	error = -zfs_getattr_fast(kcred->user_ns, ip, stat);
484f9693befSMartin Matuska #endif
4852faf504dSMartin Matuska 
4862faf504dSMartin Matuska #ifdef STATX_BTIME
4872faf504dSMartin Matuska 	if (request_mask & STATX_BTIME) {
4882faf504dSMartin Matuska 		stat->btime = zp->z_btime;
4892faf504dSMartin Matuska 		stat->result_mask |= STATX_BTIME;
4902faf504dSMartin Matuska 	}
4912faf504dSMartin Matuska #endif
4922faf504dSMartin Matuska 
4932faf504dSMartin Matuska #ifdef STATX_ATTR_IMMUTABLE
4942faf504dSMartin Matuska 	if (zp->z_pflags & ZFS_IMMUTABLE)
4952faf504dSMartin Matuska 		stat->attributes |= STATX_ATTR_IMMUTABLE;
4962faf504dSMartin Matuska 	stat->attributes_mask |= STATX_ATTR_IMMUTABLE;
4972faf504dSMartin Matuska #endif
4982faf504dSMartin Matuska 
4992faf504dSMartin Matuska #ifdef STATX_ATTR_APPEND
5002faf504dSMartin Matuska 	if (zp->z_pflags & ZFS_APPENDONLY)
5012faf504dSMartin Matuska 		stat->attributes |= STATX_ATTR_APPEND;
5022faf504dSMartin Matuska 	stat->attributes_mask |= STATX_ATTR_APPEND;
5032faf504dSMartin Matuska #endif
5042faf504dSMartin Matuska 
5052faf504dSMartin Matuska #ifdef STATX_ATTR_NODUMP
5062faf504dSMartin Matuska 	if (zp->z_pflags & ZFS_NODUMP)
5072faf504dSMartin Matuska 		stat->attributes |= STATX_ATTR_NODUMP;
5082faf504dSMartin Matuska 	stat->attributes_mask |= STATX_ATTR_NODUMP;
5092faf504dSMartin Matuska #endif
5102faf504dSMartin Matuska 
511eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
512eda14cbcSMatt Macy 	ASSERT3S(error, <=, 0);
513eda14cbcSMatt Macy 
514eda14cbcSMatt Macy 	return (error);
515eda14cbcSMatt Macy }
516eda14cbcSMatt Macy ZPL_GETATTR_WRAPPER(zpl_getattr);
517eda14cbcSMatt Macy 
518eda14cbcSMatt Macy static int
519d411c1d6SMartin Matuska #ifdef HAVE_USERNS_IOPS_SETATTR
520f9693befSMartin Matuska zpl_setattr(struct user_namespace *user_ns, struct dentry *dentry,
521f9693befSMartin Matuska     struct iattr *ia)
522d411c1d6SMartin Matuska #elif defined(HAVE_IDMAP_IOPS_SETATTR)
523d411c1d6SMartin Matuska zpl_setattr(struct mnt_idmap *user_ns, struct dentry *dentry,
524d411c1d6SMartin Matuska     struct iattr *ia)
525f9693befSMartin Matuska #else
526eda14cbcSMatt Macy zpl_setattr(struct dentry *dentry, struct iattr *ia)
527f9693befSMartin Matuska #endif
528eda14cbcSMatt Macy {
529eda14cbcSMatt Macy 	struct inode *ip = dentry->d_inode;
530eda14cbcSMatt Macy 	cred_t *cr = CRED();
531eda14cbcSMatt Macy 	vattr_t *vap;
532eda14cbcSMatt Macy 	int error;
533eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
534eda14cbcSMatt Macy 
535dbd5678dSMartin Matuska #ifdef HAVE_SETATTR_PREPARE_USERNS
536dbd5678dSMartin Matuska 	error = zpl_setattr_prepare(user_ns, dentry, ia);
537d411c1d6SMartin Matuska #elif defined(HAVE_SETATTR_PREPARE_IDMAP)
538d411c1d6SMartin Matuska 	error = zpl_setattr_prepare(user_ns, dentry, ia);
539dbd5678dSMartin Matuska #else
540d411c1d6SMartin Matuska 	error = zpl_setattr_prepare(zfs_init_idmap, dentry, ia);
541dbd5678dSMartin Matuska #endif
542eda14cbcSMatt Macy 	if (error)
543eda14cbcSMatt Macy 		return (error);
544eda14cbcSMatt Macy 
545eda14cbcSMatt Macy 	crhold(cr);
546eda14cbcSMatt Macy 	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
547eda14cbcSMatt Macy 	vap->va_mask = ia->ia_valid & ATTR_IATTR_MASK;
548eda14cbcSMatt Macy 	vap->va_mode = ia->ia_mode;
549dbd5678dSMartin Matuska 	if (ia->ia_valid & ATTR_UID)
550dbd5678dSMartin Matuska #ifdef HAVE_IATTR_VFSID
551dbd5678dSMartin Matuska 		vap->va_uid = zfs_vfsuid_to_uid(user_ns, zfs_i_user_ns(ip),
552dbd5678dSMartin Matuska 		    __vfsuid_val(ia->ia_vfsuid));
553dbd5678dSMartin Matuska #else
554eda14cbcSMatt Macy 		vap->va_uid = KUID_TO_SUID(ia->ia_uid);
555dbd5678dSMartin Matuska #endif
556dbd5678dSMartin Matuska 	if (ia->ia_valid & ATTR_GID)
557dbd5678dSMartin Matuska #ifdef HAVE_IATTR_VFSID
558dbd5678dSMartin Matuska 		vap->va_gid = zfs_vfsgid_to_gid(user_ns, zfs_i_user_ns(ip),
559dbd5678dSMartin Matuska 		    __vfsgid_val(ia->ia_vfsgid));
560dbd5678dSMartin Matuska #else
561eda14cbcSMatt Macy 		vap->va_gid = KGID_TO_SGID(ia->ia_gid);
562dbd5678dSMartin Matuska #endif
563eda14cbcSMatt Macy 	vap->va_size = ia->ia_size;
564eda14cbcSMatt Macy 	vap->va_atime = ia->ia_atime;
565eda14cbcSMatt Macy 	vap->va_mtime = ia->ia_mtime;
566eda14cbcSMatt Macy 	vap->va_ctime = ia->ia_ctime;
567eda14cbcSMatt Macy 
568eda14cbcSMatt Macy 	if (vap->va_mask & ATTR_ATIME)
569b356da80SMartin Matuska 		zpl_inode_set_atime_to_ts(ip,
570b356da80SMartin Matuska 		    zpl_inode_timestamp_truncate(ia->ia_atime, ip));
571eda14cbcSMatt Macy 
572eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
573d411c1d6SMartin Matuska #ifdef HAVE_USERNS_IOPS_SETATTR
574d411c1d6SMartin Matuska 	error = -zfs_setattr(ITOZ(ip), vap, 0, cr, user_ns);
575d411c1d6SMartin Matuska #elif defined(HAVE_IDMAP_IOPS_SETATTR)
576dbd5678dSMartin Matuska 	error = -zfs_setattr(ITOZ(ip), vap, 0, cr, user_ns);
577dbd5678dSMartin Matuska #else
578d411c1d6SMartin Matuska 	error = -zfs_setattr(ITOZ(ip), vap, 0, cr, zfs_init_idmap);
579dbd5678dSMartin Matuska #endif
580eda14cbcSMatt Macy 	if (!error && (ia->ia_valid & ATTR_MODE))
581eda14cbcSMatt Macy 		error = zpl_chmod_acl(ip);
582eda14cbcSMatt Macy 
583eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
584eda14cbcSMatt Macy 	kmem_free(vap, sizeof (vattr_t));
585eda14cbcSMatt Macy 	crfree(cr);
586eda14cbcSMatt Macy 	ASSERT3S(error, <=, 0);
587eda14cbcSMatt Macy 
588eda14cbcSMatt Macy 	return (error);
589eda14cbcSMatt Macy }
590eda14cbcSMatt Macy 
591eda14cbcSMatt Macy static int
592f9693befSMartin Matuska #ifdef HAVE_IOPS_RENAME_USERNS
593f9693befSMartin Matuska zpl_rename2(struct user_namespace *user_ns, struct inode *sdip,
594f9693befSMartin Matuska     struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
595dbd5678dSMartin Matuska     unsigned int rflags)
596d411c1d6SMartin Matuska #elif defined(HAVE_IOPS_RENAME_IDMAP)
597d411c1d6SMartin Matuska zpl_rename2(struct mnt_idmap *user_ns, struct inode *sdip,
598d411c1d6SMartin Matuska     struct dentry *sdentry, struct inode *tdip, struct dentry *tdentry,
599d411c1d6SMartin Matuska     unsigned int rflags)
600f9693befSMartin Matuska #else
601eda14cbcSMatt Macy zpl_rename2(struct inode *sdip, struct dentry *sdentry,
602dbd5678dSMartin Matuska     struct inode *tdip, struct dentry *tdentry, unsigned int rflags)
603f9693befSMartin Matuska #endif
604eda14cbcSMatt Macy {
605eda14cbcSMatt Macy 	cred_t *cr = CRED();
606dbd5678dSMartin Matuska 	vattr_t *wo_vap = NULL;
607eda14cbcSMatt Macy 	int error;
608eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
609d411c1d6SMartin Matuska #if !(defined(HAVE_IOPS_RENAME_USERNS) || defined(HAVE_IOPS_RENAME_IDMAP))
610d411c1d6SMartin Matuska 	zidmap_t *user_ns = kcred->user_ns;
611dbd5678dSMartin Matuska #endif
612eda14cbcSMatt Macy 
613*7a7741afSMartin Matuska 	if (is_nametoolong(tdentry)) {
614*7a7741afSMartin Matuska 		return (-ENAMETOOLONG);
615*7a7741afSMartin Matuska 	}
616*7a7741afSMartin Matuska 
617eda14cbcSMatt Macy 	crhold(cr);
618dbd5678dSMartin Matuska 	if (rflags & RENAME_WHITEOUT) {
619dbd5678dSMartin Matuska 		wo_vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
620dbd5678dSMartin Matuska 		zpl_vap_init(wo_vap, sdip, S_IFCHR, cr, user_ns);
621dbd5678dSMartin Matuska 		wo_vap->va_rdev = makedevice(0, 0);
622dbd5678dSMartin Matuska 	}
623dbd5678dSMartin Matuska 
624eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
625eda14cbcSMatt Macy 	error = -zfs_rename(ITOZ(sdip), dname(sdentry), ITOZ(tdip),
626dbd5678dSMartin Matuska 	    dname(tdentry), cr, 0, rflags, wo_vap, user_ns);
627eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
628dbd5678dSMartin Matuska 	if (wo_vap)
629dbd5678dSMartin Matuska 		kmem_free(wo_vap, sizeof (vattr_t));
630eda14cbcSMatt Macy 	crfree(cr);
631eda14cbcSMatt Macy 	ASSERT3S(error, <=, 0);
632eda14cbcSMatt Macy 
633eda14cbcSMatt Macy 	return (error);
634eda14cbcSMatt Macy }
635eda14cbcSMatt Macy 
636dbd5678dSMartin Matuska #if !defined(HAVE_IOPS_RENAME_USERNS) && \
637dbd5678dSMartin Matuska 	!defined(HAVE_RENAME_WANTS_FLAGS) && \
638d411c1d6SMartin Matuska 	!defined(HAVE_IOPS_RENAME_IDMAP)
639eda14cbcSMatt Macy static int
640eda14cbcSMatt Macy zpl_rename(struct inode *sdip, struct dentry *sdentry,
641eda14cbcSMatt Macy     struct inode *tdip, struct dentry *tdentry)
642eda14cbcSMatt Macy {
643eda14cbcSMatt Macy 	return (zpl_rename2(sdip, sdentry, tdip, tdentry, 0));
644eda14cbcSMatt Macy }
645eda14cbcSMatt Macy #endif
646eda14cbcSMatt Macy 
647eda14cbcSMatt Macy static int
648f9693befSMartin Matuska #ifdef HAVE_IOPS_SYMLINK_USERNS
649f9693befSMartin Matuska zpl_symlink(struct user_namespace *user_ns, struct inode *dir,
650f9693befSMartin Matuska     struct dentry *dentry, const char *name)
651d411c1d6SMartin Matuska #elif defined(HAVE_IOPS_SYMLINK_IDMAP)
652d411c1d6SMartin Matuska zpl_symlink(struct mnt_idmap *user_ns, struct inode *dir,
653d411c1d6SMartin Matuska     struct dentry *dentry, const char *name)
654f9693befSMartin Matuska #else
655eda14cbcSMatt Macy zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
656f9693befSMartin Matuska #endif
657eda14cbcSMatt Macy {
658eda14cbcSMatt Macy 	cred_t *cr = CRED();
659eda14cbcSMatt Macy 	vattr_t *vap;
660eda14cbcSMatt Macy 	znode_t *zp;
661eda14cbcSMatt Macy 	int error;
662eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
663d411c1d6SMartin Matuska #if !(defined(HAVE_IOPS_SYMLINK_USERNS) || defined(HAVE_IOPS_SYMLINK_IDMAP))
664d411c1d6SMartin Matuska 	zidmap_t *user_ns = kcred->user_ns;
665dbd5678dSMartin Matuska #endif
666eda14cbcSMatt Macy 
667*7a7741afSMartin Matuska 	if (is_nametoolong(dentry)) {
668*7a7741afSMartin Matuska 		return (-ENAMETOOLONG);
669*7a7741afSMartin Matuska 	}
670*7a7741afSMartin Matuska 
671eda14cbcSMatt Macy 	crhold(cr);
672eda14cbcSMatt Macy 	vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
673dbd5678dSMartin Matuska 	zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr, user_ns);
674eda14cbcSMatt Macy 
675eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
676eda14cbcSMatt Macy 	error = -zfs_symlink(ITOZ(dir), dname(dentry), vap,
677dbd5678dSMartin Matuska 	    (char *)name, &zp, cr, 0, user_ns);
678eda14cbcSMatt Macy 	if (error == 0) {
679eda14cbcSMatt Macy 		error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
68016038816SMartin Matuska 		if (error) {
681eda14cbcSMatt Macy 			(void) zfs_remove(ITOZ(dir), dname(dentry), cr, 0);
68216038816SMartin Matuska 			remove_inode_hash(ZTOI(zp));
68316038816SMartin Matuska 			iput(ZTOI(zp));
68416038816SMartin Matuska 		} else {
68516038816SMartin Matuska 			d_instantiate(dentry, ZTOI(zp));
68616038816SMartin Matuska 		}
687eda14cbcSMatt Macy 	}
688eda14cbcSMatt Macy 
689eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
690eda14cbcSMatt Macy 	kmem_free(vap, sizeof (vattr_t));
691eda14cbcSMatt Macy 	crfree(cr);
692eda14cbcSMatt Macy 	ASSERT3S(error, <=, 0);
693eda14cbcSMatt Macy 
694eda14cbcSMatt Macy 	return (error);
695eda14cbcSMatt Macy }
696eda14cbcSMatt Macy 
697eda14cbcSMatt Macy static void
698eda14cbcSMatt Macy zpl_put_link(void *ptr)
699eda14cbcSMatt Macy {
700eda14cbcSMatt Macy 	kmem_free(ptr, MAXPATHLEN);
701eda14cbcSMatt Macy }
702eda14cbcSMatt Macy 
703eda14cbcSMatt Macy static int
704eda14cbcSMatt Macy zpl_get_link_common(struct dentry *dentry, struct inode *ip, char **link)
705eda14cbcSMatt Macy {
706eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
707eda14cbcSMatt Macy 	cred_t *cr = CRED();
708eda14cbcSMatt Macy 	int error;
709eda14cbcSMatt Macy 
710eda14cbcSMatt Macy 	crhold(cr);
711eda14cbcSMatt Macy 	*link = NULL;
7127877fdebSMatt Macy 
7137877fdebSMatt Macy 	struct iovec iov;
714eda14cbcSMatt Macy 	iov.iov_len = MAXPATHLEN;
715eda14cbcSMatt Macy 	iov.iov_base = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
716eda14cbcSMatt Macy 
717184c1b94SMartin Matuska 	zfs_uio_t uio;
718184c1b94SMartin Matuska 	zfs_uio_iovec_init(&uio, &iov, 1, 0, UIO_SYSSPACE, MAXPATHLEN - 1, 0);
719eda14cbcSMatt Macy 
720eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
721eda14cbcSMatt Macy 	error = -zfs_readlink(ip, &uio, cr);
722eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
723eda14cbcSMatt Macy 	crfree(cr);
724eda14cbcSMatt Macy 
725eda14cbcSMatt Macy 	if (error)
726eda14cbcSMatt Macy 		kmem_free(iov.iov_base, MAXPATHLEN);
727eda14cbcSMatt Macy 	else
728eda14cbcSMatt Macy 		*link = iov.iov_base;
729eda14cbcSMatt Macy 
730eda14cbcSMatt Macy 	return (error);
731eda14cbcSMatt Macy }
732eda14cbcSMatt Macy 
733eda14cbcSMatt Macy static const char *
734eda14cbcSMatt Macy zpl_get_link(struct dentry *dentry, struct inode *inode,
735eda14cbcSMatt Macy     struct delayed_call *done)
736eda14cbcSMatt Macy {
737eda14cbcSMatt Macy 	char *link = NULL;
738eda14cbcSMatt Macy 	int error;
739eda14cbcSMatt Macy 
740eda14cbcSMatt Macy 	if (!dentry)
741eda14cbcSMatt Macy 		return (ERR_PTR(-ECHILD));
742eda14cbcSMatt Macy 
743eda14cbcSMatt Macy 	error = zpl_get_link_common(dentry, inode, &link);
744eda14cbcSMatt Macy 	if (error)
745eda14cbcSMatt Macy 		return (ERR_PTR(error));
746eda14cbcSMatt Macy 
747eda14cbcSMatt Macy 	set_delayed_call(done, zpl_put_link, link);
748eda14cbcSMatt Macy 
749eda14cbcSMatt Macy 	return (link);
750eda14cbcSMatt Macy }
751eda14cbcSMatt Macy 
752eda14cbcSMatt Macy static int
753eda14cbcSMatt Macy zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
754eda14cbcSMatt Macy {
755eda14cbcSMatt Macy 	cred_t *cr = CRED();
756eda14cbcSMatt Macy 	struct inode *ip = old_dentry->d_inode;
757eda14cbcSMatt Macy 	int error;
758eda14cbcSMatt Macy 	fstrans_cookie_t cookie;
759eda14cbcSMatt Macy 
760*7a7741afSMartin Matuska 	if (is_nametoolong(dentry)) {
761*7a7741afSMartin Matuska 		return (-ENAMETOOLONG);
762*7a7741afSMartin Matuska 	}
763*7a7741afSMartin Matuska 
764eda14cbcSMatt Macy 	if (ip->i_nlink >= ZFS_LINK_MAX)
765eda14cbcSMatt Macy 		return (-EMLINK);
766eda14cbcSMatt Macy 
767eda14cbcSMatt Macy 	crhold(cr);
768abcdc1b9SMartin Matuska 	zpl_inode_set_ctime_to_ts(ip, current_time(ip));
769f9693befSMartin Matuska 	/* Must have an existing ref, so igrab() cannot return NULL */
770f9693befSMartin Matuska 	VERIFY3P(igrab(ip), !=, NULL);
771eda14cbcSMatt Macy 
772eda14cbcSMatt Macy 	cookie = spl_fstrans_mark();
773eda14cbcSMatt Macy 	error = -zfs_link(ITOZ(dir), ITOZ(ip), dname(dentry), cr, 0);
774eda14cbcSMatt Macy 	if (error) {
775eda14cbcSMatt Macy 		iput(ip);
776eda14cbcSMatt Macy 		goto out;
777eda14cbcSMatt Macy 	}
778eda14cbcSMatt Macy 
779eda14cbcSMatt Macy 	d_instantiate(dentry, ip);
780eda14cbcSMatt Macy out:
781eda14cbcSMatt Macy 	spl_fstrans_unmark(cookie);
782eda14cbcSMatt Macy 	crfree(cr);
783eda14cbcSMatt Macy 	ASSERT3S(error, <=, 0);
784eda14cbcSMatt Macy 
785eda14cbcSMatt Macy 	return (error);
786eda14cbcSMatt Macy }
787eda14cbcSMatt Macy 
788eda14cbcSMatt Macy const struct inode_operations zpl_inode_operations = {
789eda14cbcSMatt Macy 	.setattr	= zpl_setattr,
790eda14cbcSMatt Macy 	.getattr	= zpl_getattr,
791eda14cbcSMatt Macy 	.listxattr	= zpl_xattr_list,
792eda14cbcSMatt Macy #if defined(CONFIG_FS_POSIX_ACL)
793eda14cbcSMatt Macy 	.set_acl	= zpl_set_acl,
79415f0b8c3SMartin Matuska #if defined(HAVE_GET_INODE_ACL)
79515f0b8c3SMartin Matuska 	.get_inode_acl	= zpl_get_acl,
79615f0b8c3SMartin Matuska #else
797eda14cbcSMatt Macy 	.get_acl	= zpl_get_acl,
79815f0b8c3SMartin Matuska #endif /* HAVE_GET_INODE_ACL */
799eda14cbcSMatt Macy #endif /* CONFIG_FS_POSIX_ACL */
800eda14cbcSMatt Macy };
801eda14cbcSMatt Macy 
802eda14cbcSMatt Macy const struct inode_operations zpl_dir_inode_operations = {
803eda14cbcSMatt Macy 	.create		= zpl_create,
804eda14cbcSMatt Macy 	.lookup		= zpl_lookup,
805eda14cbcSMatt Macy 	.link		= zpl_link,
806eda14cbcSMatt Macy 	.unlink		= zpl_unlink,
807eda14cbcSMatt Macy 	.symlink	= zpl_symlink,
808eda14cbcSMatt Macy 	.mkdir		= zpl_mkdir,
809eda14cbcSMatt Macy 	.rmdir		= zpl_rmdir,
810eda14cbcSMatt Macy 	.mknod		= zpl_mknod,
811*7a7741afSMartin Matuska #if defined(HAVE_RENAME_WANTS_FLAGS) || defined(HAVE_IOPS_RENAME_USERNS)
812eda14cbcSMatt Macy 	.rename		= zpl_rename2,
813d411c1d6SMartin Matuska #elif defined(HAVE_IOPS_RENAME_IDMAP)
814d411c1d6SMartin Matuska 	.rename		= zpl_rename2,
815eda14cbcSMatt Macy #else
816eda14cbcSMatt Macy 	.rename		= zpl_rename,
817eda14cbcSMatt Macy #endif
818eda14cbcSMatt Macy 	.tmpfile	= zpl_tmpfile,
819eda14cbcSMatt Macy 	.setattr	= zpl_setattr,
820eda14cbcSMatt Macy 	.getattr	= zpl_getattr,
821eda14cbcSMatt Macy 	.listxattr	= zpl_xattr_list,
822eda14cbcSMatt Macy #if defined(CONFIG_FS_POSIX_ACL)
823eda14cbcSMatt Macy 	.set_acl	= zpl_set_acl,
82415f0b8c3SMartin Matuska #if defined(HAVE_GET_INODE_ACL)
82515f0b8c3SMartin Matuska 	.get_inode_acl	= zpl_get_acl,
82615f0b8c3SMartin Matuska #else
827eda14cbcSMatt Macy 	.get_acl	= zpl_get_acl,
82815f0b8c3SMartin Matuska #endif /* HAVE_GET_INODE_ACL */
829eda14cbcSMatt Macy #endif /* CONFIG_FS_POSIX_ACL */
830eda14cbcSMatt Macy };
831eda14cbcSMatt Macy 
832eda14cbcSMatt Macy const struct inode_operations zpl_symlink_inode_operations = {
833eda14cbcSMatt Macy 	.get_link	= zpl_get_link,
834eda14cbcSMatt Macy 	.setattr	= zpl_setattr,
835eda14cbcSMatt Macy 	.getattr	= zpl_getattr,
836eda14cbcSMatt Macy 	.listxattr	= zpl_xattr_list,
837eda14cbcSMatt Macy };
838eda14cbcSMatt Macy 
839eda14cbcSMatt Macy const struct inode_operations zpl_special_inode_operations = {
840eda14cbcSMatt Macy 	.setattr	= zpl_setattr,
841eda14cbcSMatt Macy 	.getattr	= zpl_getattr,
842eda14cbcSMatt Macy 	.listxattr	= zpl_xattr_list,
843eda14cbcSMatt Macy #if defined(CONFIG_FS_POSIX_ACL)
844eda14cbcSMatt Macy 	.set_acl	= zpl_set_acl,
84515f0b8c3SMartin Matuska #if defined(HAVE_GET_INODE_ACL)
84615f0b8c3SMartin Matuska 	.get_inode_acl	= zpl_get_acl,
84715f0b8c3SMartin Matuska #else
848eda14cbcSMatt Macy 	.get_acl	= zpl_get_acl,
84915f0b8c3SMartin Matuska #endif /* HAVE_GET_INODE_ACL */
850eda14cbcSMatt Macy #endif /* CONFIG_FS_POSIX_ACL */
851eda14cbcSMatt Macy };
852