Blame view

fs/gfs2/ops_inode.c 30.6 KB
b3b94faa5   David Teigland   [GFS2] The core o...
1
2
  /*
   * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3a8a9a103   Steven Whitehouse   [GFS2] Update cop...
3
   * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
b3b94faa5   David Teigland   [GFS2] The core o...
4
5
6
   *
   * This copyrighted material is made available to anyone wishing to use,
   * modify, copy, or redistribute it subject to the terms and conditions
e9fc2aa09   Steven Whitehouse   [GFS2] Update cop...
7
   * of the GNU General Public License version 2.
b3b94faa5   David Teigland   [GFS2] The core o...
8
   */
b3b94faa5   David Teigland   [GFS2] The core o...
9
10
11
12
13
  #include <linux/slab.h>
  #include <linux/spinlock.h>
  #include <linux/completion.h>
  #include <linux/buffer_head.h>
  #include <linux/namei.h>
b3b94faa5   David Teigland   [GFS2] The core o...
14
15
16
  #include <linux/mm.h>
  #include <linux/xattr.h>
  #include <linux/posix_acl.h>
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
17
  #include <linux/gfs2_ondisk.h>
71b86f562   Steven Whitehouse   [GFS2] Further up...
18
  #include <linux/crc32.h>
e9079cce2   Steven Whitehouse   GFS2: Support for...
19
  #include <linux/fiemap.h>
b3b94faa5   David Teigland   [GFS2] The core o...
20
21
22
  #include <asm/uaccess.h>
  
  #include "gfs2.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
23
  #include "incore.h"
b3b94faa5   David Teigland   [GFS2] The core o...
24
25
26
  #include "acl.h"
  #include "bmap.h"
  #include "dir.h"
307cf6e63   Steven Whitehouse   GFS2: Rename eatt...
27
  #include "xattr.h"
b3b94faa5   David Teigland   [GFS2] The core o...
28
29
30
  #include "glock.h"
  #include "inode.h"
  #include "meta_io.h"
b3b94faa5   David Teigland   [GFS2] The core o...
31
32
33
  #include "quota.h"
  #include "rgrp.h"
  #include "trans.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
34
  #include "util.h"
b27605837   Steven Whitehouse   GFS2: Rationalise...
35
  #include "super.h"
b3b94faa5   David Teigland   [GFS2] The core o...
36
37
38
39
40
41
42
43
44
45
46
47
48
  
  /**
   * gfs2_create - Create a file
   * @dir: The directory in which to create the file
   * @dentry: The dentry of the new file
   * @mode: The mode of the new file
   *
   * Returns: errno
   */
  
  static int gfs2_create(struct inode *dir, struct dentry *dentry,
  		       int mode, struct nameidata *nd)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
49
50
  	struct gfs2_inode *dip = GFS2_I(dir);
  	struct gfs2_sbd *sdp = GFS2_SB(dir);
b3b94faa5   David Teigland   [GFS2] The core o...
51
52
  	struct gfs2_holder ghs[2];
  	struct inode *inode;
b3b94faa5   David Teigland   [GFS2] The core o...
53

b3b94faa5   David Teigland   [GFS2] The core o...
54
55
56
  	gfs2_holder_init(dip->i_gl, 0, 0, ghs);
  
  	for (;;) {
e7f14f4d0   Steven Whitehouse   [GFS2] Shrink gfs...
57
  		inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0);
