Blame view

fs/xfs/xfs_iops.c 31.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
7b7187698   Nathan Scott   [XFS] Update lice...
2
3
   * Copyright (c) 2000-2005 Silicon Graphics, Inc.
   * All Rights Reserved.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
   *
7b7187698   Nathan Scott   [XFS] Update lice...
5
6
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License as
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
   * published by the Free Software Foundation.
   *
7b7187698   Nathan Scott   [XFS] Update lice...
9
10
11
12
   * This program is distributed in the hope that it would be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
   *
7b7187698   Nathan Scott   [XFS] Update lice...
14
15
16
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write the Free Software Foundation,
   * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
  #include "xfs.h"
  #include "xfs_fs.h"
70a9883c5   Dave Chinner   xfs: create a sha...
20
  #include "xfs_shared.h"
239880ef6   Dave Chinner   xfs: decouple log...
21
22
23
  #include "xfs_format.h"
  #include "xfs_log_format.h"
  #include "xfs_trans_resv.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
  #include "xfs_mount.h"
570627875   Dave Chinner   xfs: unify direct...
25
  #include "xfs_da_format.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
  #include "xfs_inode.h"
  #include "xfs_bmap.h"
689881145   Dave Chinner   xfs: create xfs_b...
28
  #include "xfs_bmap_util.h"
239880ef6   Dave Chinner   xfs: decouple log...
29
  #include "xfs_acl.h"
239880ef6   Dave Chinner   xfs: decouple log...
30
  #include "xfs_quota.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
  #include "xfs_error.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
  #include "xfs_attr.h"
239880ef6   Dave Chinner   xfs: decouple log...
33
  #include "xfs_trans.h"
0b1b213fc   Christoph Hellwig   xfs: event tracin...
34
  #include "xfs_trace.h"
27b528679   Brian Foster   xfs: add EOFBLOCK...
35
  #include "xfs_icache.h"
c24b5dfad   Dave Chinner   xfs: kill xfs_vno...
36
  #include "xfs_symlink.h"
0cb97766f   Dave Chinner   xfs: Add read-onl...
37
  #include "xfs_da_btree.h"
1b767ee38   Dave Chinner   xfs: move ftype c...
38
  #include "xfs_dir2.h"
99b6436bc   Zhi Yong Wu   xfs: add O_TMPFIL...
39
  #include "xfs_trans_space.h"
781355c6e   Christoph Hellwig   xfs: recall pNFS ...
40
  #include "xfs_pnfs.h"
68a9f5e70   Christoph Hellwig   xfs: implement io...
41
  #include "xfs_iomap.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42

16f7e0fe2   Randy Dunlap   [PATCH] capable/c...
43
  #include <linux/capability.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
  #include <linux/xattr.h>
ef14f0c15   Christoph Hellwig   xfs: use generic ...
45
  #include <linux/posix_acl.h>
446ada4a0   Nathan Scott   [XFS] Add an XFS ...
46
  #include <linux/security.h>
d2bb140e9   Christoph Hellwig   xfs: use iomap fi...
47
  #include <linux/iomap.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
48
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49

93a8614e3   Dave Chinner   xfs: fix director...
50
51
52
53
54
55
56
57
58
59
60
  /*
   * Directories have different lock order w.r.t. mmap_sem compared to regular
   * files. This is due to readdir potentially triggering page faults on a user
   * buffer inside filldir(), and this happens with the ilock on the directory
   * held. For regular files, the lock order is the other way around - the
   * mmap_sem is taken during the page fault, and then we lock the ilock to do
   * block mapping. Hence we need a different class for the directory ilock so
   * that lockdep can tell them apart.
   */
  static struct lock_class_key xfs_nondir_ilock_class;
  static struct lock_class_key xfs_dir_ilock_class;
8d2a5e6ee   Dave Chinner   xfs: clean up min...
61
62
63
64
65
  static int
  xfs_initxattrs(
  	struct inode		*inode,
  	const struct xattr	*xattr_array,
  	void			*fs_info)
9d8f13ba3   Mimi Zohar   security: new sec...
66
  {
8d2a5e6ee   Dave Chinner   xfs: clean up min...
67
68
69
  	const struct xattr	*xattr;
  	struct xfs_inode	*ip = XFS_I(inode);
  	int			error = 0;
9d8f13ba3   Mimi Zohar   security: new sec...
70
71
  
  	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
2451337dd   Dave Chinner   xfs: global error...
72
  		error = xfs_attr_set(ip, xattr->name, xattr->value,
a5a14de22   Dave Chinner   xfs: fix wrong er...
73
  				      xattr->value_len, ATTR_SECURE);
9d8f13ba3   Mimi Zohar   security: new sec...
74
75
76
77
78
  		if (error < 0)
  			break;
  	}
  	return error;
  }
5d51eff45   David Chinner   [XFS] Fix inode a...
79
  /*
446ada4a0   Nathan Scott   [XFS] Add an XFS ...
80
81
82
83
84
   * Hook in SELinux.  This is not quite correct yet, what we really need
   * here (as we do for default ACLs) is a mechanism by which creation of
   * these attrs can be journalled at inode creation time (along with the
   * inode, of course, such that log replay can't cause these to be lost).
   */
9d8f13ba3   Mimi Zohar   security: new sec...
85

446ada4a0   Nathan Scott   [XFS] Add an XFS ...
86
  STATIC int
416c6d5bc   Nathan Scott   [XFS] Switch over...
87
  xfs_init_security(
af048193f   Christoph Hellwig   [XFS] cleanup vno...
88
  	struct inode	*inode,
2a7dba391   Eric Paris   fs/vfs/security: ...
89
90
  	struct inode	*dir,
  	const struct qstr *qstr)
446ada4a0   Nathan Scott   [XFS] Add an XFS ...
91
  {
2451337dd   Dave Chinner   xfs: global error...
92
  	return security_inode_init_security(inode, dir, qstr,
a5a14de22   Dave Chinner   xfs: fix wrong er...
93
  					     &xfs_initxattrs, NULL);
446ada4a0   Nathan Scott   [XFS] Add an XFS ...
94
  }
556b8b166   Barry Naujok   [XFS] remove bhv_...
95
96
97
  static void
  xfs_dentry_to_name(
  	struct xfs_name	*namep,
43ce59217   Amir Goldstein   xfs: sanity check...
98
99
100
101
102
103
104
105
106
107
  	struct dentry	*dentry)
  {
  	namep->name = dentry->d_name.name;
  	namep->len = dentry->d_name.len;
  	namep->type = XFS_DIR3_FT_UNKNOWN;
  }
  
  static int
  xfs_dentry_mode_to_name(
  	struct xfs_name	*namep,
0cb97766f   Dave Chinner   xfs: Add read-onl...
108
109
  	struct dentry	*dentry,
  	int		mode)
556b8b166   Barry Naujok   [XFS] remove bhv_...
110
111
112
  {
  	namep->name = dentry->d_name.name;
  	namep->len = dentry->d_name.len;
b5f68e24c   Amir Goldstein   xfs: replace xfs_...
113
  	namep->type = xfs_mode_to_ftype(mode);
43ce59217   Amir Goldstein   xfs: sanity check...
114
115
116
117
118
  
  	if (unlikely(namep->type == XFS_DIR3_FT_UNKNOWN))
  		return -EFSCORRUPTED;
  
  	return 0;
556b8b166   Barry Naujok   [XFS] remove bhv_...
119
  }
7989cb8ef   David Chinner   [XFS] Keep stack ...
120
  STATIC void
416c6d5bc   Nathan Scott   [XFS] Switch over...
121
  xfs_cleanup_inode(
739bfb2a7   Christoph Hellwig   [XFS] call common...
122
  	struct inode	*dir,
af048193f   Christoph Hellwig   [XFS] cleanup vno...
123
  	struct inode	*inode,
8f112e3bc   Christoph Hellwig   [XFS] Merge xfs_r...
124
  	struct dentry	*dentry)
