xref: /openbmc/linux/fs/xfs/xfs_iops.c (revision d540e43b0ab134b22f015f725ce6e070d12b0244)
1c59d87c4SChristoph Hellwig /*
2c59d87c4SChristoph Hellwig  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3c59d87c4SChristoph Hellwig  * All Rights Reserved.
4c59d87c4SChristoph Hellwig  *
5c59d87c4SChristoph Hellwig  * This program is free software; you can redistribute it and/or
6c59d87c4SChristoph Hellwig  * modify it under the terms of the GNU General Public License as
7c59d87c4SChristoph Hellwig  * published by the Free Software Foundation.
8c59d87c4SChristoph Hellwig  *
9c59d87c4SChristoph Hellwig  * This program is distributed in the hope that it would be useful,
10c59d87c4SChristoph Hellwig  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c59d87c4SChristoph Hellwig  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12c59d87c4SChristoph Hellwig  * GNU General Public License for more details.
13c59d87c4SChristoph Hellwig  *
14c59d87c4SChristoph Hellwig  * You should have received a copy of the GNU General Public License
15c59d87c4SChristoph Hellwig  * along with this program; if not, write the Free Software Foundation,
16c59d87c4SChristoph Hellwig  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17c59d87c4SChristoph Hellwig  */
18c59d87c4SChristoph Hellwig #include "xfs.h"
19c59d87c4SChristoph Hellwig #include "xfs_fs.h"
2070a9883cSDave Chinner #include "xfs_shared.h"
21239880efSDave Chinner #include "xfs_format.h"
22239880efSDave Chinner #include "xfs_log_format.h"
23239880efSDave Chinner #include "xfs_trans_resv.h"
24c59d87c4SChristoph Hellwig #include "xfs_sb.h"
25c59d87c4SChristoph Hellwig #include "xfs_ag.h"
26c59d87c4SChristoph Hellwig #include "xfs_mount.h"
2757062787SDave Chinner #include "xfs_da_format.h"
28c59d87c4SChristoph Hellwig #include "xfs_inode.h"
29c59d87c4SChristoph Hellwig #include "xfs_bmap.h"
3068988114SDave Chinner #include "xfs_bmap_util.h"
31239880efSDave Chinner #include "xfs_acl.h"
32239880efSDave Chinner #include "xfs_quota.h"
33c59d87c4SChristoph Hellwig #include "xfs_error.h"
34c59d87c4SChristoph Hellwig #include "xfs_attr.h"
35239880efSDave Chinner #include "xfs_trans.h"
36c59d87c4SChristoph Hellwig #include "xfs_trace.h"
3727b52867SBrian Foster #include "xfs_icache.h"
38c24b5dfaSDave Chinner #include "xfs_symlink.h"
390cb97766SDave Chinner #include "xfs_da_btree.h"
400cb97766SDave Chinner #include "xfs_dir2_priv.h"
41a4fbe6abSDave Chinner #include "xfs_dinode.h"
4299b6436bSZhi Yong Wu #include "xfs_trans_space.h"
43c59d87c4SChristoph Hellwig 
44c59d87c4SChristoph Hellwig #include <linux/capability.h>
45c59d87c4SChristoph Hellwig #include <linux/xattr.h>
46c59d87c4SChristoph Hellwig #include <linux/namei.h>
47c59d87c4SChristoph Hellwig #include <linux/posix_acl.h>
48c59d87c4SChristoph Hellwig #include <linux/security.h>
49c59d87c4SChristoph Hellwig #include <linux/fiemap.h>
50c59d87c4SChristoph Hellwig #include <linux/slab.h>
51c59d87c4SChristoph Hellwig 
5293a8614eSDave Chinner /*
5393a8614eSDave Chinner  * Directories have different lock order w.r.t. mmap_sem compared to regular
5493a8614eSDave Chinner  * files. This is due to readdir potentially triggering page faults on a user
5593a8614eSDave Chinner  * buffer inside filldir(), and this happens with the ilock on the directory
5693a8614eSDave Chinner  * held. For regular files, the lock order is the other way around - the
5793a8614eSDave Chinner  * mmap_sem is taken during the page fault, and then we lock the ilock to do
5893a8614eSDave Chinner  * block mapping. Hence we need a different class for the directory ilock so
5993a8614eSDave Chinner  * that lockdep can tell them apart.
6093a8614eSDave Chinner  */
6193a8614eSDave Chinner static struct lock_class_key xfs_nondir_ilock_class;
6293a8614eSDave Chinner static struct lock_class_key xfs_dir_ilock_class;
6393a8614eSDave Chinner 
648d2a5e6eSDave Chinner static int
658d2a5e6eSDave Chinner xfs_initxattrs(
668d2a5e6eSDave Chinner 	struct inode		*inode,
678d2a5e6eSDave Chinner 	const struct xattr	*xattr_array,
6836b8d186SLinus Torvalds 	void			*fs_info)
6936b8d186SLinus Torvalds {
7036b8d186SLinus Torvalds 	const struct xattr	*xattr;
7136b8d186SLinus Torvalds 	struct xfs_inode	*ip = XFS_I(inode);
7236b8d186SLinus Torvalds 	int			error = 0;
7336b8d186SLinus Torvalds 
7436b8d186SLinus Torvalds 	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
7536b8d186SLinus Torvalds 		error = xfs_attr_set(ip, xattr->name, xattr->value,
7636b8d186SLinus Torvalds 				     xattr->value_len, ATTR_SECURE);
7736b8d186SLinus Torvalds 		if (error < 0)
7836b8d186SLinus Torvalds 			break;
7936b8d186SLinus Torvalds 	}
8036b8d186SLinus Torvalds 	return error;
8136b8d186SLinus Torvalds }
8236b8d186SLinus Torvalds 
83c59d87c4SChristoph Hellwig /*
84c59d87c4SChristoph Hellwig  * Hook in SELinux.  This is not quite correct yet, what we really need
85c59d87c4SChristoph Hellwig  * here (as we do for default ACLs) is a mechanism by which creation of
86c59d87c4SChristoph Hellwig  * these attrs can be journalled at inode creation time (along with the
87c59d87c4SChristoph Hellwig  * inode, of course, such that log replay can't cause these to be lost).
88c59d87c4SChristoph Hellwig  */
8936b8d186SLinus Torvalds 
90c59d87c4SChristoph Hellwig STATIC int
91c59d87c4SChristoph Hellwig xfs_init_security(
92c59d87c4SChristoph Hellwig 	struct inode	*inode,
93c59d87c4SChristoph Hellwig 	struct inode	*dir,
94c59d87c4SChristoph Hellwig 	const struct qstr *qstr)
95c59d87c4SChristoph Hellwig {
9636b8d186SLinus Torvalds 	return security_inode_init_security(inode, dir, qstr,
9736b8d186SLinus Torvalds 					    &xfs_initxattrs, NULL);
98c59d87c4SChristoph Hellwig }
99c59d87c4SChristoph Hellwig 
100c59d87c4SChristoph Hellwig static void
101c59d87c4SChristoph Hellwig xfs_dentry_to_name(
102c59d87c4SChristoph Hellwig 	struct xfs_name	*namep,
1030cb97766SDave Chinner 	struct dentry	*dentry,
1040cb97766SDave Chinner 	int		mode)
105c59d87c4SChristoph Hellwig {
106c59d87c4SChristoph Hellwig 	namep->name = dentry->d_name.name;
107c59d87c4SChristoph Hellwig 	namep->len = dentry->d_name.len;
1080cb97766SDave Chinner 	namep->type = xfs_mode_to_ftype[(mode & S_IFMT) >> S_SHIFT];
109c59d87c4SChristoph Hellwig }
110c59d87c4SChristoph Hellwig 
111c59d87c4SChristoph Hellwig STATIC void
112c59d87c4SChristoph Hellwig xfs_cleanup_inode(
113c59d87c4SChristoph Hellwig 	struct inode	*dir,
114c59d87c4SChristoph Hellwig 	struct inode	*inode,
115c59d87c4SChristoph Hellwig 	struct dentry	*dentry)
116c59d87c4SChristoph Hellwig {
117c59d87c4SChristoph Hellwig 	struct xfs_name	teardown;
118c59d87c4SChristoph Hellwig 
119c59d87c4SChristoph Hellwig 	/* Oh, the horror.
120c59d87c4SChristoph Hellwig 	 * If we can't add the ACL or we fail in
121c59d87c4SChristoph Hellwig 	 * xfs_init_security we must back out.
122c59d87c4SChristoph Hellwig 	 * ENOSPC can hit here, among other things.
123c59d87c4SChristoph Hellwig 	 */
1240cb97766SDave Chinner 	xfs_dentry_to_name(&teardown, dentry, 0);
125c59d87c4SChristoph Hellwig 
126c59d87c4SChristoph Hellwig 	xfs_remove(XFS_I(dir), &teardown, XFS_I(inode));
127c59d87c4SChristoph Hellwig }
128c59d87c4SChristoph Hellwig 
129c59d87c4SChristoph Hellwig STATIC int
130*d540e43bSBrian Foster xfs_generic_create(
131c59d87c4SChristoph Hellwig 	struct inode	*dir,
132c59d87c4SChristoph Hellwig 	struct dentry	*dentry,
1331a67aafbSAl Viro 	umode_t		mode,
134*d540e43bSBrian Foster 	dev_t		rdev,
135*d540e43bSBrian Foster 	bool		tmpfile)	/* unnamed file */
136c59d87c4SChristoph Hellwig {
137c59d87c4SChristoph Hellwig 	struct inode	*inode;
138c59d87c4SChristoph Hellwig 	struct xfs_inode *ip = NULL;
1392401dc29SChristoph Hellwig 	struct posix_acl *default_acl, *acl;
140c59d87c4SChristoph Hellwig 	struct xfs_name	name;
141c59d87c4SChristoph Hellwig 	int		error;
142c59d87c4SChristoph Hellwig 
143c59d87c4SChristoph Hellwig 	/*
144c59d87c4SChristoph Hellwig 	 * Irix uses Missed'em'V split, but doesn't want to see
145c59d87c4SChristoph Hellwig 	 * the upper 5 bits of (14bit) major.
146c59d87c4SChristoph Hellwig 	 */
147c59d87c4SChristoph Hellwig 	if (S_ISCHR(mode) || S_ISBLK(mode)) {
148c59d87c4SChristoph Hellwig 		if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff))
149c59d87c4SChristoph Hellwig 			return -EINVAL;
150c59d87c4SChristoph Hellwig 		rdev = sysv_encode_dev(rdev);
151c59d87c4SChristoph Hellwig 	} else {
152c59d87c4SChristoph Hellwig 		rdev = 0;
153c59d87c4SChristoph Hellwig 	}
154c59d87c4SChristoph Hellwig 
1552401dc29SChristoph Hellwig 	error = posix_acl_create(dir, &mode, &default_acl, &acl);
1562401dc29SChristoph Hellwig 	if (error)
1572401dc29SChristoph Hellwig 		return error;
158c59d87c4SChristoph Hellwig 
159*d540e43bSBrian Foster 	if (!tmpfile) {
1600cb97766SDave Chinner 		xfs_dentry_to_name(&name, dentry, mode);
161c59d87c4SChristoph Hellwig 		error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip);
162*d540e43bSBrian Foster 	} else {
163*d540e43bSBrian Foster 		error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip);
164*d540e43bSBrian Foster 	}
165c59d87c4SChristoph Hellwig 	if (unlikely(error))
166c59d87c4SChristoph Hellwig 		goto out_free_acl;
167c59d87c4SChristoph Hellwig 
168c59d87c4SChristoph Hellwig 	inode = VFS_I(ip);
169c59d87c4SChristoph Hellwig 
170c59d87c4SChristoph Hellwig 	error = xfs_init_security(inode, dir, &dentry->d_name);
171c59d87c4SChristoph Hellwig 	if (unlikely(error))
172c59d87c4SChristoph Hellwig 		goto out_cleanup_inode;
173c59d87c4SChristoph Hellwig 
1742401dc29SChristoph Hellwig #ifdef CONFIG_XFS_POSIX_ACL
175c59d87c4SChristoph Hellwig 	if (default_acl) {
1762401dc29SChristoph Hellwig 		error = xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
1772401dc29SChristoph Hellwig 		if (error)
178c59d87c4SChristoph Hellwig 			goto out_cleanup_inode;
179c59d87c4SChristoph Hellwig 	}
1802401dc29SChristoph Hellwig 	if (acl) {
1812401dc29SChristoph Hellwig 		error = xfs_set_acl(inode, acl, ACL_TYPE_ACCESS);
1822401dc29SChristoph Hellwig 		if (error)
1832401dc29SChristoph Hellwig 			goto out_cleanup_inode;
1842401dc29SChristoph Hellwig 	}
1852401dc29SChristoph Hellwig #endif
186c59d87c4SChristoph Hellwig 
187*d540e43bSBrian Foster 	if (tmpfile)
188*d540e43bSBrian Foster 		d_tmpfile(dentry, inode);
189*d540e43bSBrian Foster 	else
190c59d87c4SChristoph Hellwig 		d_instantiate(dentry, inode);
191*d540e43bSBrian Foster 
1922401dc29SChristoph Hellwig  out_free_acl:
1932401dc29SChristoph Hellwig 	if (default_acl)
1942401dc29SChristoph Hellwig 		posix_acl_release(default_acl);
1952401dc29SChristoph Hellwig 	if (acl)
1962401dc29SChristoph Hellwig 		posix_acl_release(acl);
197c59d87c4SChristoph Hellwig 	return -error;
198c59d87c4SChristoph Hellwig 
199c59d87c4SChristoph Hellwig  out_cleanup_inode:
200*d540e43bSBrian Foster 	if (!tmpfile)
201c59d87c4SChristoph Hellwig 		xfs_cleanup_inode(dir, inode, dentry);
202*d540e43bSBrian Foster 	iput(inode);
2032401dc29SChristoph Hellwig 	goto out_free_acl;
204c59d87c4SChristoph Hellwig }
205c59d87c4SChristoph Hellwig 
206c59d87c4SChristoph Hellwig STATIC int
207*d540e43bSBrian Foster xfs_vn_mknod(
208*d540e43bSBrian Foster 	struct inode	*dir,
209*d540e43bSBrian Foster 	struct dentry	*dentry,
210*d540e43bSBrian Foster 	umode_t		mode,
211*d540e43bSBrian Foster 	dev_t		rdev)
212*d540e43bSBrian Foster {
213*d540e43bSBrian Foster 	return xfs_generic_create(dir, dentry, mode, rdev, false);
214*d540e43bSBrian Foster }
215*d540e43bSBrian Foster 
216*d540e43bSBrian Foster STATIC int
217c59d87c4SChristoph Hellwig xfs_vn_create(
218c59d87c4SChristoph Hellwig 	struct inode	*dir,
219c59d87c4SChristoph Hellwig 	struct dentry	*dentry,
2204acdaf27SAl Viro 	umode_t		mode,
221ebfc3b49SAl Viro 	bool		flags)
222c59d87c4SChristoph Hellwig {
223c59d87c4SChristoph Hellwig 	return xfs_vn_mknod(dir, dentry, mode, 0);
224c59d87c4SChristoph Hellwig }
225c59d87c4SChristoph Hellwig 
226c59d87c4SChristoph Hellwig STATIC int
227c59d87c4SChristoph Hellwig xfs_vn_mkdir(
228c59d87c4SChristoph Hellwig 	struct inode	*dir,
229c59d87c4SChristoph Hellwig 	struct dentry	*dentry,
23018bb1db3SAl Viro 	umode_t		mode)
231c59d87c4SChristoph Hellwig {
232c59d87c4SChristoph Hellwig 	return xfs_vn_mknod(dir, dentry, mode|S_IFDIR, 0);
233c59d87c4SChristoph Hellwig }
234c59d87c4SChristoph Hellwig 
235c59d87c4SChristoph Hellwig STATIC struct dentry *
236c59d87c4SChristoph Hellwig xfs_vn_lookup(
237c59d87c4SChristoph Hellwig 	struct inode	*dir,
238c59d87c4SChristoph Hellwig 	struct dentry	*dentry,
23900cd8dd3SAl Viro 	unsigned int flags)
240c59d87c4SChristoph Hellwig {
241c59d87c4SChristoph Hellwig 	struct xfs_inode *cip;
242c59d87c4SChristoph Hellwig 	struct xfs_name	name;
243c59d87c4SChristoph Hellwig 	int		error;
244c59d87c4SChristoph Hellwig 
245c59d87c4SChristoph Hellwig 	if (dentry->d_name.len >= MAXNAMELEN)
246c59d87c4SChristoph Hellwig 		return ERR_PTR(-ENAMETOOLONG);
247c59d87c4SChristoph Hellwig 
2480cb97766SDave Chinner 	xfs_dentry_to_name(&name, dentry, 0);
249c59d87c4SChristoph Hellwig 	error = xfs_lookup(XFS_I(dir), &name, &cip, NULL);
250c59d87c4SChristoph Hellwig 	if (unlikely(error)) {
251c59d87c4SChristoph Hellwig 		if (unlikely(error != ENOENT))
252c59d87c4SChristoph Hellwig 			return ERR_PTR(-error);
253c59d87c4SChristoph Hellwig 		d_add(dentry, NULL);
254c59d87c4SChristoph Hellwig 		return NULL;
255c59d87c4SChristoph Hellwig 	}
256c59d87c4SChristoph Hellwig 
257c59d87c4SChristoph Hellwig 	return d_splice_alias(VFS_I(cip), dentry);
258c59d87c4SChristoph Hellwig }
259c59d87c4SChristoph Hellwig 
260c59d87c4SChristoph Hellwig STATIC struct dentry *
261c59d87c4SChristoph Hellwig xfs_vn_ci_lookup(
262c59d87c4SChristoph Hellwig 	struct inode	*dir,
263c59d87c4SChristoph Hellwig 	struct dentry	*dentry,
26400cd8dd3SAl Viro 	unsigned int flags)
265c59d87c4SChristoph Hellwig {
266c59d87c4SChristoph Hellwig 	struct xfs_inode *ip;
267c59d87c4SChristoph Hellwig 	struct xfs_name	xname;
268c59d87c4SChristoph Hellwig 	struct xfs_name ci_name;
269c59d87c4SChristoph Hellwig 	struct qstr	dname;
270c59d87c4SChristoph Hellwig 	int		error;
271c59d87c4SChristoph Hellwig 
272c59d87c4SChristoph Hellwig 	if (dentry->d_name.len >= MAXNAMELEN)
273c59d87c4SChristoph Hellwig 		return ERR_PTR(-ENAMETOOLONG);
274c59d87c4SChristoph Hellwig 
2750cb97766SDave Chinner 	xfs_dentry_to_name(&xname, dentry, 0);
276c59d87c4SChristoph Hellwig 	error = xfs_lookup(XFS_I(dir), &xname, &ip, &ci_name);
277c59d87c4SChristoph Hellwig 	if (unlikely(error)) {
278c59d87c4SChristoph Hellwig 		if (unlikely(error != ENOENT))
279c59d87c4SChristoph Hellwig 			return ERR_PTR(-error);
280c59d87c4SChristoph Hellwig 		/*
281c59d87c4SChristoph Hellwig 		 * call d_add(dentry, NULL) here when d_drop_negative_children
282c59d87c4SChristoph Hellwig 		 * is called in xfs_vn_mknod (ie. allow negative dentries
283c59d87c4SChristoph Hellwig 		 * with CI filesystems).
284c59d87c4SChristoph Hellwig 		 */
285c59d87c4SChristoph Hellwig 		return NULL;
286c59d87c4SChristoph Hellwig 	}
287c59d87c4SChristoph Hellwig 
288c59d87c4SChristoph Hellwig 	/* if exact match, just splice and exit */
289c59d87c4SChristoph Hellwig 	if (!ci_name.name)
290c59d87c4SChristoph Hellwig 		return d_splice_alias(VFS_I(ip), dentry);
291c59d87c4SChristoph Hellwig 
292c59d87c4SChristoph Hellwig 	/* else case-insensitive match... */
293c59d87c4SChristoph Hellwig 	dname.name = ci_name.name;
294c59d87c4SChristoph Hellwig 	dname.len = ci_name.len;
295c59d87c4SChristoph Hellwig 	dentry = d_add_ci(dentry, VFS_I(ip), &dname);
296c59d87c4SChristoph Hellwig 	kmem_free(ci_name.name);
297c59d87c4SChristoph Hellwig 	return dentry;
298c59d87c4SChristoph Hellwig }
299c59d87c4SChristoph Hellwig 
300c59d87c4SChristoph Hellwig STATIC int
301c59d87c4SChristoph Hellwig xfs_vn_link(
302c59d87c4SChristoph Hellwig 	struct dentry	*old_dentry,
303c59d87c4SChristoph Hellwig 	struct inode	*dir,
304c59d87c4SChristoph Hellwig 	struct dentry	*dentry)
305c59d87c4SChristoph Hellwig {
306c59d87c4SChristoph Hellwig 	struct inode	*inode = old_dentry->d_inode;
307c59d87c4SChristoph Hellwig 	struct xfs_name	name;
308c59d87c4SChristoph Hellwig 	int		error;
309c59d87c4SChristoph Hellwig 
3100cb97766SDave Chinner 	xfs_dentry_to_name(&name, dentry, inode->i_mode);
311c59d87c4SChristoph Hellwig 
312c59d87c4SChristoph Hellwig 	error = xfs_link(XFS_I(dir), XFS_I(inode), &name);
313c59d87c4SChristoph Hellwig 	if (unlikely(error))
314c59d87c4SChristoph Hellwig 		return -error;
315c59d87c4SChristoph Hellwig 
316c59d87c4SChristoph Hellwig 	ihold(inode);
317c59d87c4SChristoph Hellwig 	d_instantiate(dentry, inode);
318c59d87c4SChristoph Hellwig 	return 0;
319c59d87c4SChristoph Hellwig }
320c59d87c4SChristoph Hellwig 
321c59d87c4SChristoph Hellwig STATIC int
322c59d87c4SChristoph Hellwig xfs_vn_unlink(
323c59d87c4SChristoph Hellwig 	struct inode	*dir,
324c59d87c4SChristoph Hellwig 	struct dentry	*dentry)
325c59d87c4SChristoph Hellwig {
326c59d87c4SChristoph Hellwig 	struct xfs_name	name;
327c59d87c4SChristoph Hellwig 	int		error;
328c59d87c4SChristoph Hellwig 
3290cb97766SDave Chinner 	xfs_dentry_to_name(&name, dentry, 0);
330c59d87c4SChristoph Hellwig 
331c59d87c4SChristoph Hellwig 	error = -xfs_remove(XFS_I(dir), &name, XFS_I(dentry->d_inode));
332c59d87c4SChristoph Hellwig 	if (error)
333c59d87c4SChristoph Hellwig 		return error;
334c59d87c4SChristoph Hellwig 
335c59d87c4SChristoph Hellwig 	/*
336c59d87c4SChristoph Hellwig 	 * With unlink, the VFS makes the dentry "negative": no inode,
337c59d87c4SChristoph Hellwig 	 * but still hashed. This is incompatible with case-insensitive
338c59d87c4SChristoph Hellwig 	 * mode, so invalidate (unhash) the dentry in CI-mode.
339c59d87c4SChristoph Hellwig 	 */
340c59d87c4SChristoph Hellwig 	if (xfs_sb_version_hasasciici(&XFS_M(dir->i_sb)->m_sb))
341c59d87c4SChristoph Hellwig 		d_invalidate(dentry);
342c59d87c4SChristoph Hellwig 	return 0;
343c59d87c4SChristoph Hellwig }
344c59d87c4SChristoph Hellwig 
345c59d87c4SChristoph Hellwig STATIC int
346c59d87c4SChristoph Hellwig xfs_vn_symlink(
347c59d87c4SChristoph Hellwig 	struct inode	*dir,
348c59d87c4SChristoph Hellwig 	struct dentry	*dentry,
349c59d87c4SChristoph Hellwig 	const char	*symname)
350c59d87c4SChristoph Hellwig {
351c59d87c4SChristoph Hellwig 	struct inode	*inode;
352c59d87c4SChristoph Hellwig 	struct xfs_inode *cip = NULL;
353c59d87c4SChristoph Hellwig 	struct xfs_name	name;
354c59d87c4SChristoph Hellwig 	int		error;
355576b1d67SAl Viro 	umode_t		mode;
356c59d87c4SChristoph Hellwig 
357c59d87c4SChristoph Hellwig 	mode = S_IFLNK |
358c59d87c4SChristoph Hellwig 		(irix_symlink_mode ? 0777 & ~current_umask() : S_IRWXUGO);
3590cb97766SDave Chinner 	xfs_dentry_to_name(&name, dentry, mode);
360c59d87c4SChristoph Hellwig 
361c59d87c4SChristoph Hellwig 	error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip);
362c59d87c4SChristoph Hellwig 	if (unlikely(error))
363c59d87c4SChristoph Hellwig 		goto out;
364c59d87c4SChristoph Hellwig 
365c59d87c4SChristoph Hellwig 	inode = VFS_I(cip);
366c59d87c4SChristoph Hellwig 
367c59d87c4SChristoph Hellwig 	error = xfs_init_security(inode, dir, &dentry->d_name);
368c59d87c4SChristoph Hellwig 	if (unlikely(error))
369c59d87c4SChristoph Hellwig 		goto out_cleanup_inode;
370c59d87c4SChristoph Hellwig 
371c59d87c4SChristoph Hellwig 	d_instantiate(dentry, inode);
372c59d87c4SChristoph Hellwig 	return 0;
373c59d87c4SChristoph Hellwig 
374c59d87c4SChristoph Hellwig  out_cleanup_inode:
375c59d87c4SChristoph Hellwig 	xfs_cleanup_inode(dir, inode, dentry);
376*d540e43bSBrian Foster 	iput(inode);
377c59d87c4SChristoph Hellwig  out:
378c59d87c4SChristoph Hellwig 	return -error;
379c59d87c4SChristoph Hellwig }
380c59d87c4SChristoph Hellwig 
381c59d87c4SChristoph Hellwig STATIC int
382c59d87c4SChristoph Hellwig xfs_vn_rename(
383c59d87c4SChristoph Hellwig 	struct inode	*odir,
384c59d87c4SChristoph Hellwig 	struct dentry	*odentry,
385c59d87c4SChristoph Hellwig 	struct inode	*ndir,
386c59d87c4SChristoph Hellwig 	struct dentry	*ndentry)
387c59d87c4SChristoph Hellwig {
388c59d87c4SChristoph Hellwig 	struct inode	*new_inode = ndentry->d_inode;
389c59d87c4SChristoph Hellwig 	struct xfs_name	oname;
390c59d87c4SChristoph Hellwig 	struct xfs_name	nname;
391c59d87c4SChristoph Hellwig 
3920cb97766SDave Chinner 	xfs_dentry_to_name(&oname, odentry, 0);
3930cb97766SDave Chinner 	xfs_dentry_to_name(&nname, ndentry, odentry->d_inode->i_mode);
394c59d87c4SChristoph Hellwig 
395c59d87c4SChristoph Hellwig 	return -xfs_rename(XFS_I(odir), &oname, XFS_I(odentry->d_inode),
396c59d87c4SChristoph Hellwig 			   XFS_I(ndir), &nname, new_inode ?
397c59d87c4SChristoph Hellwig 						XFS_I(new_inode) : NULL);
398c59d87c4SChristoph Hellwig }
399c59d87c4SChristoph Hellwig 
400c59d87c4SChristoph Hellwig /*
401c59d87c4SChristoph Hellwig  * careful here - this function can get called recursively, so
402c59d87c4SChristoph Hellwig  * we need to be very careful about how much stack we use.
403c59d87c4SChristoph Hellwig  * uio is kmalloced for this reason...
404c59d87c4SChristoph Hellwig  */
405c59d87c4SChristoph Hellwig STATIC void *
406c59d87c4SChristoph Hellwig xfs_vn_follow_link(
407c59d87c4SChristoph Hellwig 	struct dentry		*dentry,
408c59d87c4SChristoph Hellwig 	struct nameidata	*nd)
409c59d87c4SChristoph Hellwig {
410c59d87c4SChristoph Hellwig 	char			*link;
411c59d87c4SChristoph Hellwig 	int			error = -ENOMEM;
412c59d87c4SChristoph Hellwig 
413c59d87c4SChristoph Hellwig 	link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
414c59d87c4SChristoph Hellwig 	if (!link)
415c59d87c4SChristoph Hellwig 		goto out_err;
416c59d87c4SChristoph Hellwig 
417c59d87c4SChristoph Hellwig 	error = -xfs_readlink(XFS_I(dentry->d_inode), link);
418c59d87c4SChristoph Hellwig 	if (unlikely(error))
419c59d87c4SChristoph Hellwig 		goto out_kfree;
420c59d87c4SChristoph Hellwig 
421c59d87c4SChristoph Hellwig 	nd_set_link(nd, link);
422c59d87c4SChristoph Hellwig 	return NULL;
423c59d87c4SChristoph Hellwig 
424c59d87c4SChristoph Hellwig  out_kfree:
425c59d87c4SChristoph Hellwig 	kfree(link);
426c59d87c4SChristoph Hellwig  out_err:
427c59d87c4SChristoph Hellwig 	nd_set_link(nd, ERR_PTR(error));
428c59d87c4SChristoph Hellwig 	return NULL;
429c59d87c4SChristoph Hellwig }
430c59d87c4SChristoph Hellwig 
431c59d87c4SChristoph Hellwig STATIC int
432c59d87c4SChristoph Hellwig xfs_vn_getattr(
433c59d87c4SChristoph Hellwig 	struct vfsmount		*mnt,
434c59d87c4SChristoph Hellwig 	struct dentry		*dentry,
435c59d87c4SChristoph Hellwig 	struct kstat		*stat)
436c59d87c4SChristoph Hellwig {
437c59d87c4SChristoph Hellwig 	struct inode		*inode = dentry->d_inode;
438c59d87c4SChristoph Hellwig 	struct xfs_inode	*ip = XFS_I(inode);
439c59d87c4SChristoph Hellwig 	struct xfs_mount	*mp = ip->i_mount;
440c59d87c4SChristoph Hellwig 
441c59d87c4SChristoph Hellwig 	trace_xfs_getattr(ip);
442c59d87c4SChristoph Hellwig 
443c59d87c4SChristoph Hellwig 	if (XFS_FORCED_SHUTDOWN(mp))
444ed32201eSMitsuo Hayasaka 		return -XFS_ERROR(EIO);
445c59d87c4SChristoph Hellwig 
446c59d87c4SChristoph Hellwig 	stat->size = XFS_ISIZE(ip);
447c59d87c4SChristoph Hellwig 	stat->dev = inode->i_sb->s_dev;
448c59d87c4SChristoph Hellwig 	stat->mode = ip->i_d.di_mode;
449c59d87c4SChristoph Hellwig 	stat->nlink = ip->i_d.di_nlink;
4507aab1b28SDwight Engen 	stat->uid = inode->i_uid;
4517aab1b28SDwight Engen 	stat->gid = inode->i_gid;
452c59d87c4SChristoph Hellwig 	stat->ino = ip->i_ino;
453c59d87c4SChristoph Hellwig 	stat->atime = inode->i_atime;
454c59d87c4SChristoph Hellwig 	stat->mtime = inode->i_mtime;
455c59d87c4SChristoph Hellwig 	stat->ctime = inode->i_ctime;
456c59d87c4SChristoph Hellwig 	stat->blocks =
457c59d87c4SChristoph Hellwig 		XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks);
458c59d87c4SChristoph Hellwig 
459c59d87c4SChristoph Hellwig 
460c59d87c4SChristoph Hellwig 	switch (inode->i_mode & S_IFMT) {
461c59d87c4SChristoph Hellwig 	case S_IFBLK:
462c59d87c4SChristoph Hellwig 	case S_IFCHR:
463c59d87c4SChristoph Hellwig 		stat->blksize = BLKDEV_IOSIZE;
464c59d87c4SChristoph Hellwig 		stat->rdev = MKDEV(sysv_major(ip->i_df.if_u2.if_rdev) & 0x1ff,
465c59d87c4SChristoph Hellwig 				   sysv_minor(ip->i_df.if_u2.if_rdev));
466c59d87c4SChristoph Hellwig 		break;
467c59d87c4SChristoph Hellwig 	default:
468c59d87c4SChristoph Hellwig 		if (XFS_IS_REALTIME_INODE(ip)) {
469c59d87c4SChristoph Hellwig 			/*
470c59d87c4SChristoph Hellwig 			 * If the file blocks are being allocated from a
471c59d87c4SChristoph Hellwig 			 * realtime volume, then return the inode's realtime
472c59d87c4SChristoph Hellwig 			 * extent size or the realtime volume's extent size.
473c59d87c4SChristoph Hellwig 			 */
474c59d87c4SChristoph Hellwig 			stat->blksize =
475c59d87c4SChristoph Hellwig 				xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog;
476c59d87c4SChristoph Hellwig 		} else
477c59d87c4SChristoph Hellwig 			stat->blksize = xfs_preferred_iosize(mp);
478c59d87c4SChristoph Hellwig 		stat->rdev = 0;
479c59d87c4SChristoph Hellwig 		break;
480c59d87c4SChristoph Hellwig 	}
481c59d87c4SChristoph Hellwig 
482c59d87c4SChristoph Hellwig 	return 0;
483c59d87c4SChristoph Hellwig }
484c59d87c4SChristoph Hellwig 
48556c19e89SDave Chinner static void
48656c19e89SDave Chinner xfs_setattr_mode(
48756c19e89SDave Chinner 	struct xfs_inode	*ip,
48856c19e89SDave Chinner 	struct iattr		*iattr)
48956c19e89SDave Chinner {
49056c19e89SDave Chinner 	struct inode		*inode = VFS_I(ip);
49156c19e89SDave Chinner 	umode_t			mode = iattr->ia_mode;
49256c19e89SDave Chinner 
49356c19e89SDave Chinner 	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
49456c19e89SDave Chinner 
49556c19e89SDave Chinner 	ip->i_d.di_mode &= S_IFMT;
49656c19e89SDave Chinner 	ip->i_d.di_mode |= mode & ~S_IFMT;
49756c19e89SDave Chinner 
49856c19e89SDave Chinner 	inode->i_mode &= S_IFMT;
49956c19e89SDave Chinner 	inode->i_mode |= mode & ~S_IFMT;
50056c19e89SDave Chinner }
50156c19e89SDave Chinner 
502c91c46c1SChristoph Hellwig static void
503c91c46c1SChristoph Hellwig xfs_setattr_time(
504c91c46c1SChristoph Hellwig 	struct xfs_inode	*ip,
505c91c46c1SChristoph Hellwig 	struct iattr		*iattr)
506c91c46c1SChristoph Hellwig {
507c91c46c1SChristoph Hellwig 	struct inode		*inode = VFS_I(ip);
508c91c46c1SChristoph Hellwig 
509c91c46c1SChristoph Hellwig 	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
510c91c46c1SChristoph Hellwig 
511c91c46c1SChristoph Hellwig 	if (iattr->ia_valid & ATTR_ATIME) {
512c91c46c1SChristoph Hellwig 		inode->i_atime = iattr->ia_atime;
513c91c46c1SChristoph Hellwig 		ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec;
514c91c46c1SChristoph Hellwig 		ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec;
515c91c46c1SChristoph Hellwig 	}
516c91c46c1SChristoph Hellwig 	if (iattr->ia_valid & ATTR_CTIME) {
517c91c46c1SChristoph Hellwig 		inode->i_ctime = iattr->ia_ctime;
518c91c46c1SChristoph Hellwig 		ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
519c91c46c1SChristoph Hellwig 		ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec;
520c91c46c1SChristoph Hellwig 	}
521c91c46c1SChristoph Hellwig 	if (iattr->ia_valid & ATTR_MTIME) {
522c91c46c1SChristoph Hellwig 		inode->i_mtime = iattr->ia_mtime;
523c91c46c1SChristoph Hellwig 		ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec;
524c91c46c1SChristoph Hellwig 		ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec;
525c91c46c1SChristoph Hellwig 	}
526c91c46c1SChristoph Hellwig }
527c91c46c1SChristoph Hellwig 
528c59d87c4SChristoph Hellwig int
529c59d87c4SChristoph Hellwig xfs_setattr_nonsize(
530c59d87c4SChristoph Hellwig 	struct xfs_inode	*ip,
531c59d87c4SChristoph Hellwig 	struct iattr		*iattr,
532c59d87c4SChristoph Hellwig 	int			flags)
533c59d87c4SChristoph Hellwig {
534c59d87c4SChristoph Hellwig 	xfs_mount_t		*mp = ip->i_mount;
535c59d87c4SChristoph Hellwig 	struct inode		*inode = VFS_I(ip);
536c59d87c4SChristoph Hellwig 	int			mask = iattr->ia_valid;
537c59d87c4SChristoph Hellwig 	xfs_trans_t		*tp;
538c59d87c4SChristoph Hellwig 	int			error;
5397aab1b28SDwight Engen 	kuid_t			uid = GLOBAL_ROOT_UID, iuid = GLOBAL_ROOT_UID;
5407aab1b28SDwight Engen 	kgid_t			gid = GLOBAL_ROOT_GID, igid = GLOBAL_ROOT_GID;
541c59d87c4SChristoph Hellwig 	struct xfs_dquot	*udqp = NULL, *gdqp = NULL;
542c59d87c4SChristoph Hellwig 	struct xfs_dquot	*olddquot1 = NULL, *olddquot2 = NULL;
543c59d87c4SChristoph Hellwig 
544c59d87c4SChristoph Hellwig 	trace_xfs_setattr(ip);
545c59d87c4SChristoph Hellwig 
54642c49d7fSCarlos Maiolino 	/* If acls are being inherited, we already have this checked */
54742c49d7fSCarlos Maiolino 	if (!(flags & XFS_ATTR_NOACL)) {
548c59d87c4SChristoph Hellwig 		if (mp->m_flags & XFS_MOUNT_RDONLY)
549c59d87c4SChristoph Hellwig 			return XFS_ERROR(EROFS);
550c59d87c4SChristoph Hellwig 
551c59d87c4SChristoph Hellwig 		if (XFS_FORCED_SHUTDOWN(mp))
552c59d87c4SChristoph Hellwig 			return XFS_ERROR(EIO);
553c59d87c4SChristoph Hellwig 
554c59d87c4SChristoph Hellwig 		error = -inode_change_ok(inode, iattr);
555c59d87c4SChristoph Hellwig 		if (error)
556c59d87c4SChristoph Hellwig 			return XFS_ERROR(error);
55742c49d7fSCarlos Maiolino 	}
558c59d87c4SChristoph Hellwig 
559c59d87c4SChristoph Hellwig 	ASSERT((mask & ATTR_SIZE) == 0);
560c59d87c4SChristoph Hellwig 
561c59d87c4SChristoph Hellwig 	/*
562c59d87c4SChristoph Hellwig 	 * If disk quotas is on, we make sure that the dquots do exist on disk,
563c59d87c4SChristoph Hellwig 	 * before we start any other transactions. Trying to do this later
564c59d87c4SChristoph Hellwig 	 * is messy. We don't care to take a readlock to look at the ids
565c59d87c4SChristoph Hellwig 	 * in inode here, because we can't hold it across the trans_reserve.
566c59d87c4SChristoph Hellwig 	 * If the IDs do change before we take the ilock, we're covered
567c59d87c4SChristoph Hellwig 	 * because the i_*dquot fields will get updated anyway.
568c59d87c4SChristoph Hellwig 	 */
569c59d87c4SChristoph Hellwig 	if (XFS_IS_QUOTA_ON(mp) && (mask & (ATTR_UID|ATTR_GID))) {
570c59d87c4SChristoph Hellwig 		uint	qflags = 0;
571c59d87c4SChristoph Hellwig 
572c59d87c4SChristoph Hellwig 		if ((mask & ATTR_UID) && XFS_IS_UQUOTA_ON(mp)) {
573c59d87c4SChristoph Hellwig 			uid = iattr->ia_uid;
574c59d87c4SChristoph Hellwig 			qflags |= XFS_QMOPT_UQUOTA;
575c59d87c4SChristoph Hellwig 		} else {
5767aab1b28SDwight Engen 			uid = inode->i_uid;
577c59d87c4SChristoph Hellwig 		}
578c59d87c4SChristoph Hellwig 		if ((mask & ATTR_GID) && XFS_IS_GQUOTA_ON(mp)) {
579c59d87c4SChristoph Hellwig 			gid = iattr->ia_gid;
580c59d87c4SChristoph Hellwig 			qflags |= XFS_QMOPT_GQUOTA;
581c59d87c4SChristoph Hellwig 		}  else {
5827aab1b28SDwight Engen 			gid = inode->i_gid;
583c59d87c4SChristoph Hellwig 		}
584c59d87c4SChristoph Hellwig 
585c59d87c4SChristoph Hellwig 		/*
586c59d87c4SChristoph Hellwig 		 * We take a reference when we initialize udqp and gdqp,
587c59d87c4SChristoph Hellwig 		 * so it is important that we never blindly double trip on
588c59d87c4SChristoph Hellwig 		 * the same variable. See xfs_create() for an example.
589c59d87c4SChristoph Hellwig 		 */
590c59d87c4SChristoph Hellwig 		ASSERT(udqp == NULL);
591c59d87c4SChristoph Hellwig 		ASSERT(gdqp == NULL);
5927aab1b28SDwight Engen 		error = xfs_qm_vop_dqalloc(ip, xfs_kuid_to_uid(uid),
5937aab1b28SDwight Engen 					   xfs_kgid_to_gid(gid),
5947aab1b28SDwight Engen 					   xfs_get_projid(ip),
59592f8ff73SChandra Seetharaman 					   qflags, &udqp, &gdqp, NULL);
596c59d87c4SChristoph Hellwig 		if (error)
597c59d87c4SChristoph Hellwig 			return error;
598c59d87c4SChristoph Hellwig 	}
599c59d87c4SChristoph Hellwig 
600c59d87c4SChristoph Hellwig 	tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE);
6013d3c8b52SJie Liu 	error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0);
602c59d87c4SChristoph Hellwig 	if (error)
603c59d87c4SChristoph Hellwig 		goto out_dqrele;
604c59d87c4SChristoph Hellwig 
605c59d87c4SChristoph Hellwig 	xfs_ilock(ip, XFS_ILOCK_EXCL);
606c59d87c4SChristoph Hellwig 
607c59d87c4SChristoph Hellwig 	/*
608c59d87c4SChristoph Hellwig 	 * Change file ownership.  Must be the owner or privileged.
609c59d87c4SChristoph Hellwig 	 */
610c59d87c4SChristoph Hellwig 	if (mask & (ATTR_UID|ATTR_GID)) {
611c59d87c4SChristoph Hellwig 		/*
612c59d87c4SChristoph Hellwig 		 * These IDs could have changed since we last looked at them.
613c59d87c4SChristoph Hellwig 		 * But, we're assured that if the ownership did change
614c59d87c4SChristoph Hellwig 		 * while we didn't have the inode locked, inode's dquot(s)
615c59d87c4SChristoph Hellwig 		 * would have changed also.
616c59d87c4SChristoph Hellwig 		 */
6177aab1b28SDwight Engen 		iuid = inode->i_uid;
6187aab1b28SDwight Engen 		igid = inode->i_gid;
619c59d87c4SChristoph Hellwig 		gid = (mask & ATTR_GID) ? iattr->ia_gid : igid;
620c59d87c4SChristoph Hellwig 		uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid;
621c59d87c4SChristoph Hellwig 
622c59d87c4SChristoph Hellwig 		/*
623c59d87c4SChristoph Hellwig 		 * Do a quota reservation only if uid/gid is actually
624c59d87c4SChristoph Hellwig 		 * going to change.
625c59d87c4SChristoph Hellwig 		 */
626c59d87c4SChristoph Hellwig 		if (XFS_IS_QUOTA_RUNNING(mp) &&
6277aab1b28SDwight Engen 		    ((XFS_IS_UQUOTA_ON(mp) && !uid_eq(iuid, uid)) ||
6287aab1b28SDwight Engen 		     (XFS_IS_GQUOTA_ON(mp) && !gid_eq(igid, gid)))) {
629c59d87c4SChristoph Hellwig 			ASSERT(tp);
630c59d87c4SChristoph Hellwig 			error = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
63192f8ff73SChandra Seetharaman 						NULL, capable(CAP_FOWNER) ?
632c59d87c4SChristoph Hellwig 						XFS_QMOPT_FORCE_RES : 0);
633c59d87c4SChristoph Hellwig 			if (error)	/* out of quota */
634c59d87c4SChristoph Hellwig 				goto out_trans_cancel;
635c59d87c4SChristoph Hellwig 		}
636c59d87c4SChristoph Hellwig 	}
637c59d87c4SChristoph Hellwig 
638ddc3415aSChristoph Hellwig 	xfs_trans_ijoin(tp, ip, 0);
639c59d87c4SChristoph Hellwig 
640c59d87c4SChristoph Hellwig 	/*
641c59d87c4SChristoph Hellwig 	 * Change file ownership.  Must be the owner or privileged.
642c59d87c4SChristoph Hellwig 	 */
643c59d87c4SChristoph Hellwig 	if (mask & (ATTR_UID|ATTR_GID)) {
644c59d87c4SChristoph Hellwig 		/*
645c59d87c4SChristoph Hellwig 		 * CAP_FSETID overrides the following restrictions:
646c59d87c4SChristoph Hellwig 		 *
647c59d87c4SChristoph Hellwig 		 * The set-user-ID and set-group-ID bits of a file will be
648c59d87c4SChristoph Hellwig 		 * cleared upon successful return from chown()
649c59d87c4SChristoph Hellwig 		 */
650c59d87c4SChristoph Hellwig 		if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) &&
651c59d87c4SChristoph Hellwig 		    !capable(CAP_FSETID))
652c59d87c4SChristoph Hellwig 			ip->i_d.di_mode &= ~(S_ISUID|S_ISGID);
653c59d87c4SChristoph Hellwig 
654c59d87c4SChristoph Hellwig 		/*
655c59d87c4SChristoph Hellwig 		 * Change the ownerships and register quota modifications
656c59d87c4SChristoph Hellwig 		 * in the transaction.
657c59d87c4SChristoph Hellwig 		 */
6587aab1b28SDwight Engen 		if (!uid_eq(iuid, uid)) {
659c59d87c4SChristoph Hellwig 			if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_UQUOTA_ON(mp)) {
660c59d87c4SChristoph Hellwig 				ASSERT(mask & ATTR_UID);
661c59d87c4SChristoph Hellwig 				ASSERT(udqp);
662c59d87c4SChristoph Hellwig 				olddquot1 = xfs_qm_vop_chown(tp, ip,
663c59d87c4SChristoph Hellwig 							&ip->i_udquot, udqp);
664c59d87c4SChristoph Hellwig 			}
6657aab1b28SDwight Engen 			ip->i_d.di_uid = xfs_kuid_to_uid(uid);
666c59d87c4SChristoph Hellwig 			inode->i_uid = uid;
667c59d87c4SChristoph Hellwig 		}
6687aab1b28SDwight Engen 		if (!gid_eq(igid, gid)) {
669c59d87c4SChristoph Hellwig 			if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) {
6705a01dd54SJie Liu 				ASSERT(xfs_sb_version_has_pquotino(&mp->m_sb) ||
6715a01dd54SJie Liu 				       !XFS_IS_PQUOTA_ON(mp));
672c59d87c4SChristoph Hellwig 				ASSERT(mask & ATTR_GID);
673c59d87c4SChristoph Hellwig 				ASSERT(gdqp);
674c59d87c4SChristoph Hellwig 				olddquot2 = xfs_qm_vop_chown(tp, ip,
675c59d87c4SChristoph Hellwig 							&ip->i_gdquot, gdqp);
676c59d87c4SChristoph Hellwig 			}
6777aab1b28SDwight Engen 			ip->i_d.di_gid = xfs_kgid_to_gid(gid);
678c59d87c4SChristoph Hellwig 			inode->i_gid = gid;
679c59d87c4SChristoph Hellwig 		}
680c59d87c4SChristoph Hellwig 	}
681c59d87c4SChristoph Hellwig 
68256c19e89SDave Chinner 	if (mask & ATTR_MODE)
6830c3d88dfSChristoph Hellwig 		xfs_setattr_mode(ip, iattr);
684c91c46c1SChristoph Hellwig 	if (mask & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME))
685c91c46c1SChristoph Hellwig 		xfs_setattr_time(ip, iattr);
686c59d87c4SChristoph Hellwig 
687c59d87c4SChristoph Hellwig 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
688c59d87c4SChristoph Hellwig 
689c59d87c4SChristoph Hellwig 	XFS_STATS_INC(xs_ig_attrchg);
690c59d87c4SChristoph Hellwig 
691c59d87c4SChristoph Hellwig 	if (mp->m_flags & XFS_MOUNT_WSYNC)
692c59d87c4SChristoph Hellwig 		xfs_trans_set_sync(tp);
693c59d87c4SChristoph Hellwig 	error = xfs_trans_commit(tp, 0);
694c59d87c4SChristoph Hellwig 
695c59d87c4SChristoph Hellwig 	xfs_iunlock(ip, XFS_ILOCK_EXCL);
696c59d87c4SChristoph Hellwig 
697c59d87c4SChristoph Hellwig 	/*
698c59d87c4SChristoph Hellwig 	 * Release any dquot(s) the inode had kept before chown.
699c59d87c4SChristoph Hellwig 	 */
700c59d87c4SChristoph Hellwig 	xfs_qm_dqrele(olddquot1);
701c59d87c4SChristoph Hellwig 	xfs_qm_dqrele(olddquot2);
702c59d87c4SChristoph Hellwig 	xfs_qm_dqrele(udqp);
703c59d87c4SChristoph Hellwig 	xfs_qm_dqrele(gdqp);
704c59d87c4SChristoph Hellwig 
705c59d87c4SChristoph Hellwig 	if (error)
706c59d87c4SChristoph Hellwig 		return XFS_ERROR(error);
707c59d87c4SChristoph Hellwig 
708c59d87c4SChristoph Hellwig 	/*
709c59d87c4SChristoph Hellwig 	 * XXX(hch): Updating the ACL entries is not atomic vs the i_mode
710c59d87c4SChristoph Hellwig 	 * 	     update.  We could avoid this with linked transactions
711c59d87c4SChristoph Hellwig 	 * 	     and passing down the transaction pointer all the way
712c59d87c4SChristoph Hellwig 	 *	     to attr_set.  No previous user of the generic
713c59d87c4SChristoph Hellwig 	 * 	     Posix ACL code seems to care about this issue either.
714c59d87c4SChristoph Hellwig 	 */
715c59d87c4SChristoph Hellwig 	if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) {
7162401dc29SChristoph Hellwig 		error = -posix_acl_chmod(inode, inode->i_mode);
717c59d87c4SChristoph Hellwig 		if (error)
718c59d87c4SChristoph Hellwig 			return XFS_ERROR(error);
719c59d87c4SChristoph Hellwig 	}
720c59d87c4SChristoph Hellwig 
721c59d87c4SChristoph Hellwig 	return 0;
722c59d87c4SChristoph Hellwig 
723c59d87c4SChristoph Hellwig out_trans_cancel:
724c59d87c4SChristoph Hellwig 	xfs_trans_cancel(tp, 0);
725c59d87c4SChristoph Hellwig 	xfs_iunlock(ip, XFS_ILOCK_EXCL);
726c59d87c4SChristoph Hellwig out_dqrele:
727c59d87c4SChristoph Hellwig 	xfs_qm_dqrele(udqp);
728c59d87c4SChristoph Hellwig 	xfs_qm_dqrele(gdqp);
729c59d87c4SChristoph Hellwig 	return error;
730c59d87c4SChristoph Hellwig }
731c59d87c4SChristoph Hellwig 
732c59d87c4SChristoph Hellwig /*
733c59d87c4SChristoph Hellwig  * Truncate file.  Must have write permission and not be a directory.
734c59d87c4SChristoph Hellwig  */
735c59d87c4SChristoph Hellwig int
736c59d87c4SChristoph Hellwig xfs_setattr_size(
737c59d87c4SChristoph Hellwig 	struct xfs_inode	*ip,
73876ca4c23SChristoph Hellwig 	struct iattr		*iattr)
739c59d87c4SChristoph Hellwig {
740c59d87c4SChristoph Hellwig 	struct xfs_mount	*mp = ip->i_mount;
741c59d87c4SChristoph Hellwig 	struct inode		*inode = VFS_I(ip);
742673e8e59SChristoph Hellwig 	xfs_off_t		oldsize, newsize;
743c59d87c4SChristoph Hellwig 	struct xfs_trans	*tp;
744c59d87c4SChristoph Hellwig 	int			error;
745f38996f5SChristoph Hellwig 	uint			lock_flags = 0;
746c59d87c4SChristoph Hellwig 	uint			commit_flags = 0;
747c59d87c4SChristoph Hellwig 
748c59d87c4SChristoph Hellwig 	trace_xfs_setattr(ip);
749c59d87c4SChristoph Hellwig 
750c59d87c4SChristoph Hellwig 	if (mp->m_flags & XFS_MOUNT_RDONLY)
751c59d87c4SChristoph Hellwig 		return XFS_ERROR(EROFS);
752c59d87c4SChristoph Hellwig 
753c59d87c4SChristoph Hellwig 	if (XFS_FORCED_SHUTDOWN(mp))
754c59d87c4SChristoph Hellwig 		return XFS_ERROR(EIO);
755c59d87c4SChristoph Hellwig 
756c59d87c4SChristoph Hellwig 	error = -inode_change_ok(inode, iattr);
757c59d87c4SChristoph Hellwig 	if (error)
758c59d87c4SChristoph Hellwig 		return XFS_ERROR(error);
759c59d87c4SChristoph Hellwig 
76076ca4c23SChristoph Hellwig 	ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
761c59d87c4SChristoph Hellwig 	ASSERT(S_ISREG(ip->i_d.di_mode));
762fe60a8a0SChristoph Hellwig 	ASSERT((iattr->ia_valid & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
76356c19e89SDave Chinner 		ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
764c59d87c4SChristoph Hellwig 
765ce7ae151SChristoph Hellwig 	oldsize = inode->i_size;
766673e8e59SChristoph Hellwig 	newsize = iattr->ia_size;
767673e8e59SChristoph Hellwig 
768c59d87c4SChristoph Hellwig 	/*
769c59d87c4SChristoph Hellwig 	 * Short circuit the truncate case for zero length files.
770c59d87c4SChristoph Hellwig 	 */
771673e8e59SChristoph Hellwig 	if (newsize == 0 && oldsize == 0 && ip->i_d.di_nextents == 0) {
772fe60a8a0SChristoph Hellwig 		if (!(iattr->ia_valid & (ATTR_CTIME|ATTR_MTIME)))
77376ca4c23SChristoph Hellwig 			return 0;
774c59d87c4SChristoph Hellwig 
775c59d87c4SChristoph Hellwig 		/*
776c59d87c4SChristoph Hellwig 		 * Use the regular setattr path to update the timestamps.
777c59d87c4SChristoph Hellwig 		 */
778c59d87c4SChristoph Hellwig 		iattr->ia_valid &= ~ATTR_SIZE;
779c59d87c4SChristoph Hellwig 		return xfs_setattr_nonsize(ip, iattr, 0);
780c59d87c4SChristoph Hellwig 	}
781c59d87c4SChristoph Hellwig 
782c59d87c4SChristoph Hellwig 	/*
783c59d87c4SChristoph Hellwig 	 * Make sure that the dquots are attached to the inode.
784c59d87c4SChristoph Hellwig 	 */
785f38996f5SChristoph Hellwig 	error = xfs_qm_dqattach(ip, 0);
786c59d87c4SChristoph Hellwig 	if (error)
78776ca4c23SChristoph Hellwig 		return error;
788c59d87c4SChristoph Hellwig 
789c59d87c4SChristoph Hellwig 	/*
790c59d87c4SChristoph Hellwig 	 * Now we can make the changes.  Before we join the inode to the
791c59d87c4SChristoph Hellwig 	 * transaction, take care of the part of the truncation that must be
792c59d87c4SChristoph Hellwig 	 * done without the inode lock.  This needs to be done before joining
793c59d87c4SChristoph Hellwig 	 * the inode to the transaction, because the inode cannot be unlocked
794c59d87c4SChristoph Hellwig 	 * once it is a part of the transaction.
795c59d87c4SChristoph Hellwig 	 */
796673e8e59SChristoph Hellwig 	if (newsize > oldsize) {
797c59d87c4SChristoph Hellwig 		/*
798c59d87c4SChristoph Hellwig 		 * Do the first part of growing a file: zero any data in the
799c59d87c4SChristoph Hellwig 		 * last block that is beyond the old EOF.  We need to do this
800c59d87c4SChristoph Hellwig 		 * before the inode is joined to the transaction to modify
801c59d87c4SChristoph Hellwig 		 * i_size.
802c59d87c4SChristoph Hellwig 		 */
803673e8e59SChristoph Hellwig 		error = xfs_zero_eof(ip, newsize, oldsize);
804c59d87c4SChristoph Hellwig 		if (error)
80576ca4c23SChristoph Hellwig 			return error;
806c59d87c4SChristoph Hellwig 	}
807c59d87c4SChristoph Hellwig 
808c59d87c4SChristoph Hellwig 	/*
809c59d87c4SChristoph Hellwig 	 * We are going to log the inode size change in this transaction so
810c59d87c4SChristoph Hellwig 	 * any previous writes that are beyond the on disk EOF and the new
811c59d87c4SChristoph Hellwig 	 * EOF that have not been written out need to be written here.  If we
812c59d87c4SChristoph Hellwig 	 * do not write the data out, we expose ourselves to the null files
813c59d87c4SChristoph Hellwig 	 * problem.
814c59d87c4SChristoph Hellwig 	 *
815c59d87c4SChristoph Hellwig 	 * Only flush from the on disk size to the smaller of the in memory
816c59d87c4SChristoph Hellwig 	 * file size or the new size as that's the range we really care about
817c59d87c4SChristoph Hellwig 	 * here and prevents waiting for other data not within the range we
818c59d87c4SChristoph Hellwig 	 * care about here.
819c59d87c4SChristoph Hellwig 	 */
820673e8e59SChristoph Hellwig 	if (oldsize != ip->i_d.di_size && newsize > ip->i_d.di_size) {
8214bc1ea6bSDave Chinner 		error = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
8224bc1ea6bSDave Chinner 						      ip->i_d.di_size, newsize);
823c59d87c4SChristoph Hellwig 		if (error)
82476ca4c23SChristoph Hellwig 			return error;
825c59d87c4SChristoph Hellwig 	}
826c59d87c4SChristoph Hellwig 
827c59d87c4SChristoph Hellwig 	/*
8284a06fd26SChristoph Hellwig 	 * Wait for all direct I/O to complete.
829c59d87c4SChristoph Hellwig 	 */
8304a06fd26SChristoph Hellwig 	inode_dio_wait(inode);
831c59d87c4SChristoph Hellwig 
832673e8e59SChristoph Hellwig 	error = -block_truncate_page(inode->i_mapping, newsize, xfs_get_blocks);
833c59d87c4SChristoph Hellwig 	if (error)
83476ca4c23SChristoph Hellwig 		return error;
835c59d87c4SChristoph Hellwig 
836c59d87c4SChristoph Hellwig 	tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE);
8373d3c8b52SJie Liu 	error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
838c59d87c4SChristoph Hellwig 	if (error)
839c59d87c4SChristoph Hellwig 		goto out_trans_cancel;
840c59d87c4SChristoph Hellwig 
841673e8e59SChristoph Hellwig 	truncate_setsize(inode, newsize);
842c59d87c4SChristoph Hellwig 
843c59d87c4SChristoph Hellwig 	commit_flags = XFS_TRANS_RELEASE_LOG_RES;
844c59d87c4SChristoph Hellwig 	lock_flags |= XFS_ILOCK_EXCL;
845c59d87c4SChristoph Hellwig 
846c59d87c4SChristoph Hellwig 	xfs_ilock(ip, XFS_ILOCK_EXCL);
847c59d87c4SChristoph Hellwig 
848ddc3415aSChristoph Hellwig 	xfs_trans_ijoin(tp, ip, 0);
849c59d87c4SChristoph Hellwig 
850c59d87c4SChristoph Hellwig 	/*
851c59d87c4SChristoph Hellwig 	 * Only change the c/mtime if we are changing the size or we are
852c59d87c4SChristoph Hellwig 	 * explicitly asked to change it.  This handles the semantic difference
853c59d87c4SChristoph Hellwig 	 * between truncate() and ftruncate() as implemented in the VFS.
854c59d87c4SChristoph Hellwig 	 *
855c59d87c4SChristoph Hellwig 	 * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a
856c59d87c4SChristoph Hellwig 	 * special case where we need to update the times despite not having
857c59d87c4SChristoph Hellwig 	 * these flags set.  For all other operations the VFS set these flags
858c59d87c4SChristoph Hellwig 	 * explicitly if it wants a timestamp update.
859c59d87c4SChristoph Hellwig 	 */
860fe60a8a0SChristoph Hellwig 	if (newsize != oldsize &&
861fe60a8a0SChristoph Hellwig 	    !(iattr->ia_valid & (ATTR_CTIME | ATTR_MTIME))) {
862c59d87c4SChristoph Hellwig 		iattr->ia_ctime = iattr->ia_mtime =
863c59d87c4SChristoph Hellwig 			current_fs_time(inode->i_sb);
864fe60a8a0SChristoph Hellwig 		iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME;
865c59d87c4SChristoph Hellwig 	}
866c59d87c4SChristoph Hellwig 
867673e8e59SChristoph Hellwig 	/*
868673e8e59SChristoph Hellwig 	 * The first thing we do is set the size to new_size permanently on
869673e8e59SChristoph Hellwig 	 * disk.  This way we don't have to worry about anyone ever being able
870673e8e59SChristoph Hellwig 	 * to look at the data being freed even in the face of a crash.
871673e8e59SChristoph Hellwig 	 * What we're getting around here is the case where we free a block, it
872673e8e59SChristoph Hellwig 	 * is allocated to another file, it is written to, and then we crash.
873673e8e59SChristoph Hellwig 	 * If the new data gets written to the file but the log buffers
874673e8e59SChristoph Hellwig 	 * containing the free and reallocation don't, then we'd end up with
875673e8e59SChristoph Hellwig 	 * garbage in the blocks being freed.  As long as we make the new size
876673e8e59SChristoph Hellwig 	 * permanent before actually freeing any blocks it doesn't matter if
877673e8e59SChristoph Hellwig 	 * they get written to.
878673e8e59SChristoph Hellwig 	 */
879673e8e59SChristoph Hellwig 	ip->i_d.di_size = newsize;
880673e8e59SChristoph Hellwig 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
881673e8e59SChristoph Hellwig 
882673e8e59SChristoph Hellwig 	if (newsize <= oldsize) {
883673e8e59SChristoph Hellwig 		error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, newsize);
884c59d87c4SChristoph Hellwig 		if (error)
885c59d87c4SChristoph Hellwig 			goto out_trans_abort;
886c59d87c4SChristoph Hellwig 
887c59d87c4SChristoph Hellwig 		/*
888c59d87c4SChristoph Hellwig 		 * Truncated "down", so we're removing references to old data
889c59d87c4SChristoph Hellwig 		 * here - if we delay flushing for a long time, we expose
890c59d87c4SChristoph Hellwig 		 * ourselves unduly to the notorious NULL files problem.  So,
891c59d87c4SChristoph Hellwig 		 * we mark this inode and flush it when the file is closed,
892c59d87c4SChristoph Hellwig 		 * and do not wait the usual (long) time for writeout.
893c59d87c4SChristoph Hellwig 		 */
894c59d87c4SChristoph Hellwig 		xfs_iflags_set(ip, XFS_ITRUNCATED);
89527b52867SBrian Foster 
89627b52867SBrian Foster 		/* A truncate down always removes post-EOF blocks. */
89727b52867SBrian Foster 		xfs_inode_clear_eofblocks_tag(ip);
898c59d87c4SChristoph Hellwig 	}
899c59d87c4SChristoph Hellwig 
900fe60a8a0SChristoph Hellwig 	if (iattr->ia_valid & ATTR_MODE)
9010c3d88dfSChristoph Hellwig 		xfs_setattr_mode(ip, iattr);
902fe60a8a0SChristoph Hellwig 	if (iattr->ia_valid & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME))
903c91c46c1SChristoph Hellwig 		xfs_setattr_time(ip, iattr);
904c59d87c4SChristoph Hellwig 
905c59d87c4SChristoph Hellwig 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
906c59d87c4SChristoph Hellwig 
907c59d87c4SChristoph Hellwig 	XFS_STATS_INC(xs_ig_attrchg);
908c59d87c4SChristoph Hellwig 
909c59d87c4SChristoph Hellwig 	if (mp->m_flags & XFS_MOUNT_WSYNC)
910c59d87c4SChristoph Hellwig 		xfs_trans_set_sync(tp);
911c59d87c4SChristoph Hellwig 
912c59d87c4SChristoph Hellwig 	error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
913c59d87c4SChristoph Hellwig out_unlock:
914c59d87c4SChristoph Hellwig 	if (lock_flags)
915c59d87c4SChristoph Hellwig 		xfs_iunlock(ip, lock_flags);
916c59d87c4SChristoph Hellwig 	return error;
917c59d87c4SChristoph Hellwig 
918c59d87c4SChristoph Hellwig out_trans_abort:
919c59d87c4SChristoph Hellwig 	commit_flags |= XFS_TRANS_ABORT;
920c59d87c4SChristoph Hellwig out_trans_cancel:
921c59d87c4SChristoph Hellwig 	xfs_trans_cancel(tp, commit_flags);
922c59d87c4SChristoph Hellwig 	goto out_unlock;
923c59d87c4SChristoph Hellwig }
924c59d87c4SChristoph Hellwig 
925c59d87c4SChristoph Hellwig STATIC int
926c59d87c4SChristoph Hellwig xfs_vn_setattr(
927c59d87c4SChristoph Hellwig 	struct dentry		*dentry,
928c59d87c4SChristoph Hellwig 	struct iattr		*iattr)
929c59d87c4SChristoph Hellwig {
93076ca4c23SChristoph Hellwig 	struct xfs_inode	*ip = XFS_I(dentry->d_inode);
93176ca4c23SChristoph Hellwig 	int			error;
93276ca4c23SChristoph Hellwig 
93376ca4c23SChristoph Hellwig 	if (iattr->ia_valid & ATTR_SIZE) {
93476ca4c23SChristoph Hellwig 		xfs_ilock(ip, XFS_IOLOCK_EXCL);
93576ca4c23SChristoph Hellwig 		error = xfs_setattr_size(ip, iattr);
93676ca4c23SChristoph Hellwig 		xfs_iunlock(ip, XFS_IOLOCK_EXCL);
93776ca4c23SChristoph Hellwig 	} else {
93876ca4c23SChristoph Hellwig 		error = xfs_setattr_nonsize(ip, iattr, 0);
93976ca4c23SChristoph Hellwig 	}
94076ca4c23SChristoph Hellwig 
94176ca4c23SChristoph Hellwig 	return -error;
942c59d87c4SChristoph Hellwig }
943c59d87c4SChristoph Hellwig 
94469ff2826SChristoph Hellwig STATIC int
94569ff2826SChristoph Hellwig xfs_vn_update_time(
94669ff2826SChristoph Hellwig 	struct inode		*inode,
94769ff2826SChristoph Hellwig 	struct timespec		*now,
94869ff2826SChristoph Hellwig 	int			flags)
94969ff2826SChristoph Hellwig {
95069ff2826SChristoph Hellwig 	struct xfs_inode	*ip = XFS_I(inode);
95169ff2826SChristoph Hellwig 	struct xfs_mount	*mp = ip->i_mount;
95269ff2826SChristoph Hellwig 	struct xfs_trans	*tp;
95369ff2826SChristoph Hellwig 	int			error;
95469ff2826SChristoph Hellwig 
95569ff2826SChristoph Hellwig 	trace_xfs_update_time(ip);
95669ff2826SChristoph Hellwig 
95769ff2826SChristoph Hellwig 	tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS);
9583d3c8b52SJie Liu 	error = xfs_trans_reserve(tp, &M_RES(mp)->tr_fsyncts, 0, 0);
95969ff2826SChristoph Hellwig 	if (error) {
96069ff2826SChristoph Hellwig 		xfs_trans_cancel(tp, 0);
96169ff2826SChristoph Hellwig 		return -error;
96269ff2826SChristoph Hellwig 	}
96369ff2826SChristoph Hellwig 
96469ff2826SChristoph Hellwig 	xfs_ilock(ip, XFS_ILOCK_EXCL);
96569ff2826SChristoph Hellwig 	if (flags & S_CTIME) {
96669ff2826SChristoph Hellwig 		inode->i_ctime = *now;
96769ff2826SChristoph Hellwig 		ip->i_d.di_ctime.t_sec = (__int32_t)now->tv_sec;
96869ff2826SChristoph Hellwig 		ip->i_d.di_ctime.t_nsec = (__int32_t)now->tv_nsec;
96969ff2826SChristoph Hellwig 	}
97069ff2826SChristoph Hellwig 	if (flags & S_MTIME) {
97169ff2826SChristoph Hellwig 		inode->i_mtime = *now;
97269ff2826SChristoph Hellwig 		ip->i_d.di_mtime.t_sec = (__int32_t)now->tv_sec;
97369ff2826SChristoph Hellwig 		ip->i_d.di_mtime.t_nsec = (__int32_t)now->tv_nsec;
97469ff2826SChristoph Hellwig 	}
97569ff2826SChristoph Hellwig 	if (flags & S_ATIME) {
97669ff2826SChristoph Hellwig 		inode->i_atime = *now;
97769ff2826SChristoph Hellwig 		ip->i_d.di_atime.t_sec = (__int32_t)now->tv_sec;
97869ff2826SChristoph Hellwig 		ip->i_d.di_atime.t_nsec = (__int32_t)now->tv_nsec;
97969ff2826SChristoph Hellwig 	}
98069ff2826SChristoph Hellwig 	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
98169ff2826SChristoph Hellwig 	xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
98269ff2826SChristoph Hellwig 	return -xfs_trans_commit(tp, 0);
98369ff2826SChristoph Hellwig }
98469ff2826SChristoph Hellwig 
985c59d87c4SChristoph Hellwig #define XFS_FIEMAP_FLAGS	(FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR)
986c59d87c4SChristoph Hellwig 
987c59d87c4SChristoph Hellwig /*
988c59d87c4SChristoph Hellwig  * Call fiemap helper to fill in user data.
989c59d87c4SChristoph Hellwig  * Returns positive errors to xfs_getbmap.
990c59d87c4SChristoph Hellwig  */
991c59d87c4SChristoph Hellwig STATIC int
992c59d87c4SChristoph Hellwig xfs_fiemap_format(
993c59d87c4SChristoph Hellwig 	void			**arg,
994c59d87c4SChristoph Hellwig 	struct getbmapx		*bmv,
995c59d87c4SChristoph Hellwig 	int			*full)
996c59d87c4SChristoph Hellwig {
997c59d87c4SChristoph Hellwig 	int			error;
998c59d87c4SChristoph Hellwig 	struct fiemap_extent_info *fieinfo = *arg;
999c59d87c4SChristoph Hellwig 	u32			fiemap_flags = 0;
1000c59d87c4SChristoph Hellwig 	u64			logical, physical, length;
1001c59d87c4SChristoph Hellwig 
1002c59d87c4SChristoph Hellwig 	/* Do nothing for a hole */
1003c59d87c4SChristoph Hellwig 	if (bmv->bmv_block == -1LL)
1004c59d87c4SChristoph Hellwig 		return 0;
1005c59d87c4SChristoph Hellwig 
1006c59d87c4SChristoph Hellwig 	logical = BBTOB(bmv->bmv_offset);
1007c59d87c4SChristoph Hellwig 	physical = BBTOB(bmv->bmv_block);
1008c59d87c4SChristoph Hellwig 	length = BBTOB(bmv->bmv_length);
1009c59d87c4SChristoph Hellwig 
1010c59d87c4SChristoph Hellwig 	if (bmv->bmv_oflags & BMV_OF_PREALLOC)
1011c59d87c4SChristoph Hellwig 		fiemap_flags |= FIEMAP_EXTENT_UNWRITTEN;
1012c59d87c4SChristoph Hellwig 	else if (bmv->bmv_oflags & BMV_OF_DELALLOC) {
1013635c4d0bSJie Liu 		fiemap_flags |= (FIEMAP_EXTENT_DELALLOC |
1014635c4d0bSJie Liu 				 FIEMAP_EXTENT_UNKNOWN);
1015c59d87c4SChristoph Hellwig 		physical = 0;   /* no block yet */
1016c59d87c4SChristoph Hellwig 	}
1017c59d87c4SChristoph Hellwig 	if (bmv->bmv_oflags & BMV_OF_LAST)
1018c59d87c4SChristoph Hellwig 		fiemap_flags |= FIEMAP_EXTENT_LAST;
1019c59d87c4SChristoph Hellwig 
1020c59d87c4SChristoph Hellwig 	error = fiemap_fill_next_extent(fieinfo, logical, physical,
1021c59d87c4SChristoph Hellwig 					length, fiemap_flags);
1022c59d87c4SChristoph Hellwig 	if (error > 0) {
1023c59d87c4SChristoph Hellwig 		error = 0;
1024c59d87c4SChristoph Hellwig 		*full = 1;	/* user array now full */
1025c59d87c4SChristoph Hellwig 	}
1026c59d87c4SChristoph Hellwig 
1027c59d87c4SChristoph Hellwig 	return -error;
1028c59d87c4SChristoph Hellwig }
1029c59d87c4SChristoph Hellwig 
1030c59d87c4SChristoph Hellwig STATIC int
1031c59d87c4SChristoph Hellwig xfs_vn_fiemap(
1032c59d87c4SChristoph Hellwig 	struct inode		*inode,
1033c59d87c4SChristoph Hellwig 	struct fiemap_extent_info *fieinfo,
1034c59d87c4SChristoph Hellwig 	u64			start,
1035c59d87c4SChristoph Hellwig 	u64			length)
1036c59d87c4SChristoph Hellwig {
1037c59d87c4SChristoph Hellwig 	xfs_inode_t		*ip = XFS_I(inode);
1038c59d87c4SChristoph Hellwig 	struct getbmapx		bm;
1039c59d87c4SChristoph Hellwig 	int			error;
1040c59d87c4SChristoph Hellwig 
1041c59d87c4SChristoph Hellwig 	error = fiemap_check_flags(fieinfo, XFS_FIEMAP_FLAGS);
1042c59d87c4SChristoph Hellwig 	if (error)
1043c59d87c4SChristoph Hellwig 		return error;
1044c59d87c4SChristoph Hellwig 
1045c59d87c4SChristoph Hellwig 	/* Set up bmap header for xfs internal routine */
1046c59d87c4SChristoph Hellwig 	bm.bmv_offset = BTOBB(start);
1047c59d87c4SChristoph Hellwig 	/* Special case for whole file */
1048c59d87c4SChristoph Hellwig 	if (length == FIEMAP_MAX_OFFSET)
1049c59d87c4SChristoph Hellwig 		bm.bmv_length = -1LL;
1050c59d87c4SChristoph Hellwig 	else
1051c59d87c4SChristoph Hellwig 		bm.bmv_length = BTOBB(length);
1052c59d87c4SChristoph Hellwig 
1053c59d87c4SChristoph Hellwig 	/* We add one because in getbmap world count includes the header */
1054c59d87c4SChristoph Hellwig 	bm.bmv_count = !fieinfo->fi_extents_max ? MAXEXTNUM :
1055c59d87c4SChristoph Hellwig 					fieinfo->fi_extents_max + 1;
1056c59d87c4SChristoph Hellwig 	bm.bmv_count = min_t(__s32, bm.bmv_count,
1057c59d87c4SChristoph Hellwig 			     (PAGE_SIZE * 16 / sizeof(struct getbmapx)));
1058c59d87c4SChristoph Hellwig 	bm.bmv_iflags = BMV_IF_PREALLOC | BMV_IF_NO_HOLES;
1059c59d87c4SChristoph Hellwig 	if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR)
1060c59d87c4SChristoph Hellwig 		bm.bmv_iflags |= BMV_IF_ATTRFORK;
1061c59d87c4SChristoph Hellwig 	if (!(fieinfo->fi_flags & FIEMAP_FLAG_SYNC))
1062c59d87c4SChristoph Hellwig 		bm.bmv_iflags |= BMV_IF_DELALLOC;
1063c59d87c4SChristoph Hellwig 
1064c59d87c4SChristoph Hellwig 	error = xfs_getbmap(ip, &bm, xfs_fiemap_format, fieinfo);
1065c59d87c4SChristoph Hellwig 	if (error)
1066c59d87c4SChristoph Hellwig 		return -error;
1067c59d87c4SChristoph Hellwig 
1068c59d87c4SChristoph Hellwig 	return 0;
1069c59d87c4SChristoph Hellwig }
1070c59d87c4SChristoph Hellwig 
107199b6436bSZhi Yong Wu STATIC int
107299b6436bSZhi Yong Wu xfs_vn_tmpfile(
107399b6436bSZhi Yong Wu 	struct inode	*dir,
107499b6436bSZhi Yong Wu 	struct dentry	*dentry,
107599b6436bSZhi Yong Wu 	umode_t		mode)
107699b6436bSZhi Yong Wu {
1077*d540e43bSBrian Foster 	return xfs_generic_create(dir, dentry, mode, 0, true);
107899b6436bSZhi Yong Wu }
107999b6436bSZhi Yong Wu 
1080c59d87c4SChristoph Hellwig static const struct inode_operations xfs_inode_operations = {
1081c59d87c4SChristoph Hellwig 	.get_acl		= xfs_get_acl,
10822401dc29SChristoph Hellwig 	.set_acl		= xfs_set_acl,
1083c59d87c4SChristoph Hellwig 	.getattr		= xfs_vn_getattr,
1084c59d87c4SChristoph Hellwig 	.setattr		= xfs_vn_setattr,
1085c59d87c4SChristoph Hellwig 	.setxattr		= generic_setxattr,
1086c59d87c4SChristoph Hellwig 	.getxattr		= generic_getxattr,
1087c59d87c4SChristoph Hellwig 	.removexattr		= generic_removexattr,
1088c59d87c4SChristoph Hellwig 	.listxattr		= xfs_vn_listxattr,
1089c59d87c4SChristoph Hellwig 	.fiemap			= xfs_vn_fiemap,
109069ff2826SChristoph Hellwig 	.update_time		= xfs_vn_update_time,
1091c59d87c4SChristoph Hellwig };
1092c59d87c4SChristoph Hellwig 
1093c59d87c4SChristoph Hellwig static const struct inode_operations xfs_dir_inode_operations = {
1094c59d87c4SChristoph Hellwig 	.create			= xfs_vn_create,
1095c59d87c4SChristoph Hellwig 	.lookup			= xfs_vn_lookup,
1096c59d87c4SChristoph Hellwig 	.link			= xfs_vn_link,
1097c59d87c4SChristoph Hellwig 	.unlink			= xfs_vn_unlink,
1098c59d87c4SChristoph Hellwig 	.symlink		= xfs_vn_symlink,
1099c59d87c4SChristoph Hellwig 	.mkdir			= xfs_vn_mkdir,
1100c59d87c4SChristoph Hellwig 	/*
1101c59d87c4SChristoph Hellwig 	 * Yes, XFS uses the same method for rmdir and unlink.
1102c59d87c4SChristoph Hellwig 	 *
1103c59d87c4SChristoph Hellwig 	 * There are some subtile differences deeper in the code,
1104c59d87c4SChristoph Hellwig 	 * but we use S_ISDIR to check for those.
1105c59d87c4SChristoph Hellwig 	 */
1106c59d87c4SChristoph Hellwig 	.rmdir			= xfs_vn_unlink,
1107c59d87c4SChristoph Hellwig 	.mknod			= xfs_vn_mknod,
1108c59d87c4SChristoph Hellwig 	.rename			= xfs_vn_rename,
1109c59d87c4SChristoph Hellwig 	.get_acl		= xfs_get_acl,
11102401dc29SChristoph Hellwig 	.set_acl		= xfs_set_acl,
1111c59d87c4SChristoph Hellwig 	.getattr		= xfs_vn_getattr,
1112c59d87c4SChristoph Hellwig 	.setattr		= xfs_vn_setattr,
1113c59d87c4SChristoph Hellwig 	.setxattr		= generic_setxattr,
1114c59d87c4SChristoph Hellwig 	.getxattr		= generic_getxattr,
1115c59d87c4SChristoph Hellwig 	.removexattr		= generic_removexattr,
1116c59d87c4SChristoph Hellwig 	.listxattr		= xfs_vn_listxattr,
111769ff2826SChristoph Hellwig 	.update_time		= xfs_vn_update_time,
111899b6436bSZhi Yong Wu 	.tmpfile		= xfs_vn_tmpfile,
1119c59d87c4SChristoph Hellwig };
1120c59d87c4SChristoph Hellwig 
1121c59d87c4SChristoph Hellwig static const struct inode_operations xfs_dir_ci_inode_operations = {
1122c59d87c4SChristoph Hellwig 	.create			= xfs_vn_create,
1123c59d87c4SChristoph Hellwig 	.lookup			= xfs_vn_ci_lookup,
1124c59d87c4SChristoph Hellwig 	.link			= xfs_vn_link,
1125c59d87c4SChristoph Hellwig 	.unlink			= xfs_vn_unlink,
1126c59d87c4SChristoph Hellwig 	.symlink		= xfs_vn_symlink,
1127c59d87c4SChristoph Hellwig 	.mkdir			= xfs_vn_mkdir,
1128c59d87c4SChristoph Hellwig 	/*
1129c59d87c4SChristoph Hellwig 	 * Yes, XFS uses the same method for rmdir and unlink.
1130c59d87c4SChristoph Hellwig 	 *
1131c59d87c4SChristoph Hellwig 	 * There are some subtile differences deeper in the code,
1132c59d87c4SChristoph Hellwig 	 * but we use S_ISDIR to check for those.
1133c59d87c4SChristoph Hellwig 	 */
1134c59d87c4SChristoph Hellwig 	.rmdir			= xfs_vn_unlink,
1135c59d87c4SChristoph Hellwig 	.mknod			= xfs_vn_mknod,
1136c59d87c4SChristoph Hellwig 	.rename			= xfs_vn_rename,
1137c59d87c4SChristoph Hellwig 	.get_acl		= xfs_get_acl,
11382401dc29SChristoph Hellwig 	.set_acl		= xfs_set_acl,
1139c59d87c4SChristoph Hellwig 	.getattr		= xfs_vn_getattr,
1140c59d87c4SChristoph Hellwig 	.setattr		= xfs_vn_setattr,
1141c59d87c4SChristoph Hellwig 	.setxattr		= generic_setxattr,
1142c59d87c4SChristoph Hellwig 	.getxattr		= generic_getxattr,
1143c59d87c4SChristoph Hellwig 	.removexattr		= generic_removexattr,
1144c59d87c4SChristoph Hellwig 	.listxattr		= xfs_vn_listxattr,
114569ff2826SChristoph Hellwig 	.update_time		= xfs_vn_update_time,
114699b6436bSZhi Yong Wu 	.tmpfile		= xfs_vn_tmpfile,
1147c59d87c4SChristoph Hellwig };
1148c59d87c4SChristoph Hellwig 
1149c59d87c4SChristoph Hellwig static const struct inode_operations xfs_symlink_inode_operations = {
1150c59d87c4SChristoph Hellwig 	.readlink		= generic_readlink,
1151c59d87c4SChristoph Hellwig 	.follow_link		= xfs_vn_follow_link,
115296c8c442SAl Viro 	.put_link		= kfree_put_link,
1153c59d87c4SChristoph Hellwig 	.getattr		= xfs_vn_getattr,
1154c59d87c4SChristoph Hellwig 	.setattr		= xfs_vn_setattr,
1155c59d87c4SChristoph Hellwig 	.setxattr		= generic_setxattr,
1156c59d87c4SChristoph Hellwig 	.getxattr		= generic_getxattr,
1157c59d87c4SChristoph Hellwig 	.removexattr		= generic_removexattr,
1158c59d87c4SChristoph Hellwig 	.listxattr		= xfs_vn_listxattr,
115969ff2826SChristoph Hellwig 	.update_time		= xfs_vn_update_time,
1160c59d87c4SChristoph Hellwig };
1161c59d87c4SChristoph Hellwig 
1162c59d87c4SChristoph Hellwig STATIC void
1163c59d87c4SChristoph Hellwig xfs_diflags_to_iflags(
1164c59d87c4SChristoph Hellwig 	struct inode		*inode,
1165c59d87c4SChristoph Hellwig 	struct xfs_inode	*ip)
1166c59d87c4SChristoph Hellwig {
1167c59d87c4SChristoph Hellwig 	if (ip->i_d.di_flags & XFS_DIFLAG_IMMUTABLE)
1168c59d87c4SChristoph Hellwig 		inode->i_flags |= S_IMMUTABLE;
1169c59d87c4SChristoph Hellwig 	else
1170c59d87c4SChristoph Hellwig 		inode->i_flags &= ~S_IMMUTABLE;
1171c59d87c4SChristoph Hellwig 	if (ip->i_d.di_flags & XFS_DIFLAG_APPEND)
1172c59d87c4SChristoph Hellwig 		inode->i_flags |= S_APPEND;
1173c59d87c4SChristoph Hellwig 	else
1174c59d87c4SChristoph Hellwig 		inode->i_flags &= ~S_APPEND;
1175c59d87c4SChristoph Hellwig 	if (ip->i_d.di_flags & XFS_DIFLAG_SYNC)
1176c59d87c4SChristoph Hellwig 		inode->i_flags |= S_SYNC;
1177c59d87c4SChristoph Hellwig 	else
1178c59d87c4SChristoph Hellwig 		inode->i_flags &= ~S_SYNC;
1179c59d87c4SChristoph Hellwig 	if (ip->i_d.di_flags & XFS_DIFLAG_NOATIME)
1180c59d87c4SChristoph Hellwig 		inode->i_flags |= S_NOATIME;
1181c59d87c4SChristoph Hellwig 	else
1182c59d87c4SChristoph Hellwig 		inode->i_flags &= ~S_NOATIME;
1183c59d87c4SChristoph Hellwig }
1184c59d87c4SChristoph Hellwig 
1185c59d87c4SChristoph Hellwig /*
1186c59d87c4SChristoph Hellwig  * Initialize the Linux inode, set up the operation vectors and
1187c59d87c4SChristoph Hellwig  * unlock the inode.
1188c59d87c4SChristoph Hellwig  *
1189c59d87c4SChristoph Hellwig  * When reading existing inodes from disk this is called directly
1190c59d87c4SChristoph Hellwig  * from xfs_iget, when creating a new inode it is called from
1191c59d87c4SChristoph Hellwig  * xfs_ialloc after setting up the inode.
1192c59d87c4SChristoph Hellwig  *
1193c59d87c4SChristoph Hellwig  * We are always called with an uninitialised linux inode here.
1194c59d87c4SChristoph Hellwig  * We need to initialise the necessary fields and take a reference
1195c59d87c4SChristoph Hellwig  * on it.
1196c59d87c4SChristoph Hellwig  */
1197c59d87c4SChristoph Hellwig void
1198c59d87c4SChristoph Hellwig xfs_setup_inode(
1199c59d87c4SChristoph Hellwig 	struct xfs_inode	*ip)
1200c59d87c4SChristoph Hellwig {
1201c59d87c4SChristoph Hellwig 	struct inode		*inode = &ip->i_vnode;
1202ad22c7a0SDave Chinner 	gfp_t			gfp_mask;
1203c59d87c4SChristoph Hellwig 
1204c59d87c4SChristoph Hellwig 	inode->i_ino = ip->i_ino;
1205c59d87c4SChristoph Hellwig 	inode->i_state = I_NEW;
1206c59d87c4SChristoph Hellwig 
1207c59d87c4SChristoph Hellwig 	inode_sb_list_add(inode);
1208c59d87c4SChristoph Hellwig 	/* make the inode look hashed for the writeback code */
1209c59d87c4SChristoph Hellwig 	hlist_add_fake(&inode->i_hash);
1210c59d87c4SChristoph Hellwig 
1211c59d87c4SChristoph Hellwig 	inode->i_mode	= ip->i_d.di_mode;
1212bfe86848SMiklos Szeredi 	set_nlink(inode, ip->i_d.di_nlink);
12137aab1b28SDwight Engen 	inode->i_uid    = xfs_uid_to_kuid(ip->i_d.di_uid);
12147aab1b28SDwight Engen 	inode->i_gid    = xfs_gid_to_kgid(ip->i_d.di_gid);
1215c59d87c4SChristoph Hellwig 
1216c59d87c4SChristoph Hellwig 	switch (inode->i_mode & S_IFMT) {
1217c59d87c4SChristoph Hellwig 	case S_IFBLK:
1218c59d87c4SChristoph Hellwig 	case S_IFCHR:
1219c59d87c4SChristoph Hellwig 		inode->i_rdev =
1220c59d87c4SChristoph Hellwig 			MKDEV(sysv_major(ip->i_df.if_u2.if_rdev) & 0x1ff,
1221c59d87c4SChristoph Hellwig 			      sysv_minor(ip->i_df.if_u2.if_rdev));
1222c59d87c4SChristoph Hellwig 		break;
1223c59d87c4SChristoph Hellwig 	default:
1224c59d87c4SChristoph Hellwig 		inode->i_rdev = 0;
1225c59d87c4SChristoph Hellwig 		break;
1226c59d87c4SChristoph Hellwig 	}
1227c59d87c4SChristoph Hellwig 
1228c59d87c4SChristoph Hellwig 	inode->i_generation = ip->i_d.di_gen;
1229c59d87c4SChristoph Hellwig 	i_size_write(inode, ip->i_d.di_size);
1230c59d87c4SChristoph Hellwig 	inode->i_atime.tv_sec	= ip->i_d.di_atime.t_sec;
1231c59d87c4SChristoph Hellwig 	inode->i_atime.tv_nsec	= ip->i_d.di_atime.t_nsec;
1232c59d87c4SChristoph Hellwig 	inode->i_mtime.tv_sec	= ip->i_d.di_mtime.t_sec;
1233c59d87c4SChristoph Hellwig 	inode->i_mtime.tv_nsec	= ip->i_d.di_mtime.t_nsec;
1234c59d87c4SChristoph Hellwig 	inode->i_ctime.tv_sec	= ip->i_d.di_ctime.t_sec;
1235c59d87c4SChristoph Hellwig 	inode->i_ctime.tv_nsec	= ip->i_d.di_ctime.t_nsec;
1236c59d87c4SChristoph Hellwig 	xfs_diflags_to_iflags(inode, ip);
1237c59d87c4SChristoph Hellwig 
12384bceb18fSDave Chinner 	ip->d_ops = ip->i_mount->m_nondir_inode_ops;
123993a8614eSDave Chinner 	lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class);
1240c59d87c4SChristoph Hellwig 	switch (inode->i_mode & S_IFMT) {
1241c59d87c4SChristoph Hellwig 	case S_IFREG:
1242c59d87c4SChristoph Hellwig 		inode->i_op = &xfs_inode_operations;
1243c59d87c4SChristoph Hellwig 		inode->i_fop = &xfs_file_operations;
1244c59d87c4SChristoph Hellwig 		inode->i_mapping->a_ops = &xfs_address_space_operations;
1245c59d87c4SChristoph Hellwig 		break;
1246c59d87c4SChristoph Hellwig 	case S_IFDIR:
124793a8614eSDave Chinner 		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class);
1248c59d87c4SChristoph Hellwig 		if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb))
1249c59d87c4SChristoph Hellwig 			inode->i_op = &xfs_dir_ci_inode_operations;
1250c59d87c4SChristoph Hellwig 		else
1251c59d87c4SChristoph Hellwig 			inode->i_op = &xfs_dir_inode_operations;
1252c59d87c4SChristoph Hellwig 		inode->i_fop = &xfs_dir_file_operations;
125332c5483aSDave Chinner 		ip->d_ops = ip->i_mount->m_dir_inode_ops;
1254c59d87c4SChristoph Hellwig 		break;
1255c59d87c4SChristoph Hellwig 	case S_IFLNK:
1256c59d87c4SChristoph Hellwig 		inode->i_op = &xfs_symlink_inode_operations;
1257c59d87c4SChristoph Hellwig 		if (!(ip->i_df.if_flags & XFS_IFINLINE))
1258c59d87c4SChristoph Hellwig 			inode->i_mapping->a_ops = &xfs_address_space_operations;
1259c59d87c4SChristoph Hellwig 		break;
1260c59d87c4SChristoph Hellwig 	default:
1261c59d87c4SChristoph Hellwig 		inode->i_op = &xfs_inode_operations;
1262c59d87c4SChristoph Hellwig 		init_special_inode(inode, inode->i_mode, inode->i_rdev);
1263c59d87c4SChristoph Hellwig 		break;
1264c59d87c4SChristoph Hellwig 	}
1265c59d87c4SChristoph Hellwig 
1266c59d87c4SChristoph Hellwig 	/*
1267ad22c7a0SDave Chinner 	 * Ensure all page cache allocations are done from GFP_NOFS context to
1268ad22c7a0SDave Chinner 	 * prevent direct reclaim recursion back into the filesystem and blowing
1269ad22c7a0SDave Chinner 	 * stacks or deadlocking.
1270ad22c7a0SDave Chinner 	 */
1271ad22c7a0SDave Chinner 	gfp_mask = mapping_gfp_mask(inode->i_mapping);
1272ad22c7a0SDave Chinner 	mapping_set_gfp_mask(inode->i_mapping, (gfp_mask & ~(__GFP_FS)));
1273ad22c7a0SDave Chinner 
1274ad22c7a0SDave Chinner 	/*
1275c59d87c4SChristoph Hellwig 	 * If there is no attribute fork no ACL can exist on this inode,
1276c59d87c4SChristoph Hellwig 	 * and it can't have any file capabilities attached to it either.
1277c59d87c4SChristoph Hellwig 	 */
1278c59d87c4SChristoph Hellwig 	if (!XFS_IFORK_Q(ip)) {
1279c59d87c4SChristoph Hellwig 		inode_has_no_xattr(inode);
1280c59d87c4SChristoph Hellwig 		cache_no_acl(inode);
1281c59d87c4SChristoph Hellwig 	}
1282c59d87c4SChristoph Hellwig 
1283c59d87c4SChristoph Hellwig 	xfs_iflags_clear(ip, XFS_INEW);
1284c59d87c4SChristoph Hellwig 	barrier();
1285c59d87c4SChristoph Hellwig 
1286c59d87c4SChristoph Hellwig 	unlock_new_inode(inode);
1287c59d87c4SChristoph Hellwig }
1288