7359a19cc   Steven Whitehouse   [GFS2] Fix for ro...
58
  		if (!IS_ERR(inode)) {
b3b94faa5   David Teigland   [GFS2] The core o...
59
  			gfs2_trans_end(sdp);
6dbd82248   Steven Whitehouse   [GFS2] Reduce ino...
60
  			if (dip->i_alloc->al_rgd)
b3b94faa5   David Teigland   [GFS2] The core o...
61
62
63
64
  				gfs2_inplace_release(dip);
  			gfs2_quota_unlock(dip);
  			gfs2_alloc_put(dip);
  			gfs2_glock_dq_uninit_m(2, ghs);
3a8476dda   Steven Whitehouse   [GFS2] Remove deb...
65
  			mark_inode_dirty(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
66
  			break;
7359a19cc   Steven Whitehouse   [GFS2] Fix for ro...
67
  		} else if (PTR_ERR(inode) != -EEXIST ||
3516586a4   Al Viro   [PATCH] make O_EX...
68
  			   (nd && nd->flags & LOOKUP_EXCL)) {
b3b94faa5   David Teigland   [GFS2] The core o...
69
  			gfs2_holder_uninit(ghs);
7359a19cc   Steven Whitehouse   [GFS2] Fix for ro...
70
  			return PTR_ERR(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
71
  		}
a569c711f   Al Viro   [PATCH] don't pas...
72
  		inode = gfs2_lookupi(dir, &dentry->d_name, 0);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
73
74
  		if (inode) {
  			if (!IS_ERR(inode)) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
75
76
77
78
79
80
  				gfs2_holder_uninit(ghs);
  				break;
  			} else {
  				gfs2_holder_uninit(ghs);
  				return PTR_ERR(inode);
  			}
b3b94faa5   David Teigland   [GFS2] The core o...
81
82
  		}
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
83
  	d_instantiate(dentry, inode);
b3b94faa5   David Teigland   [GFS2] The core o...
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
  
  	return 0;
  }
  
  /**
   * gfs2_lookup - Look up a filename in a directory and return its inode
   * @dir: The directory inode
   * @dentry: The dentry of the new inode
   * @nd: passed from Linux VFS, ignored by us
   *
   * Called by the VFS layer. Lock dir and call gfs2_lookupi()
   *
   * Returns: errno
   */
  
  static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry,
  				  struct nameidata *nd)
  {
b3b94faa5   David Teigland   [GFS2] The core o...
102
  	struct inode *inode = NULL;
b3b94faa5   David Teigland   [GFS2] The core o...
103

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
104
  	dentry->d_op = &gfs2_dops;
b3b94faa5   David Teigland   [GFS2] The core o...
105

a569c711f   Al Viro   [PATCH] don't pas...
106
  	inode = gfs2_lookupi(dir, &dentry->d_name, 0);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
107
  	if (inode && IS_ERR(inode))
e231c2ee6   David Howells   Convert ERR_PTR(P...
108
  		return ERR_CAST(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
109

9656b2c14   Steven Whitehouse   [GFS2] Fix proble...
110
111
112
113
114
115
116
117
118
119
  	if (inode) {
  		struct gfs2_glock *gl = GFS2_I(inode)->i_gl;
  		struct gfs2_holder gh;
  		int error;
  		error = gfs2_glock_nq_init(gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
  		if (error) {
  			iput(inode);
  			return ERR_PTR(error);
  		}
  		gfs2_glock_dq_uninit(&gh);
b3b94faa5   David Teigland   [GFS2] The core o...
120
  		return d_splice_alias(inode, dentry);
9656b2c14   Steven Whitehouse   [GFS2] Fix proble...
121
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  	d_add(dentry, inode);
  
  	return NULL;
  }
  
  /**
   * gfs2_link - Link to a file
   * @old_dentry: The inode to link
   * @dir: Add link to this directory
   * @dentry: The name of the link
   *
   * Link the inode in "old_dentry" into the directory "dir" with the
   * name in "dentry".
   *
   * Returns: errno
   */
  
  static int gfs2_link(struct dentry *old_dentry, struct inode *dir,
  		     struct dentry *dentry)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
142
143
  	struct gfs2_inode *dip = GFS2_I(dir);
  	struct gfs2_sbd *sdp = GFS2_SB(dir);
b3b94faa5   David Teigland   [GFS2] The core o...
144
  	struct inode *inode = old_dentry->d_inode;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
145
  	struct gfs2_inode *ip = GFS2_I(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
146
147
148
  	struct gfs2_holder ghs[2];
  	int alloc_required;
  	int error;
b60623c23   Steven Whitehouse   [GFS2] Shrink gfs...
149
  	if (S_ISDIR(inode->i_mode))
b3b94faa5   David Teigland   [GFS2] The core o...
150
151
152
153
  		return -EPERM;
  
  	gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
  	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
72dbf4790   Bob Peterson   GFS2: rm on multi...
154
155
156
157
158
  	error = gfs2_glock_nq(ghs); /* parent */
  	if (error)
  		goto out_parent;
  
  	error = gfs2_glock_nq(ghs + 1); /* child */
b3b94faa5   David Teigland   [GFS2] The core o...
159
  	if (error)
72dbf4790   Bob Peterson   GFS2: rm on multi...
160
  		goto out_child;
b3b94faa5   David Teigland   [GFS2] The core o...
161

f58ba8891   Miklos Szeredi   [GFS2] don't call...
162
  	error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC);
b3b94faa5   David Teigland   [GFS2] The core o...
163
164
  	if (error)
  		goto out_gunlock;
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
165
  	error = gfs2_dir_check(dir, &dentry->d_name, NULL);
b3b94faa5   David Teigland   [GFS2] The core o...
166
167
168
169
170
171
172
173
174
175
  	switch (error) {
  	case -ENOENT:
  		break;
  	case 0:
  		error = -EEXIST;
  	default:
  		goto out_gunlock;
  	}
  
  	error = -EINVAL;
4f56110a0   Steven Whitehouse   [GFS2] Shrink gfs...
176
  	if (!dip->i_inode.i_nlink)
b3b94faa5   David Teigland   [GFS2] The core o...
177
178
  		goto out_gunlock;
  	error = -EFBIG;
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
179
  	if (dip->i_entries == (u32)-1)
b3b94faa5   David Teigland   [GFS2] The core o...
180
181
182
183
184
  		goto out_gunlock;
  	error = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
  		goto out_gunlock;
  	error = -EINVAL;
4f56110a0   Steven Whitehouse   [GFS2] Shrink gfs...
185
  	if (!ip->i_inode.i_nlink)
b3b94faa5   David Teigland   [GFS2] The core o...
186
187
  		goto out_gunlock;
  	error = -EMLINK;
4f56110a0   Steven Whitehouse   [GFS2] Shrink gfs...
188
  	if (ip->i_inode.i_nlink == (u32)-1)
b3b94faa5   David Teigland   [GFS2] The core o...
189
  		goto out_gunlock;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
190
191
  	alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name);
  	if (error < 0)
b3b94faa5   David Teigland   [GFS2] The core o...
192
  		goto out_gunlock;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
193
  	error = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
194
195
196
  
  	if (alloc_required) {
  		struct gfs2_alloc *al = gfs2_alloc_get(dip);
182fe5abd   Cyrill Gorcunov   [GFS2] possible n...
197
198
199
200
  		if (!al) {
  			error = -ENOMEM;
  			goto out_gunlock;
  		}
b3b94faa5   David Teigland   [GFS2] The core o...
201

d82661d96   Steven Whitehouse   [GFS2] Streamline...
202
  		error = gfs2_quota_lock_check(dip);
b3b94faa5   David Teigland   [GFS2] The core o...
203
204
  		if (error)
  			goto out_alloc;
b3b94faa5   David Teigland   [GFS2] The core o...
205
206
207
208
209
  		al->al_requested = sdp->sd_max_dirres;
  
  		error = gfs2_inplace_reserve(dip);
  		if (error)
  			goto out_gunlock_q;
1b50259bc   Steven Whitehouse   [GFS2] Drop log l...
210
  		error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
bb8d8a6f5   Steven Whitehouse   [GFS2] Fix sign p...
211
  					 al->al_rgd->rd_length +
b3b94faa5   David Teigland   [GFS2] The core o...
212
213
214
215
216
217
218
219
220
  					 2 * RES_DINODE + RES_STATFS +
  					 RES_QUOTA, 0);
  		if (error)
  			goto out_ipres;
  	} else {
  		error = gfs2_trans_begin(sdp, 2 * RES_DINODE + RES_LEAF, 0);
  		if (error)
  			goto out_ipres;
  	}
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
221
  	error = gfs2_dir_add(dir, &dentry->d_name, ip, IF2DT(inode->i_mode));
b3b94faa5   David Teigland   [GFS2] The core o...
222
223
224
225
  	if (error)
  		goto out_end_trans;
  
  	error = gfs2_change_nlink(ip, +1);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
226
  out_end_trans:
b3b94faa5   David Teigland   [GFS2] The core o...
227
  	gfs2_trans_end(sdp);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
228
  out_ipres:
b3b94faa5   David Teigland   [GFS2] The core o...
229
230
  	if (alloc_required)
  		gfs2_inplace_release(dip);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
231
  out_gunlock_q:
b3b94faa5   David Teigland   [GFS2] The core o...
232
233
  	if (alloc_required)
  		gfs2_quota_unlock(dip);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
234
  out_alloc:
b3b94faa5   David Teigland   [GFS2] The core o...
235
236
  	if (alloc_required)
  		gfs2_alloc_put(dip);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
237
  out_gunlock:
72dbf4790   Bob Peterson   GFS2: rm on multi...
238
239
240
241
  	gfs2_glock_dq(ghs + 1);
  out_child:
  	gfs2_glock_dq(ghs);
  out_parent:
b3b94faa5   David Teigland   [GFS2] The core o...
242
243
  	gfs2_holder_uninit(ghs);
  	gfs2_holder_uninit(ghs + 1);
b3b94faa5   David Teigland   [GFS2] The core o...
244
  	if (!error) {
29937ac6c   Steven Whitehouse   [GFS2] Fixes to s...
245
  		atomic_inc(&inode->i_count);
b3b94faa5   David Teigland   [GFS2] The core o...
246
247
248
  		d_instantiate(dentry, inode);
  		mark_inode_dirty(inode);
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
249
250
  	return error;
  }
87ec21741   Steven Whitehouse   GFS2: Move gfs2_u...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
  /*
   * gfs2_unlink_ok - check to see that a inode is still in a directory
   * @dip: the directory
   * @name: the name of the file
   * @ip: the inode
   *
   * Assumes that the lock on (at least) @dip is held.
   *
   * Returns: 0 if the parent/child relationship is correct, errno if it isn't
   */
  
  static int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
  			  const struct gfs2_inode *ip)
  {
  	int error;
  
  	if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode))
  		return -EPERM;
  
  	if ((dip->i_inode.i_mode & S_ISVTX) &&
  	    dip->i_inode.i_uid != current_fsuid() &&
  	    ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER))
  		return -EPERM;
  
  	if (IS_APPEND(&dip->i_inode))
  		return -EPERM;
  
  	error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC);
  	if (error)
  		return error;
  
  	error = gfs2_dir_check(&dip->i_inode, name, ip);
  	if (error)
  		return error;
  
  	return 0;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
288
289
290
291
292
293
294
295
296
297
298
299
  /**
   * gfs2_unlink - Unlink a file
   * @dir: The inode of the directory containing the file to unlink
   * @dentry: The file itself
   *
   * Unlink a file.  Call gfs2_unlinki()
   *
   * Returns: errno
   */
  
  static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
300
301
302
  	struct gfs2_inode *dip = GFS2_I(dir);
  	struct gfs2_sbd *sdp = GFS2_SB(dir);
  	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
303
304
305
  	struct gfs2_holder ghs[3];
  	struct gfs2_rgrpd *rgd;
  	struct gfs2_holder ri_gh;
b3b94faa5   David Teigland   [GFS2] The core o...
306
  	int error;
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
307
308
309
  	error = gfs2_rindex_hold(sdp, &ri_gh);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
310
  	gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
311
  	gfs2_holder_init(ip->i_gl,  LM_ST_EXCLUSIVE, 0, ghs + 1);
b3b94faa5   David Teigland   [GFS2] The core o...
312

dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
313
  	rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
314
  	gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
8497a46e1   Steven Whitehouse   [GFS2] Correct lo...
315
  	error = gfs2_glock_nq(ghs); /* parent */
b3b94faa5   David Teigland   [GFS2] The core o...
316
  	if (error)
8497a46e1   Steven Whitehouse   [GFS2] Correct lo...
317
318
319
320
321
322
323
324
325
  		goto out_parent;
  
  	error = gfs2_glock_nq(ghs + 1); /* child */
  	if (error)
  		goto out_child;
  
  	error = gfs2_glock_nq(ghs + 2); /* rgrp */
  	if (error)
  		goto out_rgrp;
b3b94faa5   David Teigland   [GFS2] The core o...
326
327
328
  
  	error = gfs2_unlink_ok(dip, &dentry->d_name, ip);
  	if (error)
72dbf4790   Bob Peterson   GFS2: rm on multi...
329
  		goto out_gunlock;
b3b94faa5   David Teigland   [GFS2] The core o...
330

feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
331
  	error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
332
  	if (error)
cd0120751   Roel Kluin   GFS2: jumping to ...
333
  		goto out_gunlock;
b3b94faa5   David Teigland   [GFS2] The core o...
334

feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
335
336
337
  	error = gfs2_dir_del(dip, &dentry->d_name);
          if (error)
                  goto out_end_trans;
b3b94faa5   David Teigland   [GFS2] The core o...
338

feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
339
  	error = gfs2_change_nlink(ip, -1);