3a69c7dc6   Yingping Lu   [XFS] Interim sol...
125
  {
556b8b166   Barry Naujok   [XFS] remove bhv_...
126
  	struct xfs_name	teardown;
3a69c7dc6   Yingping Lu   [XFS] Interim sol...
127
128
  
  	/* Oh, the horror.
220b52841   Nathan Scott   [XFS] Dynamically...
129
  	 * If we can't add the ACL or we fail in
416c6d5bc   Nathan Scott   [XFS] Switch over...
130
  	 * xfs_init_security we must back out.
3a69c7dc6   Yingping Lu   [XFS] Interim sol...
131
132
  	 * ENOSPC can hit here, among other things.
  	 */
43ce59217   Amir Goldstein   xfs: sanity check...
133
  	xfs_dentry_to_name(&teardown, dentry);
3a69c7dc6   Yingping Lu   [XFS] Interim sol...
134

8f112e3bc   Christoph Hellwig   [XFS] Merge xfs_r...
135
  	xfs_remove(XFS_I(dir), &teardown, XFS_I(inode));
3a69c7dc6   Yingping Lu   [XFS] Interim sol...
136
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
  STATIC int
d540e43b0   Brian Foster   xfs: initialize d...
138
  xfs_generic_create(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
  	struct inode	*dir,
  	struct dentry	*dentry,
1a67aafb5   Al Viro   switch ->mknod() ...
141
  	umode_t		mode,
d540e43b0   Brian Foster   xfs: initialize d...
142
143
  	dev_t		rdev,
  	bool		tmpfile)	/* unnamed file */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
  {
db0bb7baa   Christoph Hellwig   [XFS] cleanup xfs...
145
  	struct inode	*inode;
979ebab11   Christoph Hellwig   [XFS] cleanup vno...
146
  	struct xfs_inode *ip = NULL;
2401dc297   Christoph Hellwig   xfs: use generic ...
147
  	struct posix_acl *default_acl, *acl;
556b8b166   Barry Naujok   [XFS] remove bhv_...
148
  	struct xfs_name	name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
150
151
152
153
154
  	int		error;
  
  	/*
  	 * Irix uses Missed'em'V split, but doesn't want to see
  	 * the upper 5 bits of (14bit) major.
  	 */
517b5e8c8   Christoph Hellwig   xfs: merge xfs_mk...
155
156
157
158
159
160
161
  	if (S_ISCHR(mode) || S_ISBLK(mode)) {
  		if (unlikely(!sysv_valid_dev(rdev) || MAJOR(rdev) & ~0x1ff))
  			return -EINVAL;
  		rdev = sysv_encode_dev(rdev);
  	} else {
  		rdev = 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162

2401dc297   Christoph Hellwig   xfs: use generic ...
163
164
165
  	error = posix_acl_create(dir, &mode, &default_acl, &acl);
  	if (error)
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166

43ce59217   Amir Goldstein   xfs: sanity check...
167
168
169
170
  	/* Verify mode is valid also for tmpfile case */
  	error = xfs_dentry_mode_to_name(&name, dentry, mode);
  	if (unlikely(error))
  		goto out_free_acl;
d540e43b0   Brian Foster   xfs: initialize d...
171
  	if (!tmpfile) {
d540e43b0   Brian Foster   xfs: initialize d...
172
173
174
175
  		error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip);
  	} else {
  		error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip);
  	}
db0bb7baa   Christoph Hellwig   [XFS] cleanup xfs...
176
177
  	if (unlikely(error))
  		goto out_free_acl;
446ada4a0   Nathan Scott   [XFS] Add an XFS ...
178

016516462   David Chinner   [XFS] Avoid direc...
179
  	inode = VFS_I(ip);
979ebab11   Christoph Hellwig   [XFS] cleanup vno...
180

2a7dba391   Eric Paris   fs/vfs/security: ...
181
  	error = xfs_init_security(inode, dir, &dentry->d_name);
db0bb7baa   Christoph Hellwig   [XFS] cleanup xfs...
182
183
  	if (unlikely(error))
  		goto out_cleanup_inode;
2401dc297   Christoph Hellwig   xfs: use generic ...
184
  #ifdef CONFIG_XFS_POSIX_ACL
db0bb7baa   Christoph Hellwig   [XFS] cleanup xfs...
185
  	if (default_acl) {
2451337dd   Dave Chinner   xfs: global error...
186
  		error = xfs_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
2401dc297   Christoph Hellwig   xfs: use generic ...
187
  		if (error)
db0bb7baa   Christoph Hellwig   [XFS] cleanup xfs...
188
  			goto out_cleanup_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
  	}
2401dc297   Christoph Hellwig   xfs: use generic ...
190
  	if (acl) {
2451337dd   Dave Chinner   xfs: global error...
191
  		error = xfs_set_acl(inode, acl, ACL_TYPE_ACCESS);
2401dc297   Christoph Hellwig   xfs: use generic ...
192
193
194
195
  		if (error)
  			goto out_cleanup_inode;
  	}
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196

2b3d1d41b   Christoph Hellwig   xfs: set up inode...
197
  	xfs_setup_iops(ip);
d540e43b0   Brian Foster   xfs: initialize d...
198
199
200
201
  	if (tmpfile)
  		d_tmpfile(dentry, inode);
  	else
  		d_instantiate(dentry, inode);
58c904734   Dave Chinner   xfs: inodes are n...
202
  	xfs_finish_inode_setup(ip);
2401dc297   Christoph Hellwig   xfs: use generic ...
203
204
205
206
207
   out_free_acl:
  	if (default_acl)
  		posix_acl_release(default_acl);
  	if (acl)
  		posix_acl_release(acl);
2451337dd   Dave Chinner   xfs: global error...
208
  	return error;
db0bb7baa   Christoph Hellwig   [XFS] cleanup xfs...
209
210
  
   out_cleanup_inode:
58c904734   Dave Chinner   xfs: inodes are n...
211
  	xfs_finish_inode_setup(ip);
d540e43b0   Brian Foster   xfs: initialize d...
212
213
214
  	if (!tmpfile)
  		xfs_cleanup_inode(dir, inode, dentry);
  	iput(inode);
2401dc297   Christoph Hellwig   xfs: use generic ...
215
  	goto out_free_acl;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
217
218
  }
  
  STATIC int
d540e43b0   Brian Foster   xfs: initialize d...
219
220
221
222
223
224
225
226
227
228
  xfs_vn_mknod(
  	struct inode	*dir,
  	struct dentry	*dentry,
  	umode_t		mode,
  	dev_t		rdev)
  {
  	return xfs_generic_create(dir, dentry, mode, rdev, false);
  }
  
  STATIC int