b3b94faa5   David Teigland   [GFS2] The core o...
340

feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
341
342
  out_end_trans:
  	gfs2_trans_end(sdp);
72dbf4790   Bob Peterson   GFS2: rm on multi...
343
  out_gunlock:
8497a46e1   Steven Whitehouse   [GFS2] Correct lo...
344
345
  	gfs2_glock_dq(ghs + 2);
  out_rgrp:
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
346
  	gfs2_holder_uninit(ghs + 2);
8497a46e1   Steven Whitehouse   [GFS2] Correct lo...
347
348
349
350
351
352
  	gfs2_glock_dq(ghs + 1);
  out_child:
  	gfs2_holder_uninit(ghs + 1);
  	gfs2_glock_dq(ghs);
  out_parent:
  	gfs2_holder_uninit(ghs);
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
353
  	gfs2_glock_dq_uninit(&ri_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
  	return error;
  }
  
  /**
   * gfs2_symlink - Create a symlink
   * @dir: The directory to create the symlink in
   * @dentry: The dentry to put the symlink in
   * @symname: The thing which the link points to
   *
   * Returns: errno
   */
  
  static int gfs2_symlink(struct inode *dir, struct dentry *dentry,
  			const char *symname)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
369
370
  	struct gfs2_inode *dip = GFS2_I(dir), *ip;
  	struct gfs2_sbd *sdp = GFS2_SB(dir);
b3b94faa5   David Teigland   [GFS2] The core o...
371
372
373
374
375
  	struct gfs2_holder ghs[2];
  	struct inode *inode;
  	struct buffer_head *dibh;
  	int size;
  	int error;
b3b94faa5   David Teigland   [GFS2] The core o...
376
377
378
379
380
381
  	/* Must be stuffed with a null terminator for gfs2_follow_link() */
  	size = strlen(symname);
  	if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode) - 1)
  		return -ENAMETOOLONG;
  
  	gfs2_holder_init(dip->i_gl, 0, 0, ghs);
e7f14f4d0   Steven Whitehouse   [GFS2] Shrink gfs...
382
  	inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO, 0);
7359a19cc   Steven Whitehouse   [GFS2] Fix for ro...
383
  	if (IS_ERR(inode)) {
b3b94faa5   David Teigland   [GFS2] The core o...
384
  		gfs2_holder_uninit(ghs);
7359a19cc   Steven Whitehouse   [GFS2] Fix for ro...
385
  		return PTR_ERR(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
386
  	}
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
387
  	ip = ghs[1].gh_gl->gl_object;
b3b94faa5   David Teigland   [GFS2] The core o...
388

c9e988867   Steven Whitehouse   GFS2: Move i_size...
389
  	ip->i_disksize = size;
5cf32524d   Steven Whitehouse   GFS2: Fix symlink...
390
  	i_size_write(inode, size);
b3b94faa5   David Teigland   [GFS2] The core o...
391
392
393
394
  
  	error = gfs2_meta_inode_buffer(ip, &dibh);
  
  	if (!gfs2_assert_withdraw(sdp, !error)) {
539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
395
  		gfs2_dinode_out(ip, dibh->b_data);
b3b94faa5   David Teigland   [GFS2] The core o...
396
397
398
399
400
401
  		memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname,
  		       size);
  		brelse(dibh);
  	}
  
  	gfs2_trans_end(sdp);
6dbd82248   Steven Whitehouse   [GFS2] Reduce ino...
402
  	if (dip->i_alloc->al_rgd)
b3b94faa5   David Teigland   [GFS2] The core o...
403
404
405
406
407
  		gfs2_inplace_release(dip);
  	gfs2_quota_unlock(dip);
  	gfs2_alloc_put(dip);
  
  	gfs2_glock_dq_uninit_m(2, ghs);
b3b94faa5   David Teigland   [GFS2] The core o...
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
  	d_instantiate(dentry, inode);
  	mark_inode_dirty(inode);
  
  	return 0;
  }
  
  /**
   * gfs2_mkdir - Make a directory
   * @dir: The parent directory of the new one
   * @dentry: The dentry of the new directory
   * @mode: The mode of the new directory
   *
   * Returns: errno
   */
  
  static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
425
426
  	struct gfs2_inode *dip = GFS2_I(dir), *ip;
  	struct gfs2_sbd *sdp = GFS2_SB(dir);
b3b94faa5   David Teigland   [GFS2] The core o...
427
428
429
430
  	struct gfs2_holder ghs[2];
  	struct inode *inode;
  	struct buffer_head *dibh;
  	int error;
b3b94faa5   David Teigland   [GFS2] The core o...
431
  	gfs2_holder_init(dip->i_gl, 0, 0, ghs);
e7f14f4d0   Steven Whitehouse   [GFS2] Shrink gfs...
432
  	inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode, 0);
7359a19cc   Steven Whitehouse   [GFS2] Fix for ro...
433
  	if (IS_ERR(inode)) {
b3b94faa5   David Teigland   [GFS2] The core o...
434
  		gfs2_holder_uninit(ghs);
7359a19cc   Steven Whitehouse   [GFS2] Fix for ro...
435
  		return PTR_ERR(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
436
  	}
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
437
  	ip = ghs[1].gh_gl->gl_object;
b3b94faa5   David Teigland   [GFS2] The core o...
438

4f56110a0   Steven Whitehouse   [GFS2] Shrink gfs...
439
  	ip->i_inode.i_nlink = 2;
c9e988867   Steven Whitehouse   GFS2: Move i_size...
440
  	ip->i_disksize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode);
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
441
  	ip->i_diskflags |= GFS2_DIF_JDATA;
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
442
  	ip->i_entries = 2;
b3b94faa5   David Teigland   [GFS2] The core o...
443
444
445
446
447
  
  	error = gfs2_meta_inode_buffer(ip, &dibh);
  
  	if (!gfs2_assert_withdraw(sdp, !error)) {
  		struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
448
  		struct gfs2_dirent *dent = (struct gfs2_dirent *)(di+1);
71b86f562   Steven Whitehouse   [GFS2] Further up...
449
  		struct qstr str;
b3b94faa5   David Teigland   [GFS2] The core o...
450

71b86f562   Steven Whitehouse   [GFS2] Further up...
451
  		gfs2_str2qstr(&str, ".");
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
452
453
  		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
  		gfs2_qstr2dirent(&str, GFS2_DIRENT_SIZE(str.len), dent);
b3b94faa5   David Teigland   [GFS2] The core o...
454
  		dent->de_inum = di->di_num; /* already GFS2 endian */
7ecdb70a0   Steven Whitehouse   [GFS2] Fix endian...
455
  		dent->de_type = cpu_to_be16(DT_DIR);
b3b94faa5   David Teigland   [GFS2] The core o...
456
  		di->di_entries = cpu_to_be32(1);
71b86f562   Steven Whitehouse   [GFS2] Further up...
457
  		gfs2_str2qstr(&str, "..");
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
458
459
  		dent = (struct gfs2_dirent *)((char*)dent + GFS2_DIRENT_SIZE(1));
  		gfs2_qstr2dirent(&str, dibh->b_size - GFS2_DIRENT_SIZE(1) - sizeof(struct gfs2_dinode), dent);
b3b94faa5   David Teigland   [GFS2] The core o...
460

dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
461
  		gfs2_inum_out(dip, dent);
7ecdb70a0   Steven Whitehouse   [GFS2] Fix endian...
462
  		dent->de_type = cpu_to_be16(DT_DIR);
b3b94faa5   David Teigland   [GFS2] The core o...
463

539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
464
  		gfs2_dinode_out(ip, di);
b3b94faa5   David Teigland   [GFS2] The core o...
465
466
467
468
469
470
471
472
  
  		brelse(dibh);
  	}
  
  	error = gfs2_change_nlink(dip, +1);
  	gfs2_assert_withdraw(sdp, !error); /* dip already pinned */
  
  	gfs2_trans_end(sdp);
6dbd82248   Steven Whitehouse   [GFS2] Reduce ino...
473
  	if (dip->i_alloc->al_rgd)
b3b94faa5   David Teigland   [GFS2] The core o...
474
475
476
477
478
  		gfs2_inplace_release(dip);
  	gfs2_quota_unlock(dip);
  	gfs2_alloc_put(dip);
  
  	gfs2_glock_dq_uninit_m(2, ghs);
b3b94faa5   David Teigland   [GFS2] The core o...
479
480
481
482
483
484
485
  	d_instantiate(dentry, inode);
  	mark_inode_dirty(inode);
  
  	return 0;
  }
  
  /**
2286dbfad   Steven Whitehouse   GFS2: Move gfs2_r...
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
   * gfs2_rmdiri - Remove a directory
   * @dip: The parent directory of the directory to be removed
   * @name: The name of the directory to be removed
   * @ip: The GFS2 inode of the directory to be removed
   *
   * Assumes Glocks on dip and ip are held
   *
   * Returns: errno
   */
  
  static int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
  		       struct gfs2_inode *ip)
  {
  	struct qstr dotname;
  	int error;
  
  	if (ip->i_entries != 2) {
  		if (gfs2_consist_inode(ip))
  			gfs2_dinode_print(ip);
  		return -EIO;
  	}
  
  	error = gfs2_dir_del(dip, name);
  	if (error)
  		return error;
  
  	error = gfs2_change_nlink(dip, -1);
  	if (error)
  		return error;
  
  	gfs2_str2qstr(&dotname, ".");
  	error = gfs2_dir_del(ip, &dotname);
  	if (error)
  		return error;
  
  	gfs2_str2qstr(&dotname, "..");
  	error = gfs2_dir_del(ip, &dotname);
  	if (error)
  		return error;
  
  	/* It looks odd, but it really should be done twice */
  	error = gfs2_change_nlink(ip, -1);
  	if (error)
  		return error;
  
  	error = gfs2_change_nlink(ip, -1);
  	if (error)
  		return error;
  
  	return error;
  }
  
  /**
b3b94faa5   David Teigland   [GFS2] The core o...
539
540
541
542
543
544
545
546
547
548
549
   * gfs2_rmdir - Remove a directory
   * @dir: The parent directory of the directory to be removed
   * @dentry: The dentry of the directory to remove
   *
   * Remove a directory. Call gfs2_rmdiri()
   *
   * Returns: errno
   */
  
  static int gfs2_rmdir(struct inode *dir, struct dentry *dentry)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
550
551
552
  	struct gfs2_inode *dip = GFS2_I(dir);
  	struct gfs2_sbd *sdp = GFS2_SB(dir);
  	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
553
554
555
  	struct gfs2_holder ghs[3];
  	struct gfs2_rgrpd *rgd;
  	struct gfs2_holder ri_gh;
b3b94faa5   David Teigland   [GFS2] The core o...
556
  	int error;
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
557
558
559
  	error = gfs2_rindex_hold(sdp, &ri_gh);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
560
561
  	gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
  	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + 1);
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
562
  	rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
563
  	gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
72dbf4790   Bob Peterson   GFS2: rm on multi...
564
565
566
567
568
  	error = gfs2_glock_nq(ghs); /* parent */
  	if (error)
  		goto out_parent;
  
  	error = gfs2_glock_nq(ghs + 1); /* child */
b3b94faa5   David Teigland   [GFS2] The core o...
569
  	if (error)
72dbf4790   Bob Peterson   GFS2: rm on multi...
570
571
572
573
574
  		goto out_child;
  
  	error = gfs2_glock_nq(ghs + 2); /* rgrp */
  	if (error)
  		goto out_rgrp;