416c6d5bc   Nathan Scott   [XFS] Switch over...
229
  xfs_vn_create(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
  	struct inode	*dir,
  	struct dentry	*dentry,
4acdaf27e   Al Viro   switch ->create()...
232
  	umode_t		mode,
ebfc3b49a   Al Viro   don't pass nameid...
233
  	bool		flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  {
416c6d5bc   Nathan Scott   [XFS] Switch over...
235
  	return xfs_vn_mknod(dir, dentry, mode, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
236
237
238
  }
  
  STATIC int
416c6d5bc   Nathan Scott   [XFS] Switch over...
239
  xfs_vn_mkdir(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
241
  	struct inode	*dir,
  	struct dentry	*dentry,
18bb1db3e   Al Viro   switch vfs_mkdir(...
242
  	umode_t		mode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
  {
416c6d5bc   Nathan Scott   [XFS] Switch over...
244
  	return xfs_vn_mknod(dir, dentry, mode|S_IFDIR, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
246
247
  }
  
  STATIC struct dentry *
416c6d5bc   Nathan Scott   [XFS] Switch over...
248
  xfs_vn_lookup(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
250
  	struct inode	*dir,
  	struct dentry	*dentry,
00cd8dd3b   Al Viro   stop passing name...
251
  	unsigned int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252
  {
ef1f5e7ad   Christoph Hellwig   [XFS] cleanup vno...
253
  	struct xfs_inode *cip;
556b8b166   Barry Naujok   [XFS] remove bhv_...
254
  	struct xfs_name	name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
256
257
258
  	int		error;
  
  	if (dentry->d_name.len >= MAXNAMELEN)
  		return ERR_PTR(-ENAMETOOLONG);
43ce59217   Amir Goldstein   xfs: sanity check...
259
  	xfs_dentry_to_name(&name, dentry);
384f3ced0   Barry Naujok   [XFS] Return case...
260
  	error = xfs_lookup(XFS_I(dir), &name, &cip, NULL);
67fcaa73a   Nathan Scott   [XFS] Resolve a n...
261
  	if (unlikely(error)) {
2451337dd   Dave Chinner   xfs: global error...
262
263
  		if (unlikely(error != -ENOENT))
  			return ERR_PTR(error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
264
265
266
  		d_add(dentry, NULL);
  		return NULL;
  	}
016516462   David Chinner   [XFS] Avoid direc...
267
  	return d_splice_alias(VFS_I(cip), dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268
  }
384f3ced0   Barry Naujok   [XFS] Return case...
269
270
271
272
  STATIC struct dentry *
  xfs_vn_ci_lookup(
  	struct inode	*dir,
  	struct dentry	*dentry,
00cd8dd3b   Al Viro   stop passing name...
273
  	unsigned int flags)
384f3ced0   Barry Naujok   [XFS] Return case...
274
275
276
277
278
279
280
281
282
  {
  	struct xfs_inode *ip;
  	struct xfs_name	xname;
  	struct xfs_name ci_name;
  	struct qstr	dname;
  	int		error;
  
  	if (dentry->d_name.len >= MAXNAMELEN)
  		return ERR_PTR(-ENAMETOOLONG);
43ce59217   Amir Goldstein   xfs: sanity check...
283
  	xfs_dentry_to_name(&xname, dentry);
384f3ced0   Barry Naujok   [XFS] Return case...
284
285
  	error = xfs_lookup(XFS_I(dir), &xname, &ip, &ci_name);
  	if (unlikely(error)) {
2451337dd   Dave Chinner   xfs: global error...
286
287
  		if (unlikely(error != -ENOENT))
  			return ERR_PTR(error);
866d5dc97   Barry Naujok   [XFS] Remove d_ad...
288
289
290
291
292
  		/*
  		 * call d_add(dentry, NULL) here when d_drop_negative_children
  		 * is called in xfs_vn_mknod (ie. allow negative dentries
  		 * with CI filesystems).
  		 */
384f3ced0   Barry Naujok   [XFS] Return case...
293
294
295
296
297
  		return NULL;
  	}
  
  	/* if exact match, just splice and exit */
  	if (!ci_name.name)
016516462   David Chinner   [XFS] Avoid direc...
298
  		return d_splice_alias(VFS_I(ip), dentry);
384f3ced0   Barry Naujok   [XFS] Return case...
299
300
301
302
  
  	/* else case-insensitive match... */
  	dname.name = ci_name.name;
  	dname.len = ci_name.len;
e45b590b9   Christoph Hellwig   [PATCH] change d_...
303
  	dentry = d_add_ci(dentry, VFS_I(ip), &dname);
384f3ced0   Barry Naujok   [XFS] Return case...
304
305
306
  	kmem_free(ci_name.name);
  	return dentry;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
  STATIC int
416c6d5bc   Nathan Scott   [XFS] Switch over...
308
  xfs_vn_link(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
310
311
312
  	struct dentry	*old_dentry,
  	struct inode	*dir,
  	struct dentry	*dentry)
  {
2b0143b5c   David Howells   VFS: normal files...
313
  	struct inode	*inode = d_inode(old_dentry);
556b8b166   Barry Naujok   [XFS] remove bhv_...
314
  	struct xfs_name	name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
  	int		error;
43ce59217   Amir Goldstein   xfs: sanity check...
316
317
318
  	error = xfs_dentry_mode_to_name(&name, dentry, inode->i_mode);
  	if (unlikely(error))
  		return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
319

556b8b166   Barry Naujok   [XFS] remove bhv_...
320
  	error = xfs_link(XFS_I(dir), XFS_I(inode), &name);
d9424b3c4   Christoph Hellwig   stop using igrab ...
321
  	if (unlikely(error))
2451337dd   Dave Chinner   xfs: global error...
322
  		return error;
a3da78964   Christoph Hellwig   [XFS] cleanup vno...
323

7de9c6ee3   Al Viro   new helper: ihold()
324
  	ihold(inode);
a3da78964   Christoph Hellwig   [XFS] cleanup vno...
325
326
  	d_instantiate(dentry, inode);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
328
329
  }
  
  STATIC int
416c6d5bc   Nathan Scott   [XFS] Switch over...
330
  xfs_vn_unlink(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331
332
333
  	struct inode	*dir,
  	struct dentry	*dentry)
  {
556b8b166   Barry Naujok   [XFS] remove bhv_...
334
  	struct xfs_name	name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335
  	int		error;
43ce59217   Amir Goldstein   xfs: sanity check...
336
  	xfs_dentry_to_name(&name, dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337

2b0143b5c   David Howells   VFS: normal files...
338
  	error = xfs_remove(XFS_I(dir), &name, XFS_I(d_inode(dentry)));
e5700704b   Christoph Hellwig   [XFS] Don't updat...
339
340
341
342
343
344
345
346
347
348
349
  	if (error)
  		return error;
  
  	/*
  	 * With unlink, the VFS makes the dentry "negative": no inode,
  	 * but still hashed. This is incompatible with case-insensitive
  	 * mode, so invalidate (unhash) the dentry in CI-mode.
  	 */
  	if (xfs_sb_version_hasasciici(&XFS_M(dir->i_sb)->m_sb))
  		d_invalidate(dentry);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
351
352
  }
  
  STATIC int
416c6d5bc   Nathan Scott   [XFS] Switch over...
353
  xfs_vn_symlink(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
355
356
357
  	struct inode	*dir,
  	struct dentry	*dentry,
  	const char	*symname)
  {
3937be5ba   Christoph Hellwig   [XFS] cleanup vno...
358
359
  	struct inode	*inode;
  	struct xfs_inode *cip = NULL;
556b8b166   Barry Naujok   [XFS] remove bhv_...
360
  	struct xfs_name	name;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
  	int		error;
576b1d67c   Al Viro   xfs: propagate um...
362
  	umode_t		mode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
363

3e5daf05a   Christoph Hellwig   [XFS] simplify xf...
364
  	mode = S_IFLNK |
ce3b0f8d5   Al Viro   New helper - curr...
365
  		(irix_symlink_mode ? 0777 & ~current_umask() : S_IRWXUGO);
43ce59217   Amir Goldstein   xfs: sanity check...
366
367
368
  	error = xfs_dentry_mode_to_name(&name, dentry, mode);
  	if (unlikely(error))
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369

6c77b0ea1   Christoph Hellwig   xfs: remove xfs_c...
370
  	error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip);
3937be5ba   Christoph Hellwig   [XFS] cleanup vno...
371
372
  	if (unlikely(error))
  		goto out;
016516462   David Chinner   [XFS] Avoid direc...
373
  	inode = VFS_I(cip);
3937be5ba   Christoph Hellwig   [XFS] cleanup vno...
374

2a7dba391   Eric Paris   fs/vfs/security: ...
375
  	error = xfs_init_security(inode, dir, &dentry->d_name);
3937be5ba   Christoph Hellwig   [XFS] cleanup vno...
376
377
  	if (unlikely(error))
  		goto out_cleanup_inode;
2b3d1d41b   Christoph Hellwig   xfs: set up inode...
378
  	xfs_setup_iops(cip);
3937be5ba   Christoph Hellwig   [XFS] cleanup vno...
379
  	d_instantiate(dentry, inode);
58c904734   Dave Chinner   xfs: inodes are n...
380
  	xfs_finish_inode_setup(cip);
3937be5ba   Christoph Hellwig   [XFS] cleanup vno...
381
382
383
  	return 0;
  
   out_cleanup_inode:
58c904734   Dave Chinner   xfs: inodes are n...
384
  	xfs_finish_inode_setup(cip);
8f112e3bc   Christoph Hellwig   [XFS] Merge xfs_r...
385
  	xfs_cleanup_inode(dir, inode, dentry);
d540e43b0   Brian Foster   xfs: initialize d...
386
  	iput(inode);
3937be5ba   Christoph Hellwig   [XFS] cleanup vno...
387
   out:
2451337dd   Dave Chinner   xfs: global error...
388
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389
390
391
  }
  
  STATIC int
416c6d5bc   Nathan Scott   [XFS] Switch over...
392
  xfs_vn_rename(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
394
395
  	struct inode	*odir,
  	struct dentry	*odentry,
  	struct inode	*ndir,
dbe1b5ca2   Carlos Maiolino   xfs: Make xfs_vn_...
396
397
  	struct dentry	*ndentry,
  	unsigned int	flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398
  {
2b0143b5c   David Howells   VFS: normal files...
399
  	struct inode	*new_inode = d_inode(ndentry);
d31a18254   Carlos Maiolino   xfs: Add support ...
400
  	int		omode = 0;
43ce59217   Amir Goldstein   xfs: sanity check...
401
  	int		error;
556b8b166   Barry Naujok   [XFS] remove bhv_...
402
403
  	struct xfs_name	oname;
  	struct xfs_name	nname;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
404

7dcf5c3e4   Dave Chinner   xfs: add RENAME_W...
405
  	if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
dbe1b5ca2   Carlos Maiolino   xfs: Make xfs_vn_...
406
  		return -EINVAL;
d31a18254   Carlos Maiolino   xfs: Add support ...
407
408
  	/* if we are exchanging files, we need to set i_mode of both files */
  	if (flags & RENAME_EXCHANGE)
2b0143b5c   David Howells   VFS: normal files...
409
  		omode = d_inode(ndentry)->i_mode;
d31a18254   Carlos Maiolino   xfs: Add support ...
410

43ce59217   Amir Goldstein   xfs: sanity check...
411
412
413
414
415
416
417
418
  	error = xfs_dentry_mode_to_name(&oname, odentry, omode);
  	if (omode && unlikely(error))
  		return error;
  
  	error = xfs_dentry_mode_to_name(&nname, ndentry,
  					d_inode(odentry)->i_mode);
  	if (unlikely(error))
  		return error;
556b8b166   Barry Naujok   [XFS] remove bhv_...
419

2b0143b5c   David Howells   VFS: normal files...
420
  	return xfs_rename(XFS_I(odir), &oname, XFS_I(d_inode(odentry)),
dbe1b5ca2   Carlos Maiolino   xfs: Make xfs_vn_...
421
  			  XFS_I(ndir), &nname,
d31a18254   Carlos Maiolino   xfs: Add support ...
422
  			  new_inode ? XFS_I(new_inode) : NULL, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
424
425
426
427
428
429
  }
  
  /*
   * careful here - this function can get called recursively, so
   * we need to be very careful about how much stack we use.
   * uio is kmalloced for this reason...
   */
680baacbc   Al Viro   new ->follow_link...
430
  STATIC const char *
6b2553918   Al Viro   replace ->follow_...
431
  xfs_vn_get_link(
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
432
  	struct dentry		*dentry,
6b2553918   Al Viro   replace ->follow_...
433
  	struct inode		*inode,
fceef393a   Al Viro   switch ->get_link...
434
  	struct delayed_call	*done)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
  	char			*link;
804c83c37   Christoph Hellwig   [XFS] stop using ...
437
  	int			error = -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438

6b2553918   Al Viro   replace ->follow_...
439
440
  	if (!dentry)
  		return ERR_PTR(-ECHILD);
f52720ca5   Panagiotis Issaris   [PATCH] fs: Remov...
441
  	link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
804c83c37   Christoph Hellwig   [XFS] stop using ...
442
443
  	if (!link)
  		goto out_err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
444

2b0143b5c   David Howells   VFS: normal files...
445
  	error = xfs_readlink(XFS_I(d_inode(dentry)), link);
804c83c37   Christoph Hellwig   [XFS] stop using ...
446
447
  	if (unlikely(error))
  		goto out_kfree;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448

fceef393a   Al Viro   switch ->get_link...
449
450
  	set_delayed_call(done, kfree_link, link);
  	return link;
804c83c37   Christoph Hellwig   [XFS] stop using ...
451
452
453
454
  
   out_kfree:
  	kfree(link);
   out_err:
680baacbc   Al Viro   new ->follow_link...
455
  	return ERR_PTR(error);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
  }
30ee052e1   Christoph Hellwig   xfs: optimize inl...
457
458
459
460
461
462
463
464
465
  STATIC const char *
  xfs_vn_get_link_inline(
  	struct dentry		*dentry,
  	struct inode		*inode,
  	struct delayed_call	*done)
  {
  	ASSERT(XFS_I(inode)->i_df.if_flags & XFS_IFINLINE);
  	return XFS_I(inode)->i_df.if_u1.if_data;
  }
4576758db   Christoph Hellwig   [XFS] use generic...
466
  STATIC int
416c6d5bc   Nathan Scott   [XFS] Switch over...
467
  xfs_vn_getattr(
c43f40879   Christoph Hellwig   [XFS] simplify xf...
468
469
470
  	struct vfsmount		*mnt,
  	struct dentry		*dentry,
  	struct kstat		*stat)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
471
  {
2b0143b5c   David Howells   VFS: normal files...
472
  	struct inode		*inode = d_inode(dentry);
c43f40879   Christoph Hellwig   [XFS] simplify xf...
473
474
  	struct xfs_inode	*ip = XFS_I(inode);
  	struct xfs_mount	*mp = ip->i_mount;
cca28fb83   Christoph Hellwig   xfs: split xfs_it...
475
  	trace_xfs_getattr(ip);
c43f40879   Christoph Hellwig   [XFS] simplify xf...
476
477
  
  	if (XFS_FORCED_SHUTDOWN(mp))
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
478
  		return -EIO;
c43f40879   Christoph Hellwig   [XFS] simplify xf...
479
480
481
  
  	stat->size = XFS_ISIZE(ip);
  	stat->dev = inode->i_sb->s_dev;
c19b3b05a   Dave Chinner   xfs: mode di_mode...
482
  	stat->mode = inode->i_mode;
54d7b5c1d   Dave Chinner   xfs: use vfs inod...
483
  	stat->nlink = inode->i_nlink;
7aab1b288   Dwight Engen   xfs: convert kuid...
484
485
  	stat->uid = inode->i_uid;
  	stat->gid = inode->i_gid;
c43f40879   Christoph Hellwig   [XFS] simplify xf...
486
  	stat->ino = ip->i_ino;
c43f40879   Christoph Hellwig   [XFS] simplify xf...
487
  	stat->atime = inode->i_atime;
f9581b144   Christoph Hellwig   xfs: implement ->...
488
489
  	stat->mtime = inode->i_mtime;
  	stat->ctime = inode->i_ctime;
c43f40879   Christoph Hellwig   [XFS] simplify xf...
490
491
492
493
494
495
496
497
498
499
500
501
  	stat->blocks =
  		XFS_FSB_TO_BB(mp, ip->i_d.di_nblocks + ip->i_delayed_blks);
  
  
  	switch (inode->i_mode & S_IFMT) {
  	case S_IFBLK:
  	case S_IFCHR:
  		stat->blksize = BLKDEV_IOSIZE;
  		stat->rdev = MKDEV(sysv_major(ip->i_df.if_u2.if_rdev) & 0x1ff,
  				   sysv_minor(ip->i_df.if_u2.if_rdev));
  		break;
  	default:
71ddabb94   Eric Sandeen   [XFS] optimize XF...
502
  		if (XFS_IS_REALTIME_INODE(ip)) {
c43f40879   Christoph Hellwig   [XFS] simplify xf...
503
504
505
506
507
508
509
510
511
512
513
  			/*
  			 * If the file blocks are being allocated from a
  			 * realtime volume, then return the inode's realtime
  			 * extent size or the realtime volume's extent size.
  			 */
  			stat->blksize =
  				xfs_get_extsz_hint(ip) << mp->m_sb.sb_blocklog;
  		} else
  			stat->blksize = xfs_preferred_iosize(mp);
  		stat->rdev = 0;
  		break;
69e23b9a5   Nathan Scott   [XFS] Update XFS ...
514
  	}
c43f40879   Christoph Hellwig   [XFS] simplify xf...
515
516
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
517
  }
56c19e89b   Dave Chinner   xfs: kill suid/sg...
518
519
  static void
  xfs_setattr_mode(
56c19e89b   Dave Chinner   xfs: kill suid/sg...
520
521
522
  	struct xfs_inode	*ip,
  	struct iattr		*iattr)
  {
0c3d88dfc   Christoph Hellwig   xfs: tiny xfs_set...
523
524
  	struct inode		*inode = VFS_I(ip);
  	umode_t			mode = iattr->ia_mode;
56c19e89b   Dave Chinner   xfs: kill suid/sg...
525

56c19e89b   Dave Chinner   xfs: kill suid/sg...
526
  	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
56c19e89b   Dave Chinner   xfs: kill suid/sg...
527
528
529
  	inode->i_mode &= S_IFMT;
  	inode->i_mode |= mode & ~S_IFMT;
  }
527851124   Christoph Hellwig   xfs: implement pN...
530
  void
c91c46c12   Christoph Hellwig   xfs: add xfs_seta...
531
532
533
534
535
536
537
  xfs_setattr_time(
  	struct xfs_inode	*ip,
  	struct iattr		*iattr)
  {
  	struct inode		*inode = VFS_I(ip);
  
  	ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
3987848c7   Dave Chinner   xfs: remove times...
538
  	if (iattr->ia_valid & ATTR_ATIME)
c91c46c12   Christoph Hellwig   xfs: add xfs_seta...
539
  		inode->i_atime = iattr->ia_atime;
3987848c7   Dave Chinner   xfs: remove times...
540
  	if (iattr->ia_valid & ATTR_CTIME)
c91c46c12   Christoph Hellwig   xfs: add xfs_seta...
541
  		inode->i_ctime = iattr->ia_ctime;
3987848c7   Dave Chinner   xfs: remove times...
542
  	if (iattr->ia_valid & ATTR_MTIME)
c91c46c12   Christoph Hellwig   xfs: add xfs_seta...
543
  		inode->i_mtime = iattr->ia_mtime;
c91c46c12   Christoph Hellwig   xfs: add xfs_seta...
544
  }
69bca8074   Jan Kara   xfs: Propagate de...
545
546
547
548
549
  static int
  xfs_vn_change_ok(
  	struct dentry	*dentry,
  	struct iattr	*iattr)
  {
31051c85b   Jan Kara   fs: Give dentry t...
550
  	struct xfs_mount	*mp = XFS_I(d_inode(dentry))->i_mount;
69bca8074   Jan Kara   xfs: Propagate de...
551
552
553
554
555
556
  
  	if (mp->m_flags & XFS_MOUNT_RDONLY)
  		return -EROFS;
  
  	if (XFS_FORCED_SHUTDOWN(mp))
  		return -EIO;
31051c85b   Jan Kara   fs: Give dentry t...
557
  	return setattr_prepare(dentry, iattr);
69bca8074   Jan Kara   xfs: Propagate de...
558
559
560
561
562
563
  }
  
  /*
   * Set non-size attributes of an inode.
   *
   * Caution: The caller of this function is responsible for calling
31051c85b   Jan Kara   fs: Give dentry t...
564
   * setattr_prepare() or otherwise verifying the change is fine.
69bca8074   Jan Kara   xfs: Propagate de...
565
   */
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
566
567
568
569
570
571
572
573
574
575
576
  int
  xfs_setattr_nonsize(
  	struct xfs_inode	*ip,
  	struct iattr		*iattr,
  	int			flags)
  {
  	xfs_mount_t		*mp = ip->i_mount;
  	struct inode		*inode = VFS_I(ip);
  	int			mask = iattr->ia_valid;
  	xfs_trans_t		*tp;
  	int			error;
7aab1b288   Dwight Engen   xfs: convert kuid...
577
578
  	kuid_t			uid = GLOBAL_ROOT_UID, iuid = GLOBAL_ROOT_UID;
  	kgid_t			gid = GLOBAL_ROOT_GID, igid = GLOBAL_ROOT_GID;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
579
580
  	struct xfs_dquot	*udqp = NULL, *gdqp = NULL;
  	struct xfs_dquot	*olddquot1 = NULL, *olddquot2 = NULL;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
  	ASSERT((mask & ATTR_SIZE) == 0);
  
  	/*
  	 * If disk quotas is on, we make sure that the dquots do exist on disk,
  	 * before we start any other transactions. Trying to do this later
  	 * is messy. We don't care to take a readlock to look at the ids
  	 * in inode here, because we can't hold it across the trans_reserve.
  	 * If the IDs do change before we take the ilock, we're covered
  	 * because the i_*dquot fields will get updated anyway.
  	 */
  	if (XFS_IS_QUOTA_ON(mp) && (mask & (ATTR_UID|ATTR_GID))) {
  		uint	qflags = 0;
  
  		if ((mask & ATTR_UID) && XFS_IS_UQUOTA_ON(mp)) {
  			uid = iattr->ia_uid;
  			qflags |= XFS_QMOPT_UQUOTA;
  		} else {
7aab1b288   Dwight Engen   xfs: convert kuid...
598
  			uid = inode->i_uid;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
599
600
601
602
603
  		}
  		if ((mask & ATTR_GID) && XFS_IS_GQUOTA_ON(mp)) {
  			gid = iattr->ia_gid;
  			qflags |= XFS_QMOPT_GQUOTA;
  		}  else {
7aab1b288   Dwight Engen   xfs: convert kuid...
604
  			gid = inode->i_gid;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
605
606
607
608
609
610
611
612
613
  		}
  
  		/*
  		 * We take a reference when we initialize udqp and gdqp,
  		 * so it is important that we never blindly double trip on
  		 * the same variable. See xfs_create() for an example.
  		 */
  		ASSERT(udqp == NULL);
  		ASSERT(gdqp == NULL);
7aab1b288   Dwight Engen   xfs: convert kuid...
614
615
616
617
  		error = xfs_qm_vop_dqalloc(ip, xfs_kuid_to_uid(uid),
  					   xfs_kgid_to_gid(gid),
  					   xfs_get_projid(ip),
  					   qflags, &udqp, &gdqp, NULL);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
618
619
620
  		if (error)
  			return error;
  	}
253f4911f   Christoph Hellwig   xfs: better xfs_t...
621
  	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
622
  	if (error)
253f4911f   Christoph Hellwig   xfs: better xfs_t...
623
  		goto out_dqrele;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
624
625
  
  	xfs_ilock(ip, XFS_ILOCK_EXCL);
253f4911f   Christoph Hellwig   xfs: better xfs_t...
626
  	xfs_trans_ijoin(tp, ip, 0);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
627
628
629
630
631
632
633
634
635
636
637
  
  	/*
  	 * Change file ownership.  Must be the owner or privileged.
  	 */
  	if (mask & (ATTR_UID|ATTR_GID)) {
  		/*
  		 * These IDs could have changed since we last looked at them.
  		 * But, we're assured that if the ownership did change
  		 * while we didn't have the inode locked, inode's dquot(s)
  		 * would have changed also.
  		 */
7aab1b288   Dwight Engen   xfs: convert kuid...
638
639
  		iuid = inode->i_uid;
  		igid = inode->i_gid;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
640
641
642
643
644
645
646
647
  		gid = (mask & ATTR_GID) ? iattr->ia_gid : igid;
  		uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid;
  
  		/*
  		 * Do a quota reservation only if uid/gid is actually
  		 * going to change.
  		 */
  		if (XFS_IS_QUOTA_RUNNING(mp) &&
7aab1b288   Dwight Engen   xfs: convert kuid...
648
649
  		    ((XFS_IS_UQUOTA_ON(mp) && !uid_eq(iuid, uid)) ||
  		     (XFS_IS_GQUOTA_ON(mp) && !gid_eq(igid, gid)))) {
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
650
651
  			ASSERT(tp);
  			error = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp,
92f8ff73f   Chandra Seetharaman   xfs: Add pquota f...
652
  						NULL, capable(CAP_FOWNER) ?
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
653
654
  						XFS_QMOPT_FORCE_RES : 0);
  			if (error)	/* out of quota */
253f4911f   Christoph Hellwig   xfs: better xfs_t...
655
  				goto out_cancel;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
656
657
  		}
  	}
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
658
659
660
661
662
663
664
665
666
667
  	/*
  	 * Change file ownership.  Must be the owner or privileged.
  	 */
  	if (mask & (ATTR_UID|ATTR_GID)) {
  		/*
  		 * CAP_FSETID overrides the following restrictions:
  		 *
  		 * The set-user-ID and set-group-ID bits of a file will be
  		 * cleared upon successful return from chown()
  		 */
c19b3b05a   Dave Chinner   xfs: mode di_mode...
668
  		if ((inode->i_mode & (S_ISUID|S_ISGID)) &&
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
669
  		    !capable(CAP_FSETID))
c19b3b05a   Dave Chinner   xfs: mode di_mode...
670
  			inode->i_mode &= ~(S_ISUID|S_ISGID);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
671
672
673
674
675
  
  		/*
  		 * Change the ownerships and register quota modifications
  		 * in the transaction.
  		 */
7aab1b288   Dwight Engen   xfs: convert kuid...
676
  		if (!uid_eq(iuid, uid)) {
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
677
678
679
680
681
682
  			if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_UQUOTA_ON(mp)) {
  				ASSERT(mask & ATTR_UID);
  				ASSERT(udqp);
  				olddquot1 = xfs_qm_vop_chown(tp, ip,
  							&ip->i_udquot, udqp);
  			}
7aab1b288   Dwight Engen   xfs: convert kuid...
683
  			ip->i_d.di_uid = xfs_kuid_to_uid(uid);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
684
685
  			inode->i_uid = uid;
  		}
7aab1b288   Dwight Engen   xfs: convert kuid...
686
  		if (!gid_eq(igid, gid)) {
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
687
  			if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) {
5a01dd54f   Jie Liu   xfs: fix assertio...
688
689
  				ASSERT(xfs_sb_version_has_pquotino(&mp->m_sb) ||
  				       !XFS_IS_PQUOTA_ON(mp));
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
690
691
692
693
694
  				ASSERT(mask & ATTR_GID);
  				ASSERT(gdqp);
  				olddquot2 = xfs_qm_vop_chown(tp, ip,
  							&ip->i_gdquot, gdqp);
  			}
7aab1b288   Dwight Engen   xfs: convert kuid...
695
  			ip->i_d.di_gid = xfs_kgid_to_gid(gid);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
696
697
698
  			inode->i_gid = gid;
  		}
  	}
56c19e89b   Dave Chinner   xfs: kill suid/sg...
699
  	if (mask & ATTR_MODE)
0c3d88dfc   Christoph Hellwig   xfs: tiny xfs_set...
700
  		xfs_setattr_mode(ip, iattr);
c91c46c12   Christoph Hellwig   xfs: add xfs_seta...
701
702
  	if (mask & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME))
  		xfs_setattr_time(ip, iattr);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
703
704
  
  	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
ff6d6af23   Bill O'Donnell   xfs: per-filesyst...
705
  	XFS_STATS_INC(mp, xs_ig_attrchg);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
706
707
708
  
  	if (mp->m_flags & XFS_MOUNT_WSYNC)
  		xfs_trans_set_sync(tp);
70393313d   Christoph Hellwig   xfs: saner xfs_tr...
709
  	error = xfs_trans_commit(tp);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
710
711
712
713
714
715
716
717
718
719
720
721
  
  	xfs_iunlock(ip, XFS_ILOCK_EXCL);
  
  	/*
  	 * Release any dquot(s) the inode had kept before chown.
  	 */
  	xfs_qm_dqrele(olddquot1);
  	xfs_qm_dqrele(olddquot2);
  	xfs_qm_dqrele(udqp);
  	xfs_qm_dqrele(gdqp);
  
  	if (error)
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
722
  		return error;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
723
724
725
726
727
728
729
730
731
  
  	/*
  	 * XXX(hch): Updating the ACL entries is not atomic vs the i_mode
  	 * 	     update.  We could avoid this with linked transactions
  	 * 	     and passing down the transaction pointer all the way
  	 *	     to attr_set.  No previous user of the generic
  	 * 	     Posix ACL code seems to care about this issue either.
  	 */
  	if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) {
2451337dd   Dave Chinner   xfs: global error...
732
  		error = posix_acl_chmod(inode, inode->i_mode);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
733
  		if (error)
b474c7ae4   Eric Sandeen   xfs: Nuke XFS_ERR...
734
  			return error;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
735
736
737
  	}
  
  	return 0;
253f4911f   Christoph Hellwig   xfs: better xfs_t...
738
  out_cancel:
4906e2154   Christoph Hellwig   xfs: remove the f...
739
  	xfs_trans_cancel(tp);
253f4911f   Christoph Hellwig   xfs: better xfs_t...
740
  out_dqrele:
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
741
742
743
744
  	xfs_qm_dqrele(udqp);
  	xfs_qm_dqrele(gdqp);
  	return error;
  }
69bca8074   Jan Kara   xfs: Propagate de...
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
  int
  xfs_vn_setattr_nonsize(
  	struct dentry		*dentry,
  	struct iattr		*iattr)
  {
  	struct xfs_inode	*ip = XFS_I(d_inode(dentry));
  	int error;
  
  	trace_xfs_setattr(ip);
  
  	error = xfs_vn_change_ok(dentry, iattr);
  	if (error)
  		return error;
  	return xfs_setattr_nonsize(ip, iattr, 0);
  }
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
760
761
  /*
   * Truncate file.  Must have write permission and not be a directory.
69bca8074   Jan Kara   xfs: Propagate de...
762
763
   *
   * Caution: The caller of this function is responsible for calling
31051c85b   Jan Kara   fs: Give dentry t...
764
   * setattr_prepare() or otherwise verifying the change is fine.
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
765
766
767
768
   */
  int
  xfs_setattr_size(
  	struct xfs_inode	*ip,
76ca4c238   Christoph Hellwig   xfs: always take ...
769
  	struct iattr		*iattr)
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
770
771
772
  {
  	struct xfs_mount	*mp = ip->i_mount;
  	struct inode		*inode = VFS_I(ip);
673e8e597   Christoph Hellwig   xfs: remove xfs_i...
773
  	xfs_off_t		oldsize, newsize;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
774
775
  	struct xfs_trans	*tp;
  	int			error;
f38996f57   Christoph Hellwig   xfs: reduce ilock...
776
  	uint			lock_flags = 0;
5885ebda8   Dave Chinner   xfs: ensure trunc...
777
  	bool			did_zeroing = false;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
778

76ca4c238   Christoph Hellwig   xfs: always take ...
779
  	ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL));
e8e9ad42c   Dave Chinner   xfs: take i_mmap_...
780
  	ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL));
c19b3b05a   Dave Chinner   xfs: mode di_mode...
781
  	ASSERT(S_ISREG(inode->i_mode));
fe60a8a09   Christoph Hellwig   xfs: ensure corre...
782
783
  	ASSERT((iattr->ia_valid & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
  		ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
784

ce7ae151d   Christoph Hellwig   xfs: remove the i...
785
  	oldsize = inode->i_size;
673e8e597   Christoph Hellwig   xfs: remove xfs_i...
786
  	newsize = iattr->ia_size;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
787
788
789
  	/*
  	 * Short circuit the truncate case for zero length files.
  	 */
673e8e597   Christoph Hellwig   xfs: remove xfs_i...
790
  	if (newsize == 0 && oldsize == 0 && ip->i_d.di_nextents == 0) {
fe60a8a09   Christoph Hellwig   xfs: ensure corre...
791
  		if (!(iattr->ia_valid & (ATTR_CTIME|ATTR_MTIME)))
76ca4c238   Christoph Hellwig   xfs: always take ...
792
  			return 0;
681b12001   Christoph Hellwig   xfs: always log t...
793
794
795
796
  
  		/*
  		 * Use the regular setattr path to update the timestamps.
  		 */
681b12001   Christoph Hellwig   xfs: always log t...
797
798
  		iattr->ia_valid &= ~ATTR_SIZE;
  		return xfs_setattr_nonsize(ip, iattr, 0);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
799
800
801
802
803
  	}
  
  	/*
  	 * Make sure that the dquots are attached to the inode.
  	 */
f38996f57   Christoph Hellwig   xfs: reduce ilock...
804
  	error = xfs_qm_dqattach(ip, 0);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
805
  	if (error)
76ca4c238   Christoph Hellwig   xfs: always take ...
806
  		return error;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
807
808
  
  	/*
f0c6bcba7   Christoph Hellwig   xfs: reorder zero...
809
810
811
812
813
  	 * Wait for all direct I/O to complete.
  	 */
  	inode_dio_wait(inode);
  
  	/*
5885ebda8   Dave Chinner   xfs: ensure trunc...
814
815
816
817
818
  	 * File data changes must be complete before we start the transaction to
  	 * modify the inode.  This needs to be done before joining the inode to
  	 * the transaction because the inode cannot be unlocked once it is a
  	 * part of the transaction.
  	 *
f0c6bcba7   Christoph Hellwig   xfs: reorder zero...
819
820
821
  	 * Start with zeroing any data beyond EOF that we may expose on file
  	 * extension, or zeroing out the rest of the block on a downward
  	 * truncate.
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
822
  	 */
673e8e597   Christoph Hellwig   xfs: remove xfs_i...
823
  	if (newsize > oldsize) {
5885ebda8   Dave Chinner   xfs: ensure trunc...
824
  		error = xfs_zero_eof(ip, newsize, oldsize, &did_zeroing);
f0c6bcba7   Christoph Hellwig   xfs: reorder zero...
825
  	} else {
459f0fbc2   Christoph Hellwig   xfs: use iomap in...
826
827
  		error = iomap_truncate_page(inode, newsize, &did_zeroing,
  				&xfs_iomap_ops);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
828
  	}
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
829

f0c6bcba7   Christoph Hellwig   xfs: reorder zero...
830
831
  	if (error)
  		return error;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
832
833
834
835
836
  	/*
  	 * We are going to log the inode size change in this transaction so
  	 * any previous writes that are beyond the on disk EOF and the new
  	 * EOF that have not been written out need to be written here.  If we
  	 * do not write the data out, we expose ourselves to the null files
5885ebda8   Dave Chinner   xfs: ensure trunc...
837
838
  	 * problem. Note that this includes any block zeroing we did above;
  	 * otherwise those blocks may not be zeroed after a crash.
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
839
  	 */
68a9f5e70   Christoph Hellwig   xfs: implement io...
840
841
  	if (did_zeroing ||
  	    (newsize > ip->i_d.di_size && oldsize != ip->i_d.di_size)) {
2451337dd   Dave Chinner   xfs: global error...
842
  		error = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
4bc1ea6b8   Dave Chinner   xfs: remove xfs_f...
843
  						      ip->i_d.di_size, newsize);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
844
  		if (error)
76ca4c238   Christoph Hellwig   xfs: always take ...
845
  			return error;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
846
  	}
49abc3a8f   Dave Chinner   xfs: truncate_set...
847
  	/*
0f9160b44   Dave Chinner   xfs: xfs_setattr_...
848
849
850
851
852
853
  	 * We've already locked out new page faults, so now we can safely remove
  	 * pages from the page cache knowing they won't get refaulted until we
  	 * drop the XFS_MMAP_EXCL lock after the extent manipulations are
  	 * complete. The truncate_setsize() call also cleans partial EOF page
  	 * PTEs on extending truncates and hence ensures sub-page block size
  	 * filesystems are correctly handled, too.
49abc3a8f   Dave Chinner   xfs: truncate_set...
854
  	 *
0f9160b44   Dave Chinner   xfs: xfs_setattr_...
855
856
857
  	 * We have to do all the page cache truncate work outside the
  	 * transaction context as the "lock" order is page lock->log space
  	 * reservation as defined by extent allocation in the writeback path.
253f4911f   Christoph Hellwig   xfs: better xfs_t...
858
  	 * Hence a truncate can fail with ENOMEM from xfs_trans_alloc(), but
0f9160b44   Dave Chinner   xfs: xfs_setattr_...
859
860
861
862
  	 * having already truncated the in-memory version of the file (i.e. made
  	 * user visible changes). There's not much we can do about this, except
  	 * to hope that the caller sees ENOMEM and retries the truncate
  	 * operation.
49abc3a8f   Dave Chinner   xfs: truncate_set...
863
  	 */
49abc3a8f   Dave Chinner   xfs: truncate_set...
864
  	truncate_setsize(inode, newsize);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
865

253f4911f   Christoph Hellwig   xfs: better xfs_t...
866
  	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
867
  	if (error)
253f4911f   Christoph Hellwig   xfs: better xfs_t...
868
  		return error;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
869

c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
870
  	lock_flags |= XFS_ILOCK_EXCL;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
871
  	xfs_ilock(ip, XFS_ILOCK_EXCL);
ddc3415ab   Christoph Hellwig   xfs: simplify xfs...
872
  	xfs_trans_ijoin(tp, ip, 0);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
873
874
875
876
877
878
879
880
881
882
883
  
  	/*
  	 * Only change the c/mtime if we are changing the size or we are
  	 * explicitly asked to change it.  This handles the semantic difference
  	 * between truncate() and ftruncate() as implemented in the VFS.
  	 *
  	 * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a
  	 * special case where we need to update the times despite not having
  	 * these flags set.  For all other operations the VFS set these flags
  	 * explicitly if it wants a timestamp update.
  	 */
fe60a8a09   Christoph Hellwig   xfs: ensure corre...
884
885
  	if (newsize != oldsize &&
  	    !(iattr->ia_valid & (ATTR_CTIME | ATTR_MTIME))) {
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
886
  		iattr->ia_ctime = iattr->ia_mtime =
c2050a454   Deepa Dinamani   fs: Replace curre...
887
  			current_time(inode);
fe60a8a09   Christoph Hellwig   xfs: ensure corre...
888
  		iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
889
  	}
673e8e597   Christoph Hellwig   xfs: remove xfs_i...
890
891
892
893
894
895
896
897
898
899
900
901
902
  	/*
  	 * The first thing we do is set the size to new_size permanently on
  	 * disk.  This way we don't have to worry about anyone ever being able
  	 * to look at the data being freed even in the face of a crash.
  	 * What we're getting around here is the case where we free a block, it
  	 * is allocated to another file, it is written to, and then we crash.
  	 * If the new data gets written to the file but the log buffers
  	 * containing the free and reallocation don't, then we'd end up with
  	 * garbage in the blocks being freed.  As long as we make the new size
  	 * permanent before actually freeing any blocks it doesn't matter if
  	 * they get written to.
  	 */
  	ip->i_d.di_size = newsize;
673e8e597   Christoph Hellwig   xfs: remove xfs_i...
903
904
905
906
  	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
  
  	if (newsize <= oldsize) {
  		error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, newsize);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
907
  		if (error)
4906e2154   Christoph Hellwig   xfs: remove the f...
908
  			goto out_trans_cancel;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
909
910
911
912
913
914
915
916
917
  
  		/*
  		 * Truncated "down", so we're removing references to old data
  		 * here - if we delay flushing for a long time, we expose
  		 * ourselves unduly to the notorious NULL files problem.  So,
  		 * we mark this inode and flush it when the file is closed,
  		 * and do not wait the usual (long) time for writeout.
  		 */
  		xfs_iflags_set(ip, XFS_ITRUNCATED);
27b528679   Brian Foster   xfs: add EOFBLOCK...
918
919
920
  
  		/* A truncate down always removes post-EOF blocks. */
  		xfs_inode_clear_eofblocks_tag(ip);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
921
  	}
fe60a8a09   Christoph Hellwig   xfs: ensure corre...
922
  	if (iattr->ia_valid & ATTR_MODE)
0c3d88dfc   Christoph Hellwig   xfs: tiny xfs_set...
923
  		xfs_setattr_mode(ip, iattr);
fe60a8a09   Christoph Hellwig   xfs: ensure corre...
924
  	if (iattr->ia_valid & (ATTR_ATIME|ATTR_CTIME|ATTR_MTIME))
c91c46c12   Christoph Hellwig   xfs: add xfs_seta...
925
  		xfs_setattr_time(ip, iattr);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
926
927
  
  	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
ff6d6af23   Bill O'Donnell   xfs: per-filesyst...
928
  	XFS_STATS_INC(mp, xs_ig_attrchg);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
929
930
931
  
  	if (mp->m_flags & XFS_MOUNT_WSYNC)
  		xfs_trans_set_sync(tp);
70393313d   Christoph Hellwig   xfs: saner xfs_tr...
932
  	error = xfs_trans_commit(tp);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
933
934
935
936
  out_unlock:
  	if (lock_flags)
  		xfs_iunlock(ip, lock_flags);
  	return error;
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
937
  out_trans_cancel:
4906e2154   Christoph Hellwig   xfs: remove the f...
938
  	xfs_trans_cancel(tp);
c4ed4243c   Christoph Hellwig   xfs: split xfs_se...
939
940
  	goto out_unlock;
  }
69bca8074   Jan Kara   xfs: Propagate de...
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
  int
  xfs_vn_setattr_size(
  	struct dentry		*dentry,
  	struct iattr		*iattr)
  {
  	struct xfs_inode	*ip = XFS_I(d_inode(dentry));
  	int error;
  
  	trace_xfs_setattr(ip);
  
  	error = xfs_vn_change_ok(dentry, iattr);
  	if (error)
  		return error;
  	return xfs_setattr_size(ip, iattr);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
956
  STATIC int
416c6d5bc   Nathan Scott   [XFS] Switch over...
957
  xfs_vn_setattr(
76ca4c238   Christoph Hellwig   xfs: always take ...
958
959
  	struct dentry		*dentry,
  	struct iattr		*iattr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
960
  {
76ca4c238   Christoph Hellwig   xfs: always take ...
961
962
963
  	int			error;
  
  	if (iattr->ia_valid & ATTR_SIZE) {
69bca8074   Jan Kara   xfs: Propagate de...
964
965
  		struct xfs_inode	*ip = XFS_I(d_inode(dentry));
  		uint			iolock = XFS_IOLOCK_EXCL;
781355c6e   Christoph Hellwig   xfs: recall pNFS ...
966
967
  
  		xfs_ilock(ip, iolock);
9ec3a646f   Linus Torvalds   Merge branch 'for...
968
  		error = xfs_break_layouts(d_inode(dentry), &iolock, true);
e8e9ad42c   Dave Chinner   xfs: take i_mmap_...
969
970
971
  		if (!error) {
  			xfs_ilock(ip, XFS_MMAPLOCK_EXCL);
  			iolock |= XFS_MMAPLOCK_EXCL;
69bca8074   Jan Kara   xfs: Propagate de...
972
  			error = xfs_vn_setattr_size(dentry, iattr);
e8e9ad42c   Dave Chinner   xfs: take i_mmap_...
973
  		}
781355c6e   Christoph Hellwig   xfs: recall pNFS ...
974
  		xfs_iunlock(ip, iolock);
76ca4c238   Christoph Hellwig   xfs: always take ...
975
  	} else {
69bca8074   Jan Kara   xfs: Propagate de...
976
  		error = xfs_vn_setattr_nonsize(dentry, iattr);
76ca4c238   Christoph Hellwig   xfs: always take ...
977
  	}
2451337dd   Dave Chinner   xfs: global error...
978
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
979
  }
69ff28261   Christoph Hellwig   xfs: implement ->...
980
981
982
983
984
985
986
987
988
989
990
991
  STATIC int
  xfs_vn_update_time(
  	struct inode		*inode,
  	struct timespec		*now,
  	int			flags)
  {
  	struct xfs_inode	*ip = XFS_I(inode);
  	struct xfs_mount	*mp = ip->i_mount;
  	struct xfs_trans	*tp;
  	int			error;
  
  	trace_xfs_update_time(ip);
253f4911f   Christoph Hellwig   xfs: better xfs_t...
992
993
  	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_fsyncts, 0, 0, 0, &tp);
  	if (error)
2451337dd   Dave Chinner   xfs: global error...
994
  		return error;
69ff28261   Christoph Hellwig   xfs: implement ->...
995
996
  
  	xfs_ilock(ip, XFS_ILOCK_EXCL);
3987848c7   Dave Chinner   xfs: remove times...
997
  	if (flags & S_CTIME)
69ff28261   Christoph Hellwig   xfs: implement ->...
998
  		inode->i_ctime = *now;
3987848c7   Dave Chinner   xfs: remove times...
999
  	if (flags & S_MTIME)
69ff28261   Christoph Hellwig   xfs: implement ->...
1000
  		inode->i_mtime = *now;
3987848c7   Dave Chinner   xfs: remove times...
1001
  	if (flags & S_ATIME)
69ff28261   Christoph Hellwig   xfs: implement ->...
1002
  		inode->i_atime = *now;
3987848c7   Dave Chinner   xfs: remove times...
1003

69ff28261   Christoph Hellwig   xfs: implement ->...
1004
1005
  	xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
  	xfs_trans_log_inode(tp, ip, XFS_ILOG_TIMESTAMP);
70393313d   Christoph Hellwig   xfs: saner xfs_tr...
1006
  	return xfs_trans_commit(tp);
69ff28261   Christoph Hellwig   xfs: implement ->...
1007
  }
f35642e2f   Eric Sandeen   [XFS] Hook up the...
1008
1009
1010
1011
1012
1013
1014
  STATIC int
  xfs_vn_fiemap(
  	struct inode		*inode,
  	struct fiemap_extent_info *fieinfo,
  	u64			start,
  	u64			length)
  {
f35642e2f   Eric Sandeen   [XFS] Hook up the...
1015
  	int			error;
d2bb140e9   Christoph Hellwig   xfs: use iomap fi...
1016
  	xfs_ilock(XFS_I(inode), XFS_IOLOCK_SHARED);
1d4795e7b   Christoph Hellwig   xfs: (re-)impleme...
1017
1018
1019
1020
1021
1022
1023
1024
  	if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) {
  		fieinfo->fi_flags &= ~FIEMAP_FLAG_XATTR;
  		error = iomap_fiemap(inode, fieinfo, start, length,
  				&xfs_xattr_iomap_ops);
  	} else {
  		error = iomap_fiemap(inode, fieinfo, start, length,
  				&xfs_iomap_ops);
  	}
d2bb140e9   Christoph Hellwig   xfs: use iomap fi...
1025
  	xfs_iunlock(XFS_I(inode), XFS_IOLOCK_SHARED);
f35642e2f   Eric Sandeen   [XFS] Hook up the...
1026

d2bb140e9   Christoph Hellwig   xfs: use iomap fi...
1027
  	return error;
f35642e2f   Eric Sandeen   [XFS] Hook up the...
1028
  }
99b6436bc   Zhi Yong Wu   xfs: add O_TMPFIL...
1029
1030
1031
1032
1033
1034
  STATIC int
  xfs_vn_tmpfile(
  	struct inode	*dir,
  	struct dentry	*dentry,
  	umode_t		mode)
  {
d540e43b0   Brian Foster   xfs: initialize d...
1035
  	return xfs_generic_create(dir, dentry, mode, 0, true);
99b6436bc   Zhi Yong Wu   xfs: add O_TMPFIL...
1036
  }
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1037
  static const struct inode_operations xfs_inode_operations = {
4e34e719e   Christoph Hellwig   fs: take the ACL ...
1038
  	.get_acl		= xfs_get_acl,
2401dc297   Christoph Hellwig   xfs: use generic ...
1039
  	.set_acl		= xfs_set_acl,
416c6d5bc   Nathan Scott   [XFS] Switch over...
1040
1041
  	.getattr		= xfs_vn_getattr,
  	.setattr		= xfs_vn_setattr,
416c6d5bc   Nathan Scott   [XFS] Switch over...
1042
  	.listxattr		= xfs_vn_listxattr,
f35642e2f   Eric Sandeen   [XFS] Hook up the...
1043
  	.fiemap			= xfs_vn_fiemap,
69ff28261   Christoph Hellwig   xfs: implement ->...
1044
  	.update_time		= xfs_vn_update_time,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1045
  };
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1046
  static const struct inode_operations xfs_dir_inode_operations = {
416c6d5bc   Nathan Scott   [XFS] Switch over...
1047
1048
1049
1050
1051
1052
  	.create			= xfs_vn_create,
  	.lookup			= xfs_vn_lookup,
  	.link			= xfs_vn_link,
  	.unlink			= xfs_vn_unlink,
  	.symlink		= xfs_vn_symlink,
  	.mkdir			= xfs_vn_mkdir,
8f112e3bc   Christoph Hellwig   [XFS] Merge xfs_r...
1053
1054
1055
1056
1057
1058
1059
  	/*
  	 * Yes, XFS uses the same method for rmdir and unlink.
  	 *
  	 * There are some subtile differences deeper in the code,
  	 * but we use S_ISDIR to check for those.
  	 */
  	.rmdir			= xfs_vn_unlink,
416c6d5bc   Nathan Scott   [XFS] Switch over...
1060
  	.mknod			= xfs_vn_mknod,
2773bf00a   Miklos Szeredi   fs: rename "renam...
1061
  	.rename			= xfs_vn_rename,
4e34e719e   Christoph Hellwig   fs: take the ACL ...
1062
  	.get_acl		= xfs_get_acl,
2401dc297   Christoph Hellwig   xfs: use generic ...
1063
  	.set_acl		= xfs_set_acl,
416c6d5bc   Nathan Scott   [XFS] Switch over...
1064
1065
  	.getattr		= xfs_vn_getattr,
  	.setattr		= xfs_vn_setattr,
416c6d5bc   Nathan Scott   [XFS] Switch over...
1066
  	.listxattr		= xfs_vn_listxattr,
69ff28261   Christoph Hellwig   xfs: implement ->...
1067
  	.update_time		= xfs_vn_update_time,
99b6436bc   Zhi Yong Wu   xfs: add O_TMPFIL...
1068
  	.tmpfile		= xfs_vn_tmpfile,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1069
  };
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1070
  static const struct inode_operations xfs_dir_ci_inode_operations = {
384f3ced0   Barry Naujok   [XFS] Return case...
1071
1072
1073
1074
1075
1076
  	.create			= xfs_vn_create,
  	.lookup			= xfs_vn_ci_lookup,
  	.link			= xfs_vn_link,
  	.unlink			= xfs_vn_unlink,
  	.symlink		= xfs_vn_symlink,
  	.mkdir			= xfs_vn_mkdir,
8f112e3bc   Christoph Hellwig   [XFS] Merge xfs_r...
1077
1078
1079
1080
1081
1082
1083
  	/*
  	 * Yes, XFS uses the same method for rmdir and unlink.
  	 *
  	 * There are some subtile differences deeper in the code,
  	 * but we use S_ISDIR to check for those.
  	 */
  	.rmdir			= xfs_vn_unlink,
384f3ced0   Barry Naujok   [XFS] Return case...
1084
  	.mknod			= xfs_vn_mknod,
2773bf00a   Miklos Szeredi   fs: rename "renam...
1085
  	.rename			= xfs_vn_rename,
4e34e719e   Christoph Hellwig   fs: take the ACL ...
1086
  	.get_acl		= xfs_get_acl,
2401dc297   Christoph Hellwig   xfs: use generic ...
1087
  	.set_acl		= xfs_set_acl,
384f3ced0   Barry Naujok   [XFS] Return case...
1088
1089
  	.getattr		= xfs_vn_getattr,
  	.setattr		= xfs_vn_setattr,
384f3ced0   Barry Naujok   [XFS] Return case...
1090
  	.listxattr		= xfs_vn_listxattr,
69ff28261   Christoph Hellwig   xfs: implement ->...
1091
  	.update_time		= xfs_vn_update_time,
99b6436bc   Zhi Yong Wu   xfs: add O_TMPFIL...
1092
  	.tmpfile		= xfs_vn_tmpfile,
384f3ced0   Barry Naujok   [XFS] Return case...
1093
  };
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1094
  static const struct inode_operations xfs_symlink_inode_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1095
  	.readlink		= generic_readlink,
6b2553918   Al Viro   replace ->follow_...
1096
  	.get_link		= xfs_vn_get_link,
416c6d5bc   Nathan Scott   [XFS] Switch over...
1097
1098
  	.getattr		= xfs_vn_getattr,
  	.setattr		= xfs_vn_setattr,
416c6d5bc   Nathan Scott   [XFS] Switch over...
1099
  	.listxattr		= xfs_vn_listxattr,
69ff28261   Christoph Hellwig   xfs: implement ->...
1100
  	.update_time		= xfs_vn_update_time,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1101
  };
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1102