b3b94faa5   David Teigland   [GFS2] The core o...
575
576
577
578
  
  	error = gfs2_unlink_ok(dip, &dentry->d_name, ip);
  	if (error)
  		goto out_gunlock;
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
579
  	if (ip->i_entries < 2) {
b3b94faa5   David Teigland   [GFS2] The core o...
580
  		if (gfs2_consist_inode(ip))
4cc14f0b8   Steven Whitehouse   [GFS2] Change arg...
581
  			gfs2_dinode_print(ip);
b3b94faa5   David Teigland   [GFS2] The core o...
582
583
584
  		error = -EIO;
  		goto out_gunlock;
  	}
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
585
  	if (ip->i_entries > 2) {
b3b94faa5   David Teigland   [GFS2] The core o...
586
587
588
  		error = -ENOTEMPTY;
  		goto out_gunlock;
  	}
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
589
  	error = gfs2_trans_begin(sdp, 2 * RES_DINODE + 3 * RES_LEAF + RES_RG_BIT, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
590
591
  	if (error)
  		goto out_gunlock;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
592
  	error = gfs2_rmdiri(dip, &dentry->d_name, ip);
b3b94faa5   David Teigland   [GFS2] The core o...
593
594
  
  	gfs2_trans_end(sdp);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
595
  out_gunlock:
72dbf4790   Bob Peterson   GFS2: rm on multi...
596
597
  	gfs2_glock_dq(ghs + 2);
  out_rgrp:
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
598
  	gfs2_holder_uninit(ghs + 2);
72dbf4790   Bob Peterson   GFS2: rm on multi...
599
600
601
602
603
604
  	gfs2_glock_dq(ghs + 1);
  out_child:
  	gfs2_holder_uninit(ghs + 1);
  	gfs2_glock_dq(ghs);
  out_parent:
  	gfs2_holder_uninit(ghs);
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
605
  	gfs2_glock_dq_uninit(&ri_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
  	return error;
  }
  
  /**
   * gfs2_mknod - Make a special file
   * @dir: The directory in which the special file will reside
   * @dentry: The dentry of the special file
   * @mode: The mode of the special file
   * @rdev: The device specification of the special file
   *
   */
  
  static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode,
  		      dev_t dev)
  {
e7f14f4d0   Steven Whitehouse   [GFS2] Shrink gfs...
621
  	struct gfs2_inode *dip = GFS2_I(dir);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
622
  	struct gfs2_sbd *sdp = GFS2_SB(dir);
b3b94faa5   David Teigland   [GFS2] The core o...
623
624
  	struct gfs2_holder ghs[2];
  	struct inode *inode;
b3b94faa5   David Teigland   [GFS2] The core o...
625
626
  
  	gfs2_holder_init(dip->i_gl, 0, 0, ghs);
e7f14f4d0   Steven Whitehouse   [GFS2] Shrink gfs...
627
  	inode = gfs2_createi(ghs, &dentry->d_name, mode, dev);
7359a19cc   Steven Whitehouse   [GFS2] Fix for ro...
628
  	if (IS_ERR(inode)) {
b3b94faa5   David Teigland   [GFS2] The core o...
629
  		gfs2_holder_uninit(ghs);
7359a19cc   Steven Whitehouse   [GFS2] Fix for ro...
630
  		return PTR_ERR(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
631
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
632
  	gfs2_trans_end(sdp);
6dbd82248   Steven Whitehouse   [GFS2] Reduce ino...
633
  	if (dip->i_alloc->al_rgd)
b3b94faa5   David Teigland   [GFS2] The core o...
634
635
636
637
638
  		gfs2_inplace_release(dip);
  	gfs2_quota_unlock(dip);
  	gfs2_alloc_put(dip);
  
  	gfs2_glock_dq_uninit_m(2, ghs);
b3b94faa5   David Teigland   [GFS2] The core o...
639
640
641
642
643
  	d_instantiate(dentry, inode);
  	mark_inode_dirty(inode);
  
  	return 0;
  }
0188d6c58   Steven Whitehouse   GFS2: Fix & clean...
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
  /*
   * gfs2_ok_to_move - check if it's ok to move a directory to another directory
   * @this: move this
   * @to: to here
   *
   * Follow @to back to the root and make sure we don't encounter @this
   * Assumes we already hold the rename lock.
   *
   * Returns: errno
   */
  
  static int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
  {
  	struct inode *dir = &to->i_inode;
  	struct super_block *sb = dir->i_sb;
  	struct inode *tmp;
  	struct qstr dotdot;
  	int error = 0;
  
  	gfs2_str2qstr(&dotdot, "..");
  
  	igrab(dir);
  
  	for (;;) {
  		if (dir == &this->i_inode) {
  			error = -EINVAL;
  			break;
  		}
  		if (dir == sb->s_root->d_inode) {
  			error = 0;
  			break;
  		}
  
  		tmp = gfs2_lookupi(dir, &dotdot, 1);
  		if (IS_ERR(tmp)) {
  			error = PTR_ERR(tmp);
  			break;
  		}
  
  		iput(dir);
  		dir = tmp;
  	}
  
  	iput(dir);
  
  	return error;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
691
692
693
694
695
696
697
698
699
700
701
702
703
  /**
   * gfs2_rename - Rename a file
   * @odir: Parent directory of old file name
   * @odentry: The old dentry of the file
   * @ndir: Parent directory of new file name
   * @ndentry: The new dentry of the file
   *
   * Returns: errno
   */
  
  static int gfs2_rename(struct inode *odir, struct dentry *odentry,
  		       struct inode *ndir, struct dentry *ndentry)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
704
705
706
  	struct gfs2_inode *odip = GFS2_I(odir);
  	struct gfs2_inode *ndip = GFS2_I(ndir);
  	struct gfs2_inode *ip = GFS2_I(odentry->d_inode);
b3b94faa5   David Teigland   [GFS2] The core o...
707
  	struct gfs2_inode *nip = NULL;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
708
  	struct gfs2_sbd *sdp = GFS2_SB(odir);
0188d6c58   Steven Whitehouse   GFS2: Fix & clean...
709
  	struct gfs2_holder ghs[5], r_gh = { .gh_gl = NULL, };
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
710
  	struct gfs2_rgrpd *nrgd;
b3b94faa5   David Teigland   [GFS2] The core o...
711
712
  	unsigned int num_gh;
  	int dir_rename = 0;
24b977b5f   Steven Whitehouse   GFS2: Fix locking...
713
  	int alloc_required = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
714
715
  	unsigned int x;
  	int error;
b3b94faa5   David Teigland   [GFS2] The core o...
716
  	if (ndentry->d_inode) {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
717
  		nip = GFS2_I(ndentry->d_inode);
b3b94faa5   David Teigland   [GFS2] The core o...
718
719
720
  		if (ip == nip)
  			return 0;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
721

0188d6c58   Steven Whitehouse   GFS2: Fix & clean...
722
723
724
  	if (odip != ndip) {
  		error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE,
  					   0, &r_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
725
726
  		if (error)
  			goto out;
0188d6c58   Steven Whitehouse   GFS2: Fix & clean...
727
728
729
730
731
732
733
  		if (S_ISDIR(ip->i_inode.i_mode)) {
  			dir_rename = 1;
  			/* don't move a dirctory into it's subdir */
  			error = gfs2_ok_to_move(ip, ndip);
  			if (error)
  				goto out_gunlock_r;
  		}
b3b94faa5   David Teigland   [GFS2] The core o...
734
  	}
d9d1ca305   Steven Whitehouse   [GFS2] Fix double...
735
  	num_gh = 1;
b3b94faa5   David Teigland   [GFS2] The core o...
736
  	gfs2_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, ghs);
d9d1ca305   Steven Whitehouse   [GFS2] Fix double...
737
738
739
740
741
742
  	if (odip != ndip) {
  		gfs2_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
  		num_gh++;
  	}
  	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
  	num_gh++;
b3b94faa5   David Teigland   [GFS2] The core o...
743

d9d1ca305   Steven Whitehouse   [GFS2] Fix double...
744
745
746
  	if (nip) {
  		gfs2_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh);
  		num_gh++;
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
747
748
749
750
  		/* grab the resource lock for unlink flag twiddling 
  		 * this is the case of the target file already existing
  		 * so we unlink before doing the rename
  		 */
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
751
  		nrgd = gfs2_blk2rgrpd(sdp, nip->i_no_addr);
ddee76089   Russell Cattelan   [GFS2] Fix unlink...
752
753
  		if (nrgd)
  			gfs2_holder_init(nrgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + num_gh++);
d9d1ca305   Steven Whitehouse   [GFS2] Fix double...
754
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
755

72dbf4790   Bob Peterson   GFS2: rm on multi...
756
757
758
759
760
  	for (x = 0; x < num_gh; x++) {
  		error = gfs2_glock_nq(ghs + x);
  		if (error)
  			goto out_gunlock;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
761
762
763
764
765
766
767
768
769
770
771
772
773
  
  	/* Check out the old directory */
  
  	error = gfs2_unlink_ok(odip, &odentry->d_name, ip);
  	if (error)
  		goto out_gunlock;
  
  	/* Check out the new directory */
  
  	if (nip) {
  		error = gfs2_unlink_ok(ndip, &ndentry->d_name, nip);
  		if (error)
  			goto out_gunlock;
b60623c23   Steven Whitehouse   [GFS2] Shrink gfs...
774
  		if (S_ISDIR(nip->i_inode.i_mode)) {
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
775
  			if (nip->i_entries < 2) {
b3b94faa5   David Teigland   [GFS2] The core o...
776
  				if (gfs2_consist_inode(nip))
4cc14f0b8   Steven Whitehouse   [GFS2] Change arg...
777
  					gfs2_dinode_print(nip);
b3b94faa5   David Teigland   [GFS2] The core o...
778
779
780
  				error = -EIO;
  				goto out_gunlock;
  			}
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
781
  			if (nip->i_entries > 2) {
b3b94faa5   David Teigland   [GFS2] The core o...
782
783
784
785
786
  				error = -ENOTEMPTY;
  				goto out_gunlock;
  			}
  		}
  	} else {
f58ba8891   Miklos Szeredi   [GFS2] don't call...
787
  		error = gfs2_permission(ndir, MAY_WRITE | MAY_EXEC);
b3b94faa5   David Teigland   [GFS2] The core o...
788
789
  		if (error)
  			goto out_gunlock;
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
790
  		error = gfs2_dir_check(ndir, &ndentry->d_name, NULL);
b3b94faa5   David Teigland   [GFS2] The core o...
791
792
793
794
795
796
797
798
799
800
801
  		switch (error) {
  		case -ENOENT:
  			error = 0;
  			break;
  		case 0:
  			error = -EEXIST;
  		default:
  			goto out_gunlock;
  		};
  
  		if (odip != ndip) {
4f56110a0   Steven Whitehouse   [GFS2] Shrink gfs...
802
  			if (!ndip->i_inode.i_nlink) {
b3b94faa5   David Teigland   [GFS2] The core o...
803
804
805
  				error = -EINVAL;
  				goto out_gunlock;
  			}
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
806
  			if (ndip->i_entries == (u32)-1) {
b3b94faa5   David Teigland   [GFS2] The core o...
807
808
809
  				error = -EFBIG;
  				goto out_gunlock;
  			}
b60623c23   Steven Whitehouse   [GFS2] Shrink gfs...
810
  			if (S_ISDIR(ip->i_inode.i_mode) &&
4f56110a0   Steven Whitehouse   [GFS2] Shrink gfs...
811
  			    ndip->i_inode.i_nlink == (u32)-1) {
b3b94faa5   David Teigland   [GFS2] The core o...
812
813
814
815
816
817
818
819
820
  				error = -EMLINK;
  				goto out_gunlock;
  			}
  		}
  	}
  
  	/* Check out the dir to be renamed */
  
  	if (dir_rename) {
f58ba8891   Miklos Szeredi   [GFS2] don't call...
821
  		error = gfs2_permission(odentry->d_inode, MAY_WRITE);
b3b94faa5   David Teigland   [GFS2] The core o...
822
823
824
  		if (error)
  			goto out_gunlock;
  	}
24b977b5f   Steven Whitehouse   GFS2: Fix locking...
825
826
827
  	if (nip == NULL)
  		alloc_required = gfs2_diradd_alloc_required(ndir, &ndentry->d_name);
  	error = alloc_required;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
828
  	if (error < 0)
b3b94faa5   David Teigland   [GFS2] The core o...
829
  		goto out_gunlock;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
830
  	error = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
831
832
833
  
  	if (alloc_required) {
  		struct gfs2_alloc *al = gfs2_alloc_get(ndip);
182fe5abd   Cyrill Gorcunov   [GFS2] possible n...
834
835
836
837
  		if (!al) {
  			error = -ENOMEM;
  			goto out_gunlock;
  		}
b3b94faa5   David Teigland   [GFS2] The core o...
838

d82661d96   Steven Whitehouse   [GFS2] Streamline...
839
  		error = gfs2_quota_lock_check(ndip);
b3b94faa5   David Teigland   [GFS2] The core o...
840
841
  		if (error)
  			goto out_alloc;
b3b94faa5   David Teigland   [GFS2] The core o...
842
843
844
845
846
  		al->al_requested = sdp->sd_max_dirres;
  
  		error = gfs2_inplace_reserve(ndip);
  		if (error)
  			goto out_gunlock_q;
fe1bdedc6   Steven Whitehouse   [GFS2] Use vmallo...
847
  		error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
bb8d8a6f5   Steven Whitehouse   [GFS2] Fix sign p...
848
  					 al->al_rgd->rd_length +
b3b94faa5   David Teigland   [GFS2] The core o...
849
  					 4 * RES_DINODE + 4 * RES_LEAF +
87d21e07f   S. Wendy Cheng   [GFS2] Fix gfs2_r...
850
  					 RES_STATFS + RES_QUOTA + 4, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
851
852
853
854
  		if (error)
  			goto out_ipreserv;
  	} else {
  		error = gfs2_trans_begin(sdp, 4 * RES_DINODE +
87d21e07f   S. Wendy Cheng   [GFS2] Fix gfs2_r...
855
  					 5 * RES_LEAF + 4, 0);
b3b94faa5   David Teigland   [GFS2] The core o...
856
857
858
859
860
861
862
  		if (error)
  			goto out_gunlock;
  	}
  
  	/* Remove the target file, if it exists */
  
  	if (nip) {
b60623c23   Steven Whitehouse   [GFS2] Shrink gfs...
863
  		if (S_ISDIR(nip->i_inode.i_mode))
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
864
865
866
867
868
  			error = gfs2_rmdiri(ndip, &ndentry->d_name, nip);
  		else {
  			error = gfs2_dir_del(ndip, &ndentry->d_name);
  			if (error)
  				goto out_end_trans;
87d21e07f   S. Wendy Cheng   [GFS2] Fix gfs2_r...
869
  			error = gfs2_change_nlink(nip, -1);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
870
  		}
b3b94faa5   David Teigland   [GFS2] The core o...
871
872
873
874
875
876
  		if (error)
  			goto out_end_trans;
  	}
  
  	if (dir_rename) {
  		struct qstr name;
71b86f562   Steven Whitehouse   [GFS2] Further up...
877
  		gfs2_str2qstr(&name, "..");
b3b94faa5   David Teigland   [GFS2] The core o...
878
879
880
881
882
883
884
  
  		error = gfs2_change_nlink(ndip, +1);
  		if (error)
  			goto out_end_trans;
  		error = gfs2_change_nlink(odip, -1);
  		if (error)
  			goto out_end_trans;
ffed8ab34   Steven Whitehouse   [GFS2] Fix typo i...
885
  		error = gfs2_dir_mvino(ip, &name, ndip, DT_DIR);
b3b94faa5   David Teigland   [GFS2] The core o...
886
887
888
889
890
891
892
  		if (error)
  			goto out_end_trans;
  	} else {
  		struct buffer_head *dibh;
  		error = gfs2_meta_inode_buffer(ip, &dibh);
  		if (error)
  			goto out_end_trans;
4bd91ba18   Steven Whitehouse   [GFS2] Add nanose...
893
  		ip->i_inode.i_ctime = CURRENT_TIME;
d4e9c4c3b   Steven Whitehouse   [GFS2] Add an add...
894
  		gfs2_trans_add_bh(ip->i_gl, dibh, 1);
539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
895
  		gfs2_dinode_out(ip, dibh->b_data);
b3b94faa5   David Teigland   [GFS2] The core o...
896
897
898
899
900
901
  		brelse(dibh);
  	}
  
  	error = gfs2_dir_del(odip, &odentry->d_name);
  	if (error)
  		goto out_end_trans;
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
902
  	error = gfs2_dir_add(ndir, &ndentry->d_name, ip, IF2DT(ip->i_inode.i_mode));
b3b94faa5   David Teigland   [GFS2] The core o...
903
904
  	if (error)
  		goto out_end_trans;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
905
  out_end_trans:
b3b94faa5   David Teigland   [GFS2] The core o...
906
  	gfs2_trans_end(sdp);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
907
  out_ipreserv:
b3b94faa5   David Teigland   [GFS2] The core o...
908
909
  	if (alloc_required)
  		gfs2_inplace_release(ndip);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
910
  out_gunlock_q:
b3b94faa5   David Teigland   [GFS2] The core o...
911
912
  	if (alloc_required)
  		gfs2_quota_unlock(ndip);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
913
  out_alloc:
b3b94faa5   David Teigland   [GFS2] The core o...
914
915
  	if (alloc_required)
  		gfs2_alloc_put(ndip);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
916
  out_gunlock:
72dbf4790   Bob Peterson   GFS2: rm on multi...
917
918
  	while (x--) {
  		gfs2_glock_dq(ghs + x);
b3b94faa5   David Teigland   [GFS2] The core o...
919
  		gfs2_holder_uninit(ghs + x);
72dbf4790   Bob Peterson   GFS2: rm on multi...
920
  	}
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
921
  out_gunlock_r:
0188d6c58   Steven Whitehouse   GFS2: Fix & clean...
922
  	if (r_gh.gh_gl)
b3b94faa5   David Teigland   [GFS2] The core o...
923
  		gfs2_glock_dq_uninit(&r_gh);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
924
  out:
b3b94faa5   David Teigland   [GFS2] The core o...
925
926
927
928
  	return error;
  }
  
  /**
c177c2ac8   Al Viro   Switch gfs2 to nd...
929
930
931
   * gfs2_follow_link - Follow a symbolic link
   * @dentry: The dentry of the link
   * @nd: Data that we pass to vfs_follow_link()
536baf02f   Steven Whitehouse   GFS2: Move gfs2_r...
932
   *
c177c2ac8   Al Viro   Switch gfs2 to nd...
933
   * This can handle symlinks of any size.
536baf02f   Steven Whitehouse   GFS2: Move gfs2_r...
934
   *
c177c2ac8   Al Viro   Switch gfs2 to nd...
935
   * Returns: 0 on success or error code
536baf02f   Steven Whitehouse   GFS2: Move gfs2_r...
936
   */
c177c2ac8   Al Viro   Switch gfs2 to nd...
937
  static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd)
536baf02f   Steven Whitehouse   GFS2: Move gfs2_r...
938
  {
c177c2ac8   Al Viro   Switch gfs2 to nd...
939
  	struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
536baf02f   Steven Whitehouse   GFS2: Move gfs2_r...
940
941
942
  	struct gfs2_holder i_gh;
  	struct buffer_head *dibh;
  	unsigned int x;
c177c2ac8   Al Viro   Switch gfs2 to nd...
943
  	char *buf;
536baf02f   Steven Whitehouse   GFS2: Move gfs2_r...
944
945
946
947
948
949
  	int error;
  
  	gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh);
  	error = gfs2_glock_nq(&i_gh);
  	if (error) {
  		gfs2_holder_uninit(&i_gh);
c177c2ac8   Al Viro   Switch gfs2 to nd...
950
951
  		nd_set_link(nd, ERR_PTR(error));
  		return NULL;
536baf02f   Steven Whitehouse   GFS2: Move gfs2_r...
952
953
954
955
  	}
  
  	if (!ip->i_disksize) {
  		gfs2_consist_inode(ip);
c177c2ac8   Al Viro   Switch gfs2 to nd...
956
  		buf = ERR_PTR(-EIO);
536baf02f   Steven Whitehouse   GFS2: Move gfs2_r...
957
958
959
960
  		goto out;
  	}
  
  	error = gfs2_meta_inode_buffer(ip, &dibh);
c177c2ac8   Al Viro   Switch gfs2 to nd...
961
962
  	if (error) {
  		buf = ERR_PTR(error);
536baf02f   Steven Whitehouse   GFS2: Move gfs2_r...
963
  		goto out;
536baf02f   Steven Whitehouse   GFS2: Move gfs2_r...
964
  	}
c177c2ac8   Al Viro   Switch gfs2 to nd...
965
966
967
968
969
970
  	x = ip->i_disksize + 1;
  	buf = kmalloc(x, GFP_NOFS);
  	if (!buf)
  		buf = ERR_PTR(-ENOMEM);
  	else
  		memcpy(buf, dibh->b_data + sizeof(struct gfs2_dinode), x);
536baf02f   Steven Whitehouse   GFS2: Move gfs2_r...
971
972
973
  	brelse(dibh);
  out:
  	gfs2_glock_dq_uninit(&i_gh);
c177c2ac8   Al Viro   Switch gfs2 to nd...
974
975
  	nd_set_link(nd, buf);
  	return NULL;
b3b94faa5   David Teigland   [GFS2] The core o...
976
  }
c177c2ac8   Al Viro   Switch gfs2 to nd...
977
  static void gfs2_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
b3b94faa5   David Teigland   [GFS2] The core o...
978
  {
c177c2ac8   Al Viro   Switch gfs2 to nd...
979
980
981
  	char *s = nd_get_link(nd);
  	if (!IS_ERR(s))
  		kfree(s);
b3b94faa5   David Teigland   [GFS2] The core o...
982
983
984
985
986
987
988
989
  }
  
  /**
   * gfs2_permission -
   * @inode:
   * @mask:
   * @nd: passed from Linux VFS, ignored by us
   *
300c7d75f   Steven Whitehouse   [GFS2] Fix recurs...
990
991
992
993
   * This may be called from the VFS directly, or from within GFS2 with the
   * inode locked, so we look to see if the glock is already locked and only
   * lock the glock if its not already been done.
   *
b3b94faa5   David Teigland   [GFS2] The core o...
994
995
   * Returns: errno
   */
f58ba8891   Miklos Szeredi   [GFS2] don't call...
996
  int gfs2_permission(struct inode *inode, int mask)
b3b94faa5   David Teigland   [GFS2] The core o...
997
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
998
  	struct gfs2_inode *ip = GFS2_I(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
999
1000
  	struct gfs2_holder i_gh;
  	int error;
300c7d75f   Steven Whitehouse   [GFS2] Fix recurs...
1001
  	int unlock = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1002

7afd88d91   Steven Whitehouse   [GFS2] Fix a page...
1003
  	if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) {
300c7d75f   Steven Whitehouse   [GFS2] Fix recurs...
1004
1005
1006
1007
1008
  		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
  		if (error)
  			return error;
  		unlock = 1;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
1009

f58ba8891   Miklos Szeredi   [GFS2] don't call...
1010
1011
1012
1013
  	if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode))
  		error = -EACCES;
  	else
  		error = generic_permission(inode, mask, gfs2_check_acl);
300c7d75f   Steven Whitehouse   [GFS2] Fix recurs...
1014
  	if (unlock)
b3b94faa5   David Teigland   [GFS2] The core o...
1015
  		gfs2_glock_dq_uninit(&i_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
1016
1017
1018
  
  	return error;
  }
15c6fd978   npiggin@suse.de   kill spurious ref...
1019
  /*
2c27c65ed   Christoph Hellwig   check ATTR_SIZE c...
1020
   * XXX(truncate): the truncate_setsize calls should be moved to the end.
15c6fd978   npiggin@suse.de   kill spurious ref...
1021
   */
b3b94faa5   David Teigland   [GFS2] The core o...
1022
1023
  static int setattr_size(struct inode *inode, struct iattr *attr)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1024
  	struct gfs2_inode *ip = GFS2_I(inode);
16615be18   Steven Whitehouse   [GFS2] Clean up j...
1025
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
1026
  	int error;
c9e988867   Steven Whitehouse   GFS2: Move i_size...
1027
  	if (attr->ia_size != ip->i_disksize) {
16615be18   Steven Whitehouse   [GFS2] Clean up j...
1028
  		error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks);
b3b94faa5   David Teigland   [GFS2] The core o...
1029
1030
  		if (error)
  			return error;
2c27c65ed   Christoph Hellwig   check ATTR_SIZE c...
1031
  		truncate_setsize(inode, attr->ia_size);