30ee052e1   Christoph Hellwig   xfs: optimize inl...
1103
1104
1105
1106
1107
  static const struct inode_operations xfs_inline_symlink_inode_operations = {
  	.readlink		= generic_readlink,
  	.get_link		= xfs_vn_get_link_inline,
  	.getattr		= xfs_vn_getattr,
  	.setattr		= xfs_vn_setattr,
30ee052e1   Christoph Hellwig   xfs: optimize inl...
1108
1109
1110
  	.listxattr		= xfs_vn_listxattr,
  	.update_time		= xfs_vn_update_time,
  };
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1111
1112
1113
1114
1115
  STATIC void
  xfs_diflags_to_iflags(
  	struct inode		*inode,
  	struct xfs_inode	*ip)
  {
cbe4dab11   Dave Chinner   xfs: add initial ...
1116
1117
1118
1119
1120
1121
  	uint16_t		flags = ip->i_d.di_flags;
  
  	inode->i_flags &= ~(S_IMMUTABLE | S_APPEND | S_SYNC |
  			    S_NOATIME | S_DAX);
  
  	if (flags & XFS_DIFLAG_IMMUTABLE)
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1122
  		inode->i_flags |= S_IMMUTABLE;
cbe4dab11   Dave Chinner   xfs: add initial ...
1123
  	if (flags & XFS_DIFLAG_APPEND)
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1124
  		inode->i_flags |= S_APPEND;
cbe4dab11   Dave Chinner   xfs: add initial ...
1125
  	if (flags & XFS_DIFLAG_SYNC)
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1126
  		inode->i_flags |= S_SYNC;
cbe4dab11   Dave Chinner   xfs: add initial ...
1127
  	if (flags & XFS_DIFLAG_NOATIME)
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1128
  		inode->i_flags |= S_NOATIME;
db10c697b   Dave Chinner   xfs: S_DAX is onl...
1129
  	if (S_ISREG(inode->i_mode) &&
644854373   Dave Chinner   xfs: XFS_DIFLAG2_...
1130
  	    ip->i_mount->m_sb.sb_blocksize == PAGE_SIZE &&
4f435ebe7   Darrick J. Wong   xfs: don't mix re...
1131
  	    !xfs_is_reflink_inode(ip) &&
db10c697b   Dave Chinner   xfs: S_DAX is onl...
1132
1133
  	    (ip->i_mount->m_flags & XFS_MOUNT_DAX ||
  	     ip->i_d.di_flags2 & XFS_DIFLAG2_DAX))
cbe4dab11   Dave Chinner   xfs: add initial ...
1134
  		inode->i_flags |= S_DAX;
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1135
1136
1137
  }
  
  /*
2b3d1d41b   Christoph Hellwig   xfs: set up inode...
1138
   * Initialize the Linux inode.
bf904248a   David Chinner   [XFS] Combine the...
1139
   *
58c904734   Dave Chinner   xfs: inodes are n...
1140
1141
1142
1143
   * When reading existing inodes from disk this is called directly from xfs_iget,
   * when creating a new inode it is called from xfs_ialloc after setting up the
   * inode. These callers have different criteria for clearing XFS_INEW, so leave
   * it up to the caller to deal with unlocking the inode appropriately.
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1144
1145
1146
1147
1148
   */
  void
  xfs_setup_inode(
  	struct xfs_inode	*ip)
  {
bf904248a   David Chinner   [XFS] Combine the...
1149
  	struct inode		*inode = &ip->i_vnode;
ad22c7a04   Dave Chinner   xfs: prevent stac...
1150
  	gfp_t			gfp_mask;
bf904248a   David Chinner   [XFS] Combine the...
1151
1152
  
  	inode->i_ino = ip->i_ino;
eaff8079d   Christoph Hellwig   kill I_LOCK
1153
  	inode->i_state = I_NEW;
646ec4615   Christoph Hellwig   fs: remove inode_...
1154
1155
  
  	inode_sb_list_add(inode);
c6f6cd060   Christoph Hellwig   xfs: use hlist_ad...
1156
1157
  	/* make the inode look hashed for the writeback code */
  	hlist_add_fake(&inode->i_hash);
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1158

7aab1b288   Dwight Engen   xfs: convert kuid...
1159
1160
  	inode->i_uid    = xfs_uid_to_kuid(ip->i_d.di_uid);
  	inode->i_gid    = xfs_gid_to_kgid(ip->i_d.di_gid);
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
  
  	switch (inode->i_mode & S_IFMT) {
  	case S_IFBLK:
  	case S_IFCHR:
  		inode->i_rdev =
  			MKDEV(sysv_major(ip->i_df.if_u2.if_rdev) & 0x1ff,
  			      sysv_minor(ip->i_df.if_u2.if_rdev));
  		break;
  	default:
  		inode->i_rdev = 0;
  		break;
  	}
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1173
  	i_size_write(inode, ip->i_d.di_size);
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1174
  	xfs_diflags_to_iflags(inode, ip);
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1175

2b3d1d41b   Christoph Hellwig   xfs: set up inode...
1176
  	if (S_ISDIR(inode->i_mode)) {
93a8614e3   Dave Chinner   xfs: fix director...
1177
  		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_dir_ilock_class);
32c5483a8   Dave Chinner   xfs: abstract the...
1178
  		ip->d_ops = ip->i_mount->m_dir_inode_ops;
2b3d1d41b   Christoph Hellwig   xfs: set up inode...
1179
1180
1181
  	} else {
  		ip->d_ops = ip->i_mount->m_nondir_inode_ops;
  		lockdep_set_class(&ip->i_lock.mr_lock, &xfs_nondir_ilock_class);
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1182
  	}