16615be18   Steven Whitehouse   [GFS2] Clean up j...
1032
  		gfs2_trans_end(sdp);
b3b94faa5   David Teigland   [GFS2] The core o...
1033
  	}
aa6a85a97   Steven Whitehouse   [GFS2] Remove poi...
1034
  	error = gfs2_truncatei(ip, attr->ia_size);
c9e988867   Steven Whitehouse   GFS2: Move i_size...
1035
1036
  	if (error && (inode->i_size != ip->i_disksize))
  		i_size_write(inode, ip->i_disksize);
b3b94faa5   David Teigland   [GFS2] The core o...
1037
1038
1039
1040
1041
1042
  
  	return error;
  }
  
  static int setattr_chown(struct inode *inode, struct iattr *attr)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1043
1044
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
1045
  	struct buffer_head *dibh;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1046
  	u32 ouid, ogid, nuid, ngid;
b3b94faa5   David Teigland   [GFS2] The core o...
1047
  	int error;
2933f9254   Steven Whitehouse   [GFS2] Shrink gfs...
1048
1049
  	ouid = inode->i_uid;
  	ogid = inode->i_gid;
b3b94faa5   David Teigland   [GFS2] The core o...
1050
1051
1052
1053
1054
1055
1056
  	nuid = attr->ia_uid;
  	ngid = attr->ia_gid;
  
  	if (!(attr->ia_valid & ATTR_UID) || ouid == nuid)
  		ouid = nuid = NO_QUOTA_CHANGE;
  	if (!(attr->ia_valid & ATTR_GID) || ogid == ngid)
  		ogid = ngid = NO_QUOTA_CHANGE;
182fe5abd   Cyrill Gorcunov   [GFS2] possible n...
1057
1058
  	if (!gfs2_alloc_get(ip))
  		return -ENOMEM;
b3b94faa5   David Teigland   [GFS2] The core o...
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
  
  	error = gfs2_quota_lock(ip, nuid, ngid);
  	if (error)
  		goto out_alloc;
  
  	if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) {
  		error = gfs2_quota_check(ip, nuid, ngid);
  		if (error)
  			goto out_gunlock_q;
  	}
  
  	error = gfs2_trans_begin(sdp, RES_DINODE + 2 * RES_QUOTA, 0);
  	if (error)
  		goto out_gunlock_q;
  
  	error = gfs2_meta_inode_buffer(ip, &dibh);
  	if (error)
  		goto out_end_trans;
1025774ce   Christoph Hellwig   remove inode_setattr
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
  	if ((attr->ia_valid & ATTR_SIZE) &&
  	    attr->ia_size != i_size_read(inode)) {
  		int error;
  
  		error = vmtruncate(inode, attr->ia_size);
  		gfs2_assert_warn(sdp, !error);
  	}
  
  	setattr_copy(inode, attr);
  	mark_inode_dirty(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
1087

d4e9c4c3b   Steven Whitehouse   [GFS2] Add an add...
1088
  	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
1089
  	gfs2_dinode_out(ip, dibh->b_data);
b3b94faa5   David Teigland   [GFS2] The core o...
1090
1091
1092
  	brelse(dibh);
  
  	if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) {
77658aad2   Steven Whitehouse   [GFS2] Eliminate ...
1093
1094
1095
  		u64 blocks = gfs2_get_inode_blocks(&ip->i_inode);
  		gfs2_quota_change(ip, -blocks, ouid, ogid);
  		gfs2_quota_change(ip, blocks, nuid, ngid);
b3b94faa5   David Teigland   [GFS2] The core o...
1096
  	}
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1097
  out_end_trans:
b3b94faa5   David Teigland   [GFS2] The core o...
1098
  	gfs2_trans_end(sdp);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1099
  out_gunlock_q:
b3b94faa5   David Teigland   [GFS2] The core o...
1100
  	gfs2_quota_unlock(ip);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1101
  out_alloc:
b3b94faa5   David Teigland   [GFS2] The core o...
1102
  	gfs2_alloc_put(ip);
b3b94faa5   David Teigland   [GFS2] The core o...
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
  	return error;
  }
  
  /**
   * gfs2_setattr - Change attributes on an inode
   * @dentry: The dentry which is changing
   * @attr: The structure describing the change
   *
   * The VFS layer wants to change one or more of an inodes attributes.  Write
   * that change out to disk.
   *
   * Returns: errno
   */
  
  static int gfs2_setattr(struct dentry *dentry, struct iattr *attr)
  {
  	struct inode *inode = dentry->d_inode;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1120
  	struct gfs2_inode *ip = GFS2_I(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
1121
1122
  	struct gfs2_holder i_gh;
  	int error;
b3b94faa5   David Teigland   [GFS2] The core o...
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
  	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
  	if (error)
  		return error;
  
  	error = -EPERM;
  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
  		goto out;
  
  	error = inode_change_ok(inode, attr);
  	if (error)
  		goto out;
  
  	if (attr->ia_valid & ATTR_SIZE)
  		error = setattr_size(inode, attr);
  	else if (attr->ia_valid & (ATTR_UID | ATTR_GID))
  		error = setattr_chown(inode, attr);
  	else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode))
  		error = gfs2_acl_chmod(ip, attr);
  	else
  		error = gfs2_setattr_simple(ip, attr);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1143
  out:
b3b94faa5   David Teigland   [GFS2] The core o...
1144
  	gfs2_glock_dq_uninit(&i_gh);
b3b94faa5   David Teigland   [GFS2] The core o...
1145
1146
  	if (!error)
  		mark_inode_dirty(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
1147
1148
1149
1150
1151
  	return error;
  }
  
  /**
   * gfs2_getattr - Read out an inode's attributes
26c1a5741   Steven Whitehouse   [GFS2] More code ...
1152
   * @mnt: The vfsmount the inode is being accessed from
b3b94faa5   David Teigland   [GFS2] The core o...
1153
1154
1155
   * @dentry: The dentry to stat
   * @stat: The inode's stats
   *
dcf3dd852   Steven Whitehouse   [GFS2] Fix recurs...
1156
1157
1158
1159
1160
1161
   * This may be called from the VFS directly, or from within GFS2 with the
   * inode locked, so we look to see if the glock is already locked and only
   * lock the glock if its not already been done. Note that its the NFS
   * readdirplus operation which causes this to be called (from filldir)
   * with the glock already held.
   *
b3b94faa5   David Teigland   [GFS2] The core o...
1162
1163
1164
1165
1166
1167
1168
   * Returns: errno
   */
  
  static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
  			struct kstat *stat)
  {
  	struct inode *inode = dentry->d_inode;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1169
  	struct gfs2_inode *ip = GFS2_I(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
1170
1171
  	struct gfs2_holder gh;
  	int error;
dcf3dd852   Steven Whitehouse   [GFS2] Fix recurs...
1172
  	int unlock = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1173

7afd88d91   Steven Whitehouse   [GFS2] Fix a page...
1174
  	if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) {
dcf3dd852   Steven Whitehouse   [GFS2] Fix recurs...
1175
1176
1177
1178
  		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
  		if (error)
  			return error;
  		unlock = 1;
b3b94faa5   David Teigland   [GFS2] The core o...
1179
  	}
dcf3dd852   Steven Whitehouse   [GFS2] Fix recurs...
1180
  	generic_fillattr(inode, stat);
d7c103d0b   Steven Whitehouse   [GFS2] Fix recurs...
1181
  	if (unlock)
dcf3dd852   Steven Whitehouse   [GFS2] Fix recurs...
1182
1183
1184
  		gfs2_glock_dq_uninit(&gh);
  
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1185
1186
1187
1188
1189
  }
  
  static int gfs2_setxattr(struct dentry *dentry, const char *name,
  			 const void *data, size_t size, int flags)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1190
  	struct inode *inode = dentry->d_inode;
40b78a322   Steven Whitehouse   GFS2: Clean up of...
1191
1192
1193
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_holder gh;
  	int ret;
b3b94faa5   David Teigland   [GFS2] The core o...
1194

40b78a322   Steven Whitehouse   GFS2: Clean up of...
1195
1196
1197
1198
1199
1200
1201
1202
  	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
  	ret = gfs2_glock_nq(&gh);
  	if (ret == 0) {
  		ret = generic_setxattr(dentry, name, data, size, flags);
  		gfs2_glock_dq(&gh);
  	}
  	gfs2_holder_uninit(&gh);
  	return ret;
b3b94faa5   David Teigland   [GFS2] The core o...
1203
1204
1205
1206
1207
  }
  
  static ssize_t gfs2_getxattr(struct dentry *dentry, const char *name,
  			     void *data, size_t size)
  {
40b78a322   Steven Whitehouse   GFS2: Clean up of...
1208
1209
1210
1211
  	struct inode *inode = dentry->d_inode;
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_holder gh;
  	int ret;
b3b94faa5   David Teigland   [GFS2] The core o...
1212

40b78a322   Steven Whitehouse   GFS2: Clean up of...
1213
1214
1215
1216
1217
1218
1219
1220
  	gfs2_holder_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh);
  	ret = gfs2_glock_nq(&gh);
  	if (ret == 0) {
  		ret = generic_getxattr(dentry, name, data, size);
  		gfs2_glock_dq(&gh);
  	}
  	gfs2_holder_uninit(&gh);
  	return ret;
b3b94faa5   David Teigland   [GFS2] The core o...
1221
1222
1223
1224
  }
  
  static int gfs2_removexattr(struct dentry *dentry, const char *name)
  {
40b78a322   Steven Whitehouse   GFS2: Clean up of...
1225
1226
1227
1228
  	struct inode *inode = dentry->d_inode;
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_holder gh;
  	int ret;
b3b94faa5   David Teigland   [GFS2] The core o...
1229

40b78a322   Steven Whitehouse   GFS2: Clean up of...
1230
1231
1232
1233
1234
1235
1236
1237
  	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
  	ret = gfs2_glock_nq(&gh);
  	if (ret == 0) {
  		ret = generic_removexattr(dentry, name);
  		gfs2_glock_dq(&gh);
  	}
  	gfs2_holder_uninit(&gh);
  	return ret;
b3b94faa5   David Teigland   [GFS2] The core o...
1238
  }
e9079cce2   Steven Whitehouse   GFS2: Support for...
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
  static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
  		       u64 start, u64 len)
  {
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_holder gh;
  	int ret;
  
  	ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC);
  	if (ret)
  		return ret;
  
  	mutex_lock(&inode->i_mutex);
  
  	ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
  	if (ret)
  		goto out;
  
  	if (gfs2_is_stuffed(ip)) {
  		u64 phys = ip->i_no_addr << inode->i_blkbits;
  		u64 size = i_size_read(inode);
  		u32 flags = FIEMAP_EXTENT_LAST|FIEMAP_EXTENT_NOT_ALIGNED|
  			    FIEMAP_EXTENT_DATA_INLINE;
  		phys += sizeof(struct gfs2_dinode);
  		phys += start;
  		if (start + len > size)
  			len = size - start;
  		if (start < size)
  			ret = fiemap_fill_next_extent(fieinfo, start, phys,
  						      len, flags);
  		if (ret == 1)
  			ret = 0;
  	} else {
  		ret = __generic_block_fiemap(inode, fieinfo, start, len,
  					     gfs2_block_map);
  	}
  
  	gfs2_glock_dq_uninit(&gh);
  out:
  	mutex_unlock(&inode->i_mutex);
  	return ret;
  }
92e1d5be9   Arjan van de Ven   [PATCH] mark stru...
1280
  const struct inode_operations gfs2_file_iops = {
e6305c43e   Al Viro   [PATCH] sanitize ...
1281
  	.permission = gfs2_permission,
b3b94faa5   David Teigland   [GFS2] The core o...
1282
1283
1284
1285
1286
1287
  	.setattr = gfs2_setattr,
  	.getattr = gfs2_getattr,
  	.setxattr = gfs2_setxattr,
  	.getxattr = gfs2_getxattr,
  	.listxattr = gfs2_listxattr,
  	.removexattr = gfs2_removexattr,
e9079cce2   Steven Whitehouse   GFS2: Support for...
1288
  	.fiemap = gfs2_fiemap,
b3b94faa5   David Teigland   [GFS2] The core o...
1289
  };
92e1d5be9   Arjan van de Ven   [PATCH] mark stru...
1290
  const struct inode_operations gfs2_dir_iops = {
b3b94faa5   David Teigland   [GFS2] The core o...
1291
1292
1293
1294
1295
1296
1297
1298
1299
  	.create = gfs2_create,
  	.lookup = gfs2_lookup,
  	.link = gfs2_link,
  	.unlink = gfs2_unlink,
  	.symlink = gfs2_symlink,
  	.mkdir = gfs2_mkdir,
  	.rmdir = gfs2_rmdir,
  	.mknod = gfs2_mknod,
  	.rename = gfs2_rename,
e6305c43e   Al Viro   [PATCH] sanitize ...
1300
  	.permission = gfs2_permission,
b3b94faa5   David Teigland   [GFS2] The core o...
1301
1302
1303
1304
1305
1306
  	.setattr = gfs2_setattr,
  	.getattr = gfs2_getattr,
  	.setxattr = gfs2_setxattr,
  	.getxattr = gfs2_getxattr,
  	.listxattr = gfs2_listxattr,
  	.removexattr = gfs2_removexattr,
e9079cce2   Steven Whitehouse   GFS2: Support for...
1307
  	.fiemap = gfs2_fiemap,
b3b94faa5   David Teigland   [GFS2] The core o...
1308
  };
92e1d5be9   Arjan van de Ven   [PATCH] mark stru...
1309
  const struct inode_operations gfs2_symlink_iops = {
c177c2ac8   Al Viro   Switch gfs2 to nd...
1310
  	.readlink = generic_readlink,
b3b94faa5   David Teigland   [GFS2] The core o...
1311
  	.follow_link = gfs2_follow_link,
c177c2ac8   Al Viro   Switch gfs2 to nd...
1312
  	.put_link = gfs2_put_link,
e6305c43e   Al Viro   [PATCH] sanitize ...
1313
  	.permission = gfs2_permission,
b3b94faa5   David Teigland   [GFS2] The core o...
1314
1315
1316
1317
1318
1319
  	.setattr = gfs2_setattr,
  	.getattr = gfs2_getattr,
  	.setxattr = gfs2_setxattr,
  	.getxattr = gfs2_getxattr,
  	.listxattr = gfs2_listxattr,
  	.removexattr = gfs2_removexattr,
e9079cce2   Steven Whitehouse   GFS2: Support for...
1320
  	.fiemap = gfs2_fiemap,
b3b94faa5   David Teigland   [GFS2] The core o...
1321
  };