510792ee2   Christoph Hellwig   xfs: optimize the...
1183
  	/*
ad22c7a04   Dave Chinner   xfs: prevent stac...
1184
1185
1186
1187
1188
1189
1190
1191
  	 * Ensure all page cache allocations are done from GFP_NOFS context to
  	 * prevent direct reclaim recursion back into the filesystem and blowing
  	 * stacks or deadlocking.
  	 */
  	gfp_mask = mapping_gfp_mask(inode->i_mapping);
  	mapping_set_gfp_mask(inode->i_mapping, (gfp_mask & ~(__GFP_FS)));
  
  	/*
510792ee2   Christoph Hellwig   xfs: optimize the...
1192
1193
1194
1195
1196
  	 * If there is no attribute fork no ACL can exist on this inode,
  	 * and it can't have any file capabilities attached to it either.
  	 */
  	if (!XFS_IFORK_Q(ip)) {
  		inode_has_no_xattr(inode);
6311b1080   Christoph Hellwig   xfs: cache negati...
1197
  		cache_no_acl(inode);
510792ee2   Christoph Hellwig   xfs: optimize the...
1198
  	}
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1199
  }
2b3d1d41b   Christoph Hellwig   xfs: set up inode...
1200
1201
1202
1203
1204
1205
  
  void
  xfs_setup_iops(
  	struct xfs_inode	*ip)
  {
  	struct inode		*inode = &ip->i_vnode;
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
  	switch (inode->i_mode & S_IFMT) {
  	case S_IFREG:
  		inode->i_op = &xfs_inode_operations;
  		inode->i_fop = &xfs_file_operations;
  		inode->i_mapping->a_ops = &xfs_address_space_operations;
  		break;
  	case S_IFDIR:
  		if (xfs_sb_version_hasasciici(&XFS_M(inode->i_sb)->m_sb))
  			inode->i_op = &xfs_dir_ci_inode_operations;
  		else
  			inode->i_op = &xfs_dir_inode_operations;
  		inode->i_fop = &xfs_dir_file_operations;
  		break;
  	case S_IFLNK:
30ee052e1   Christoph Hellwig   xfs: optimize inl...
1220
1221
1222
1223
  		if (ip->i_df.if_flags & XFS_IFINLINE)
  			inode->i_op = &xfs_inline_symlink_inode_operations;
  		else
  			inode->i_op = &xfs_symlink_inode_operations;
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1224
1225
1226
1227
1228
1229
  		break;
  	default:
  		inode->i_op = &xfs_inode_operations;
  		init_special_inode(inode, inode->i_mode, inode->i_rdev);
  		break;
  	}
41be8bed1   Christoph Hellwig   [XFS] sanitize xf...
1230
  }