Blame view

fs/gfs2/dir.c 45.8 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
9
10
   */
  
  /*
61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
   * Implements Extendible Hashing as described in:
   *   "Extendible Hashing" by Fagin, et al in
   *     __ACM Trans. on Database Systems__, Sept 1979.
   *
   *
   * Here's the layout of dirents which is essentially the same as that of ext2
   * within a single block. The field de_name_len is the number of bytes
   * actually required for the name (no null terminator). The field de_rec_len
   * is the number of bytes allocated to the dirent. The offset of the next
   * dirent in the block is (dirent + dirent->de_rec_len). When a dirent is
   * deleted, the preceding dirent inherits its allocated space, ie
   * prev->de_rec_len += deleted->de_rec_len. Since the next dirent is obtained
   * by adding de_rec_len to the current dirent, this essentially causes the
   * deleted dirent to get jumped over when iterating through all the dirents.
   *
   * When deleting the first dirent in a block, there is no previous dirent so
   * the field de_ino is set to zero to designate it as deleted. When allocating
   * a dirent, gfs2_dirent_alloc iterates through the dirents in a block. If the
   * first dirent has (de_ino == 0) and de_rec_len is large enough, this first
   * dirent is allocated. Otherwise it must go through all the 'used' dirents
   * searching for one in which the amount of total space minus the amount of
   * used space will provide enough space for the new dirent.
   *
   * There are two types of blocks in which dirents reside. In a stuffed dinode,
   * the dirents begin at offset sizeof(struct gfs2_dinode) from the beginning of
   * the block.  In leaves, they begin at offset sizeof(struct gfs2_leaf) from the
   * beginning of the leaf block. The dirents reside in leaves when
   *
   * dip->i_di.di_flags & GFS2_DIF_EXHASH is true
   *
   * Otherwise, the dirents are "linear", within a single stuffed dinode block.
   *
   * When the dirents are in leaves, the actual contents of the directory file are
   * used as an array of 64-bit block pointers pointing to the leaf blocks. The
   * dirents are NOT in the directory file itself. There can be more than one
   * block pointer in the array that points to the same leaf. In fact, when a
   * directory is first converted from linear to exhash, all of the pointers
   * point to the same leaf.
   *
   * When a leaf is completely full, the size of the hash table can be
   * doubled unless it is already at the maximum size which is hard coded into
   * GFS2_DIR_MAX_DEPTH. After that, leaves are chained together in a linked list,
   * but never before the maximum hash table size has been reached.
   */
b3b94faa5   David Teigland   [GFS2] The core o...
55
56
57
58
  
  #include <linux/sched.h>
  #include <linux/slab.h>
  #include <linux/spinlock.h>
b3b94faa5   David Teigland   [GFS2] The core o...
59
60
  #include <linux/buffer_head.h>
  #include <linux/sort.h>
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
61
  #include <linux/gfs2_ondisk.h>
71b86f562   Steven Whitehouse   [GFS2] Further up...
62
  #include <linux/crc32.h>
fe1bdedc6   Steven Whitehouse   [GFS2] Use vmallo...
63
  #include <linux/vmalloc.h>
7d308590a   Fabio Massimo Di Nitto   [GFS2] Export lm_...
64
  #include <linux/lm_interface.h>
b3b94faa5   David Teigland   [GFS2] The core o...
65
66
  
  #include "gfs2.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
67
  #include "incore.h"
b3b94faa5   David Teigland   [GFS2] The core o...
68
69
70
  #include "dir.h"
  #include "glock.h"
  #include "inode.h"
b3b94faa5   David Teigland   [GFS2] The core o...
71
72
73
74
  #include "meta_io.h"
  #include "quota.h"
  #include "rgrp.h"
  #include "trans.h"
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
75
  #include "bmap.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
76
  #include "util.h"
b3b94faa5   David Teigland   [GFS2] The core o...
77
78
79
  
  #define IS_LEAF     1 /* Hashed (leaf) directory */
  #define IS_DINODE   2 /* Linear (stuffed dinode block) directory */
cd915493f   Steven Whitehouse   [GFS2] Change all...
80
81
  #define gfs2_disk_hash2offset(h) (((u64)(h)) >> 1)
  #define gfs2_dir_offset2hash(p) ((u32)(((u64)(p)) << 1))
b3b94faa5   David Teigland   [GFS2] The core o...
82

907b9bceb   Steven Whitehouse   [GFS2/DLM] Fix tr...
83
  typedef int (*leaf_call_t) (struct gfs2_inode *dip, u32 index, u32 len,
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
84
85
86
  			    u64 leaf_no, void *data);
  typedef int (*gfs2_dscan_t)(const struct gfs2_dirent *dent,
  			    const struct qstr *name, void *opaque);
b3b94faa5   David Teigland   [GFS2] The core o...
87

61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
88

cd915493f   Steven Whitehouse   [GFS2] Change all...
89
  int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block,
61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
90
  			    struct buffer_head **bhp)
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
91
92
  {
  	struct buffer_head *bh;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
93

61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
94
95
96
97
  	bh = gfs2_meta_new(ip->i_gl, block);
  	gfs2_trans_add_bh(ip->i_gl, bh, 1);
  	gfs2_metatype_set(bh, GFS2_METATYPE_JD, GFS2_FORMAT_JD);
  	gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
98
99
100
  	*bhp = bh;
  	return 0;
  }
cd915493f   Steven Whitehouse   [GFS2] Change all...
101
  static int gfs2_dir_get_existing_buffer(struct gfs2_inode *ip, u64 block,
61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
102
103
104
105
  					struct buffer_head **bhp)
  {
  	struct buffer_head *bh;
  	int error;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
106

7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
107
  	error = gfs2_meta_read(ip->i_gl, block, DIO_WAIT, &bh);
61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
108
109
  	if (error)
  		return error;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
110
  	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) {
61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
111
112
113
114
115
116
  		brelse(bh);
  		return -EIO;
  	}
  	*bhp = bh;
  	return 0;
  }
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
117
118
119
  
  static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf,
  				  unsigned int offset, unsigned int size)
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
120
121
122
123
124
125
126
127
128
  {
  	struct buffer_head *dibh;
  	int error;
  
  	error = gfs2_meta_inode_buffer(ip, &dibh);
  	if (error)
  		return error;
  
  	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
129
  	memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
  	if (ip->i_di.di_size < offset + size)
  		ip->i_di.di_size = offset + size;
  	ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds();
  	gfs2_dinode_out(&ip->i_di, dibh->b_data);
  
  	brelse(dibh);
  
  	return size;
  }
  
  
  
  /**
   * gfs2_dir_write_data - Write directory information to the inode
   * @ip: The GFS2 inode
   * @buf: The buffer containing information to be written
   * @offset: The file offset to start writing at
   * @size: The amount of data to write
   *
   * Returns: The number of bytes correctly written or error code
   */
  static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
cd915493f   Steven Whitehouse   [GFS2] Change all...
152
  			       u64 offset, unsigned int size)
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
153
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
154
  	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
155
  	struct buffer_head *dibh;
cd915493f   Steven Whitehouse   [GFS2] Change all...
156
157
  	u64 lblock, dblock;
  	u32 extlen = 0;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
158
159
160
161
162
163
164
165
166
  	unsigned int o;
  	int copied = 0;
  	int error = 0;
  
  	if (!size)
  		return 0;
  
  	if (gfs2_is_stuffed(ip) &&
  	    offset + size <= sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode))
568f4c965   Steven Whitehouse   [GFS2] 80 Column ...
167
168
  		return gfs2_dir_write_stuffed(ip, buf, (unsigned int)offset,
  					      size);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
169
170
171
172
173
  
  	if (gfs2_assert_warn(sdp, gfs2_is_jdata(ip)))
  		return -EINVAL;
  
  	if (gfs2_is_stuffed(ip)) {
f25ef0c1b   Steven Whitehouse   [GFS2] Tidy gfs2_...
174
  		error = gfs2_unstuff_dinode(ip, NULL);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
175
  		if (error)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
176
  			return error;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
177
178
179
180
181
182
183
184
  	}
  
  	lblock = offset;
  	o = do_div(lblock, sdp->sd_jbsize) + sizeof(struct gfs2_meta_header);
  
  	while (copied < size) {
  		unsigned int amount;
  		struct buffer_head *bh;
348acd48f   Adrian Bunk   [GFS2] fs/gfs2/di...
185
  		int new = 0;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
186
187
188
189
190
191
192
  
  		amount = size - copied;
  		if (amount > sdp->sd_sb.sb_bsize - o)
  			amount = sdp->sd_sb.sb_bsize - o;
  
  		if (!extlen) {
  			new = 1;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
193
  			error = gfs2_extent_map(&ip->i_inode, lblock, &new,
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
194
  						&dblock, &extlen);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
195
196
197
198
199
200
  			if (error)
  				goto fail;
  			error = -EIO;
  			if (gfs2_assert_withdraw(sdp, dblock))
  				goto fail;
  		}
61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
201
202
203
204
  		if (amount == sdp->sd_jbsize || new)
  			error = gfs2_dir_get_new_buffer(ip, dblock, &bh);
  		else
  			error = gfs2_dir_get_existing_buffer(ip, dblock, &bh);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
205
206
207
208
209
210
  		if (error)
  			goto fail;
  
  		gfs2_trans_add_bh(ip->i_gl, bh, 1);
  		memcpy(bh->b_data + o, buf, amount);
  		brelse(bh);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
211

899bb2645   Steven Whitehouse   [GFS2] Fix bug in...
212
  		buf += amount;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
  		copied += amount;
  		lblock++;
  		dblock++;
  		extlen--;
  
  		o = sizeof(struct gfs2_meta_header);
  	}
  
  out:
  	error = gfs2_meta_inode_buffer(ip, &dibh);
  	if (error)
  		return error;
  
  	if (ip->i_di.di_size < offset + copied)
  		ip->i_di.di_size = offset + copied;
  	ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds();
  
  	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
  	gfs2_dinode_out(&ip->i_di, dibh->b_data);
  	brelse(dibh);
  
  	return copied;
  fail:
  	if (copied)
  		goto out;
  	return error;
  }
  
  static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, char *buf,
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
242
  				 u64 offset, unsigned int size)
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
  {
  	struct buffer_head *dibh;
  	int error;
  
  	error = gfs2_meta_inode_buffer(ip, &dibh);
  	if (!error) {
  		offset += sizeof(struct gfs2_dinode);
  		memcpy(buf, dibh->b_data + offset, size);
  		brelse(dibh);
  	}
  
  	return (error) ? error : size;
  }
  
  
  /**
   * gfs2_dir_read_data - Read a data from a directory inode
   * @ip: The GFS2 Inode
   * @buf: The buffer to place result into
   * @offset: File offset to begin jdata_readng from
   * @size: Amount of data to transfer
   *
   * Returns: The amount of data actually copied or the error
   */
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
267
268
  static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, u64 offset,
  			      unsigned int size, unsigned ra)
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
269
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
270
  	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
cd915493f   Steven Whitehouse   [GFS2] Change all...
271
272
  	u64 lblock, dblock;
  	u32 extlen = 0;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
273
274
275
276
277
278
  	unsigned int o;
  	int copied = 0;
  	int error = 0;
  
  	if (offset >= ip->i_di.di_size)
  		return 0;
c53921248   Jan Engelhardt   [GFS2] More style...
279
  	if (offset + size > ip->i_di.di_size)
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
280
281
282
283
284
285
  		size = ip->i_di.di_size - offset;
  
  	if (!size)
  		return 0;
  
  	if (gfs2_is_stuffed(ip))
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
286
  		return gfs2_dir_read_stuffed(ip, buf, offset, size);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
  
  	if (gfs2_assert_warn(sdp, gfs2_is_jdata(ip)))
  		return -EINVAL;
  
  	lblock = offset;
  	o = do_div(lblock, sdp->sd_jbsize) + sizeof(struct gfs2_meta_header);
  
  	while (copied < size) {
  		unsigned int amount;
  		struct buffer_head *bh;
  		int new;
  
  		amount = size - copied;
  		if (amount > sdp->sd_sb.sb_bsize - o)
  			amount = sdp->sd_sb.sb_bsize - o;
  
  		if (!extlen) {
  			new = 0;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
305
  			error = gfs2_extent_map(&ip->i_inode, lblock, &new,
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
306
  						&dblock, &extlen);
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
307
  			if (error || !dblock)
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
308
  				goto fail;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
309
310
311
312
  			BUG_ON(extlen < 1);
  			if (!ra)
  				extlen = 1;
  			bh = gfs2_meta_ra(ip->i_gl, dblock, extlen);
b7d8ac3e1   Adrian Bunk   [GFS2] gfs2_dir_r...
313
  		} else {
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
314
  			error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, &bh);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
315
316
  			if (error)
  				goto fail;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
317
318
319
320
321
322
323
324
  		}
  		error = gfs2_metatype_check(sdp, bh, GFS2_METATYPE_JD);
  		if (error) {
  			brelse(bh);
  			goto fail;
  		}
  		dblock++;
  		extlen--;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
325
326
  		memcpy(buf, bh->b_data + o, amount);
  		brelse(bh);
899bb2645   Steven Whitehouse   [GFS2] Fix bug in...
327
  		buf += amount;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
328
329
  		copied += amount;
  		lblock++;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
330
331
332
333
334
335
336
  		o = sizeof(struct gfs2_meta_header);
  	}
  
  	return copied;
  fail:
  	return (copied) ? copied : error;
  }
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
337
338
339
340
341
342
  static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent,
  				     const struct qstr *name, int ret)
  {
  	if (dent->de_inum.no_addr != 0 &&
  	    be32_to_cpu(dent->de_hash) == name->hash &&
  	    be16_to_cpu(dent->de_name_len) == name->len &&
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
343
  	    memcmp(dent+1, name->name, name->len) == 0)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
344
345
346
347
348
  		return ret;
  	return 0;
  }
  
  static int gfs2_dirent_find(const struct gfs2_dirent *dent,
71b86f562   Steven Whitehouse   [GFS2] Further up...
349
350
  			    const struct qstr *name,
  			    void *opaque)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
351
352
353
354
355
  {
  	return __gfs2_dirent_find(dent, name, 1);
  }
  
  static int gfs2_dirent_prev(const struct gfs2_dirent *dent,
71b86f562   Steven Whitehouse   [GFS2] Further up...
356
357
  			    const struct qstr *name,
  			    void *opaque)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
358
359
360
361
362
363
364
  {
  	return __gfs2_dirent_find(dent, name, 2);
  }
  
  /*
   * name->name holds ptr to start of block.
   * name->len holds size of block.
b3b94faa5   David Teigland   [GFS2] The core o...
365
   */
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
366
  static int gfs2_dirent_last(const struct gfs2_dirent *dent,
71b86f562   Steven Whitehouse   [GFS2] Further up...
367
368
  			    const struct qstr *name,
  			    void *opaque)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
369
370
371
372
373
374
375
  {
  	const char *start = name->name;
  	const char *end = (const char *)dent + be16_to_cpu(dent->de_rec_len);
  	if (name->len == (end - start))
  		return 1;
  	return 0;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
376

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
377
  static int gfs2_dirent_find_space(const struct gfs2_dirent *dent,
71b86f562   Steven Whitehouse   [GFS2] Further up...
378
379
  				  const struct qstr *name,
  				  void *opaque)
b3b94faa5   David Teigland   [GFS2] The core o...
380
  {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
381
382
383
  	unsigned required = GFS2_DIRENT_SIZE(name->len);
  	unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len));
  	unsigned totlen = be16_to_cpu(dent->de_rec_len);
71b86f562   Steven Whitehouse   [GFS2] Further up...
384
385
  	if (!dent->de_inum.no_addr)
  		actual = GFS2_DIRENT_SIZE(0);
c53921248   Jan Engelhardt   [GFS2] More style...
386
  	if (totlen - actual >= required)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
387
388
389
  		return 1;
  	return 0;
  }
71b86f562   Steven Whitehouse   [GFS2] Further up...
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
  struct dirent_gather {
  	const struct gfs2_dirent **pdent;
  	unsigned offset;
  };
  
  static int gfs2_dirent_gather(const struct gfs2_dirent *dent,
  			      const struct qstr *name,
  			      void *opaque)
  {
  	struct dirent_gather *g = opaque;
  	if (dent->de_inum.no_addr) {
  		g->pdent[g->offset++] = dent;
  	}
  	return 0;
  }
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
  /*
   * Other possible things to check:
   * - Inode located within filesystem size (and on valid block)
   * - Valid directory entry type
   * Not sure how heavy-weight we want to make this... could also check
   * hash is correct for example, but that would take a lot of extra time.
   * For now the most important thing is to check that the various sizes
   * are correct.
   */
  static int gfs2_check_dirent(struct gfs2_dirent *dent, unsigned int offset,
  			     unsigned int size, unsigned int len, int first)
  {
  	const char *msg = "gfs2_dirent too small";
  	if (unlikely(size < sizeof(struct gfs2_dirent)))
  		goto error;
  	msg = "gfs2_dirent misaligned";
  	if (unlikely(offset & 0x7))
  		goto error;
  	msg = "gfs2_dirent points beyond end of block";
  	if (unlikely(offset + size > len))
  		goto error;
  	msg = "zero inode number";
  	if (unlikely(!first && !dent->de_inum.no_addr))
  		goto error;
  	msg = "name length is greater than space in dirent";
  	if (dent->de_inum.no_addr &&
  	    unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) >
  		     size))
  		goto error;
  	return 0;
  error:
  	printk(KERN_WARNING "gfs2_check_dirent: %s (%s)
  ", msg,
  	       first ? "first in block" : "not first in block");
  	return -EIO;
b3b94faa5   David Teigland   [GFS2] The core o...
440
  }
71b86f562   Steven Whitehouse   [GFS2] Further up...
441
  static int gfs2_dirent_offset(const void *buf)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
442
  {
71b86f562   Steven Whitehouse   [GFS2] Further up...
443
444
  	const struct gfs2_meta_header *h = buf;
  	int offset;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
445
446
  
  	BUG_ON(buf == NULL);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
447

e3167ded1   Steven Whitehouse   [GFS] Fix bug in ...
448
  	switch(be32_to_cpu(h->mh_type)) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
449
450
451
452
453
454
455
456
457
  	case GFS2_METATYPE_LF:
  		offset = sizeof(struct gfs2_leaf);
  		break;
  	case GFS2_METATYPE_DI:
  		offset = sizeof(struct gfs2_dinode);
  		break;
  	default:
  		goto wrong_type;
  	}
71b86f562   Steven Whitehouse   [GFS2] Further up...
458
459
460
461
  	return offset;
  wrong_type:
  	printk(KERN_WARNING "gfs2_scan_dirent: wrong block type %u
  ",
e3167ded1   Steven Whitehouse   [GFS] Fix bug in ...
462
  	       be32_to_cpu(h->mh_type));
71b86f562   Steven Whitehouse   [GFS2] Further up...
463
464
  	return -1;
  }
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
465
  static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
71b86f562   Steven Whitehouse   [GFS2] Further up...
466
467
468
469
470
471
472
473
  					    unsigned int len, gfs2_dscan_t scan,
  					    const struct qstr *name,
  					    void *opaque)
  {
  	struct gfs2_dirent *dent, *prev;
  	unsigned offset;
  	unsigned size;
  	int ret = 0;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
474

71b86f562   Steven Whitehouse   [GFS2] Further up...
475
476
477
478
479
  	ret = gfs2_dirent_offset(buf);
  	if (ret < 0)
  		goto consist_inode;
  
  	offset = ret;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
480
  	prev = NULL;
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
481
  	dent = buf + offset;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
482
483
484
485
  	size = be16_to_cpu(dent->de_rec_len);
  	if (gfs2_check_dirent(dent, offset, size, len, 1))
  		goto consist_inode;
  	do {
71b86f562   Steven Whitehouse   [GFS2] Further up...
486
  		ret = scan(dent, name, opaque);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
487
488
489
490
491
492
  		if (ret)
  			break;
  		offset += size;
  		if (offset == len)
  			break;
  		prev = dent;
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
493
  		dent = buf + offset;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
  		size = be16_to_cpu(dent->de_rec_len);
  		if (gfs2_check_dirent(dent, offset, size, len, 0))
  			goto consist_inode;
  	} while(1);
  
  	switch(ret) {
  	case 0:
  		return NULL;
  	case 1:
  		return dent;
  	case 2:
  		return prev ? prev : dent;
  	default:
  		BUG_ON(ret > 0);
  		return ERR_PTR(ret);
  	}
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
510
  consist_inode:
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
511
  	gfs2_consist_inode(GFS2_I(inode));
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
512
513
  	return ERR_PTR(-EIO);
  }
b3b94faa5   David Teigland   [GFS2] The core o...
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
  /**
   * dirent_first - Return the first dirent
   * @dip: the directory
   * @bh: The buffer
   * @dent: Pointer to list of dirents
   *
   * return first dirent whether bh points to leaf or stuffed dinode
   *
   * Returns: IS_LEAF, IS_DINODE, or -errno
   */
  
  static int dirent_first(struct gfs2_inode *dip, struct buffer_head *bh,
  			struct gfs2_dirent **dent)
  {
  	struct gfs2_meta_header *h = (struct gfs2_meta_header *)bh->b_data;
e3167ded1   Steven Whitehouse   [GFS] Fix bug in ...
529
  	if (be32_to_cpu(h->mh_type) == GFS2_METATYPE_LF) {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
530
  		if (gfs2_meta_check(GFS2_SB(&dip->i_inode), bh))
b3b94faa5   David Teigland   [GFS2] The core o...
531
532
533
534
535
  			return -EIO;
  		*dent = (struct gfs2_dirent *)(bh->b_data +
  					       sizeof(struct gfs2_leaf));
  		return IS_LEAF;
  	} else {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
536
  		if (gfs2_metatype_check(GFS2_SB(&dip->i_inode), bh, GFS2_METATYPE_DI))
b3b94faa5   David Teigland   [GFS2] The core o...
537
538
539
540
541
542
  			return -EIO;
  		*dent = (struct gfs2_dirent *)(bh->b_data +
  					       sizeof(struct gfs2_dinode));
  		return IS_DINODE;
  	}
  }
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
  static int dirent_check_reclen(struct gfs2_inode *dip,
  			       const struct gfs2_dirent *d, const void *end_p)
  {
  	const void *ptr = d;
  	u16 rec_len = be16_to_cpu(d->de_rec_len);
  
  	if (unlikely(rec_len < sizeof(struct gfs2_dirent)))
  		goto broken;
  	ptr += rec_len;
  	if (ptr < end_p)
  		return rec_len;
  	if (ptr == end_p)
  		return -ENOENT;
  broken:
  	gfs2_consist_inode(dip);
  	return -EIO;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
560
561
562
563
564
565
566
567
568
569
570
571
  /**
   * dirent_next - Next dirent
   * @dip: the directory
   * @bh: The buffer
   * @dent: Pointer to list of dirents
   *
   * Returns: 0 on success, error code otherwise
   */
  
  static int dirent_next(struct gfs2_inode *dip, struct buffer_head *bh,
  		       struct gfs2_dirent **dent)
  {
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
572
573
574
  	struct gfs2_dirent *cur = *dent, *tmp;
  	char *bh_end = bh->b_data + bh->b_size;
  	int ret;
b3b94faa5   David Teigland   [GFS2] The core o...
575

2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
576
577
578
  	ret = dirent_check_reclen(dip, cur, bh_end);
  	if (ret < 0)
  		return ret;
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
579

2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
580
581
582
583
  	tmp = (void *)cur + ret;
  	ret = dirent_check_reclen(dip, tmp, bh_end);
  	if (ret == -EIO)
  		return ret;
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
584

b3b94faa5   David Teigland   [GFS2] The core o...
585
586
587
588
589
590
591
          /* Only the first dent could ever have de_inum.no_addr == 0 */
  	if (!tmp->de_inum.no_addr) {
  		gfs2_consist_inode(dip);
  		return -EIO;
  	}
  
  	*dent = tmp;
b3b94faa5   David Teigland   [GFS2] The core o...
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
  	return 0;
  }
  
  /**
   * dirent_del - Delete a dirent
   * @dip: The GFS2 inode
   * @bh: The buffer
   * @prev: The previous dirent
   * @cur: The current dirent
   *
   */
  
  static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh,
  		       struct gfs2_dirent *prev, struct gfs2_dirent *cur)
  {
cd915493f   Steven Whitehouse   [GFS2] Change all...
607
  	u16 cur_rec_len, prev_rec_len;
b3b94faa5   David Teigland   [GFS2] The core o...
608
609
610
611
612
  
  	if (!cur->de_inum.no_addr) {
  		gfs2_consist_inode(dip);
  		return;
  	}
d4e9c4c3b   Steven Whitehouse   [GFS2] Add an add...
613
  	gfs2_trans_add_bh(dip->i_gl, bh, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
614
615
616
617
618
619
620
621
622
623
624
  
  	/* If there is no prev entry, this is the first entry in the block.
  	   The de_rec_len is already as big as it needs to be.  Just zero
  	   out the inode number and return.  */
  
  	if (!prev) {
  		cur->de_inum.no_addr = 0;	/* No endianess worries */
  		return;
  	}
  
  	/*  Combine this dentry with the previous one.  */
fc69d0d33   Steven Whitehouse   [GFS2] Change ond...
625
626
  	prev_rec_len = be16_to_cpu(prev->de_rec_len);
  	cur_rec_len = be16_to_cpu(cur->de_rec_len);
b3b94faa5   David Teigland   [GFS2] The core o...
627
628
629
630
631
632
633
  
  	if ((char *)prev + prev_rec_len != (char *)cur)
  		gfs2_consist_inode(dip);
  	if ((char *)cur + cur_rec_len > bh->b_data + bh->b_size)
  		gfs2_consist_inode(dip);
  
  	prev_rec_len += cur_rec_len;
fc69d0d33   Steven Whitehouse   [GFS2] Change ond...
634
  	prev->de_rec_len = cpu_to_be16(prev_rec_len);
b3b94faa5   David Teigland   [GFS2] The core o...
635
  }
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
636
637
638
  /*
   * Takes a dent from which to grab space as an argument. Returns the
   * newly created dent.
b3b94faa5   David Teigland   [GFS2] The core o...
639
   */
08bc2dbc7   Adrian Bunk   [GFS2] [-mm patch...
640
641
642
643
  static struct gfs2_dirent *gfs2_init_dirent(struct inode *inode,
  					    struct gfs2_dirent *dent,
  					    const struct qstr *name,
  					    struct buffer_head *bh)
b3b94faa5   David Teigland   [GFS2] The core o...
644
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
645
  	struct gfs2_inode *ip = GFS2_I(inode);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
646
647
648
649
650
651
652
653
654
655
656
657
  	struct gfs2_dirent *ndent;
  	unsigned offset = 0, totlen;
  
  	if (dent->de_inum.no_addr)
  		offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len));
  	totlen = be16_to_cpu(dent->de_rec_len);
  	BUG_ON(offset + name->len > totlen);
  	gfs2_trans_add_bh(ip->i_gl, bh, 1);
  	ndent = (struct gfs2_dirent *)((char *)dent + offset);
  	dent->de_rec_len = cpu_to_be16(offset);
  	gfs2_qstr2dirent(name, totlen - offset, ndent);
  	return ndent;
b3b94faa5   David Teigland   [GFS2] The core o...
658
  }
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
659
660
661
  static struct gfs2_dirent *gfs2_dirent_alloc(struct inode *inode,
  					     struct buffer_head *bh,
  					     const struct qstr *name)
b3b94faa5   David Teigland   [GFS2] The core o...
662
663
  {
  	struct gfs2_dirent *dent;
907b9bceb   Steven Whitehouse   [GFS2/DLM] Fix tr...
664
  	dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size,
71b86f562   Steven Whitehouse   [GFS2] Further up...
665
  				gfs2_dirent_find_space, name, NULL);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
666
667
668
  	if (!dent || IS_ERR(dent))
  		return dent;
  	return gfs2_init_dirent(inode, dent, name, bh);
b3b94faa5   David Teigland   [GFS2] The core o...
669
  }
cd915493f   Steven Whitehouse   [GFS2] Change all...
670
  static int get_leaf(struct gfs2_inode *dip, u64 leaf_no,
b3b94faa5   David Teigland   [GFS2] The core o...
671
672
673
  		    struct buffer_head **bhp)
  {
  	int error;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
674
  	error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_WAIT, bhp);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
675
676
677
  	if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) {
  		/* printk(KERN_INFO "block num=%llu
  ", leaf_no); */
b3b94faa5   David Teigland   [GFS2] The core o...
678
  		error = -EIO;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
679
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
680
681
682
683
684
685
686
687
688
689
690
691
  
  	return error;
  }
  
  /**
   * get_leaf_nr - Get a leaf number associated with the index
   * @dip: The GFS2 inode
   * @index:
   * @leaf_out:
   *
   * Returns: 0 on success, error code otherwise
   */
cd915493f   Steven Whitehouse   [GFS2] Change all...
692
693
  static int get_leaf_nr(struct gfs2_inode *dip, u32 index,
  		       u64 *leaf_out)
b3b94faa5   David Teigland   [GFS2] The core o...
694
  {
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
695
  	__be64 leaf_no;
b3b94faa5   David Teigland   [GFS2] The core o...
696
  	int error;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
697
  	error = gfs2_dir_read_data(dip, (char *)&leaf_no,
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
698
699
  				    index * sizeof(__be64),
  				    sizeof(__be64), 0);
cd915493f   Steven Whitehouse   [GFS2] Change all...
700
  	if (error != sizeof(u64))
b3b94faa5   David Teigland   [GFS2] The core o...
701
702
703
704
705
706
  		return (error < 0) ? error : -EIO;
  
  	*leaf_out = be64_to_cpu(leaf_no);
  
  	return 0;
  }
cd915493f   Steven Whitehouse   [GFS2] Change all...
707
  static int get_first_leaf(struct gfs2_inode *dip, u32 index,
b3b94faa5   David Teigland   [GFS2] The core o...
708
709
  			  struct buffer_head **bh_out)
  {
cd915493f   Steven Whitehouse   [GFS2] Change all...
710
  	u64 leaf_no;
b3b94faa5   David Teigland   [GFS2] The core o...
711
712
713
714
715
716
717
718
  	int error;
  
  	error = get_leaf_nr(dip, index, &leaf_no);
  	if (!error)
  		error = get_leaf(dip, leaf_no, bh_out);
  
  	return error;
  }
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
719
720
721
722
  static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
  					      const struct qstr *name,
  					      gfs2_dscan_t scan,
  					      struct buffer_head **pbh)
b3b94faa5   David Teigland   [GFS2] The core o...
723
  {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
724
725
  	struct buffer_head *bh;
  	struct gfs2_dirent *dent;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
726
  	struct gfs2_inode *ip = GFS2_I(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
727
  	int error;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
728
729
730
731
732
733
734
735
736
  	if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
  		struct gfs2_leaf *leaf;
  		unsigned hsize = 1 << ip->i_di.di_depth;
  		unsigned index;
  		u64 ln;
  		if (hsize * sizeof(u64) != ip->i_di.di_size) {
  			gfs2_consist_inode(ip);
  			return ERR_PTR(-EIO);
  		}
907b9bceb   Steven Whitehouse   [GFS2/DLM] Fix tr...
737

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
738
739
740
741
742
743
  		index = name->hash >> (32 - ip->i_di.di_depth);
  		error = get_first_leaf(ip, index, &bh);
  		if (error)
  			return ERR_PTR(error);
  		do {
  			dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size,
71b86f562   Steven Whitehouse   [GFS2] Further up...
744
  						scan, name, NULL);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
745
746
747
748
  			if (dent)
  				goto got_dent;
  			leaf = (struct gfs2_leaf *)bh->b_data;
  			ln = be64_to_cpu(leaf->lf_next);
f4154ea03   Steven Whitehouse   [GFS2] Update jou...
749
  			brelse(bh);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
750
751
  			if (!ln)
  				break;
907b9bceb   Steven Whitehouse   [GFS2/DLM] Fix tr...
752

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
753
754
  			error = get_leaf(ip, ln, &bh);
  		} while(!error);
b3b94faa5   David Teigland   [GFS2] The core o...
755

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
756
  		return error ? ERR_PTR(error) : NULL;
b3b94faa5   David Teigland   [GFS2] The core o...
757
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
758

907b9bceb   Steven Whitehouse   [GFS2/DLM] Fix tr...
759

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
760
761
762
  	error = gfs2_meta_inode_buffer(ip, &bh);
  	if (error)
  		return ERR_PTR(error);
71b86f562   Steven Whitehouse   [GFS2] Further up...
763
  	dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, scan, name, NULL);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
764
  got_dent:
f4154ea03   Steven Whitehouse   [GFS2] Update jou...
765
  	if (unlikely(dent == NULL || IS_ERR(dent))) {
ed3865079   Steven Whitehouse   [GFS2] Finally ge...
766
767
768
  		brelse(bh);
  		bh = NULL;
  	}
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
769
770
771
  	*pbh = bh;
  	return dent;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
772

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
773
774
  static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, u16 depth)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
775
  	struct gfs2_inode *ip = GFS2_I(inode);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
776
777
778
779
  	u64 bn = gfs2_alloc_meta(ip);
  	struct buffer_head *bh = gfs2_meta_new(ip->i_gl, bn);
  	struct gfs2_leaf *leaf;
  	struct gfs2_dirent *dent;
71b86f562   Steven Whitehouse   [GFS2] Further up...
780
  	struct qstr name = { .name = "", .len = 0, .hash = 0 };
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
781
782
  	if (!bh)
  		return NULL;
907b9bceb   Steven Whitehouse   [GFS2/DLM] Fix tr...
783

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
784
785
786
787
  	gfs2_trans_add_bh(ip->i_gl, bh, 1);
  	gfs2_metatype_set(bh, GFS2_METATYPE_LF, GFS2_FORMAT_LF);
  	leaf = (struct gfs2_leaf *)bh->b_data;
  	leaf->lf_depth = cpu_to_be16(depth);
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
788
  	leaf->lf_entries = 0;
a2d7d021d   Al Viro   [GFS2] gfs2 endia...
789
  	leaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE);
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
790
  	leaf->lf_next = 0;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
791
792
  	memset(leaf->lf_reserved, 0, sizeof(leaf->lf_reserved));
  	dent = (struct gfs2_dirent *)(leaf+1);
71b86f562   Steven Whitehouse   [GFS2] Further up...
793
  	gfs2_qstr2dirent(&name, bh->b_size - sizeof(struct gfs2_leaf), dent);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
794
795
  	*pbh = bh;
  	return leaf;
b3b94faa5   David Teigland   [GFS2] The core o...
796
797
798
799
800
801
802
803
  }
  
  /**
   * dir_make_exhash - Convert a stuffed directory into an ExHash directory
   * @dip: The GFS2 inode
   *
   * Returns: 0 on success, error code otherwise
   */
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
804
  static int dir_make_exhash(struct inode *inode)
b3b94faa5   David Teigland   [GFS2] The core o...
805
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
806
807
  	struct gfs2_inode *dip = GFS2_I(inode);
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
808
  	struct gfs2_dirent *dent;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
809
  	struct qstr args;
b3b94faa5   David Teigland   [GFS2] The core o...
810
811
812
  	struct buffer_head *bh, *dibh;
  	struct gfs2_leaf *leaf;
  	int y;
cd915493f   Steven Whitehouse   [GFS2] Change all...
813
  	u32 x;
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
814
815
  	__be64 *lp;
  	u64 bn;
b3b94faa5   David Teigland   [GFS2] The core o...
816
817
818
819
820
  	int error;
  
  	error = gfs2_meta_inode_buffer(dip, &dibh);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
821
  	/*  Turn over a new leaf  */
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
822
823
824
825
  	leaf = new_leaf(inode, &bh, 0);
  	if (!leaf)
  		return -ENOSPC;
  	bn = bh->b_blocknr;
b3b94faa5   David Teigland   [GFS2] The core o...
826
827
  
  	gfs2_assert(sdp, dip->i_di.di_entries < (1 << 16));
b3b94faa5   David Teigland   [GFS2] The core o...
828
829
830
831
832
833
834
835
836
837
  	leaf->lf_entries = cpu_to_be16(dip->i_di.di_entries);
  
  	/*  Copy dirents  */
  
  	gfs2_buffer_copy_tail(bh, sizeof(struct gfs2_leaf), dibh,
  			     sizeof(struct gfs2_dinode));
  
  	/*  Find last entry  */
  
  	x = 0;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
838
839
840
  	args.len = bh->b_size - sizeof(struct gfs2_dinode) +
  		   sizeof(struct gfs2_leaf);
  	args.name = bh->b_data;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
841
  	dent = gfs2_dirent_scan(&dip->i_inode, bh->b_data, bh->b_size,
71b86f562   Steven Whitehouse   [GFS2] Further up...
842
  				gfs2_dirent_last, &args, NULL);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
843
844
845
846
847
848
849
850
851
  	if (!dent) {
  		brelse(bh);
  		brelse(dibh);
  		return -EIO;
  	}
  	if (IS_ERR(dent)) {
  		brelse(bh);
  		brelse(dibh);
  		return PTR_ERR(dent);
b3b94faa5   David Teigland   [GFS2] The core o...
852
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
853
854
855
  
  	/*  Adjust the last dirent's record length
  	   (Remember that dent still points to the last entry.)  */
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
856
  	dent->de_rec_len = cpu_to_be16(be16_to_cpu(dent->de_rec_len) +
b3b94faa5   David Teigland   [GFS2] The core o...
857
  		sizeof(struct gfs2_dinode) -
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
858
  		sizeof(struct gfs2_leaf));
b3b94faa5   David Teigland   [GFS2] The core o...
859
860
861
862
863
  
  	brelse(bh);
  
  	/*  We're done with the new leaf block, now setup the new
  	    hash table.  */
d4e9c4c3b   Steven Whitehouse   [GFS2] Add an add...
864
  	gfs2_trans_add_bh(dip->i_gl, dibh, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
865
  	gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
866
  	lp = (__be64 *)(dibh->b_data + sizeof(struct gfs2_dinode));
b3b94faa5   David Teigland   [GFS2] The core o...
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
  
  	for (x = sdp->sd_hash_ptrs; x--; lp++)
  		*lp = cpu_to_be64(bn);
  
  	dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2;
  	dip->i_di.di_blocks++;
  	dip->i_di.di_flags |= GFS2_DIF_EXHASH;
  	dip->i_di.di_payload_format = 0;
  
  	for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ;
  	dip->i_di.di_depth = y;
  
  	gfs2_dinode_out(&dip->i_di, dibh->b_data);
  
  	brelse(dibh);
  
  	return 0;
  }
  
  /**
   * dir_split_leaf - Split a leaf block into two
   * @dip: The GFS2 inode
   * @index:
   * @leaf_no:
   *
   * Returns: 0 on success, error code on failure
   */
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
894
  static int dir_split_leaf(struct inode *inode, const struct qstr *name)
b3b94faa5   David Teigland   [GFS2] The core o...
895
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
896
  	struct gfs2_inode *dip = GFS2_I(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
897
898
  	struct buffer_head *nbh, *obh, *dibh;
  	struct gfs2_leaf *nleaf, *oleaf;
4da3c6463   Steven Whitehouse   [GFS2] Fix a coup...
899
  	struct gfs2_dirent *dent = NULL, *prev = NULL, *next = NULL, *new;
cd915493f   Steven Whitehouse   [GFS2] Change all...
900
  	u32 start, len, half_len, divider;
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
901
902
  	u64 bn, leaf_no;
  	__be64 *lp;
cd915493f   Steven Whitehouse   [GFS2] Change all...
903
  	u32 index;
b3b94faa5   David Teigland   [GFS2] The core o...
904
905
  	int x, moved = 0;
  	int error;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
906
907
908
909
  	index = name->hash >> (32 - dip->i_di.di_depth);
  	error = get_leaf_nr(dip, index, &leaf_no);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
910
911
  
  	/*  Get the old leaf block  */
b3b94faa5   David Teigland   [GFS2] The core o...
912
913
  	error = get_leaf(dip, leaf_no, &obh);
  	if (error)
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
914
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
915

b3b94faa5   David Teigland   [GFS2] The core o...
916
  	oleaf = (struct gfs2_leaf *)obh->b_data;
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
917
918
919
920
921
922
  	if (dip->i_di.di_depth == be16_to_cpu(oleaf->lf_depth)) {
  		brelse(obh);
  		return 1; /* can't split */
  	}
  
  	gfs2_trans_add_bh(dip->i_gl, obh, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
923

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
924
925
926
927
928
929
  	nleaf = new_leaf(inode, &nbh, be16_to_cpu(oleaf->lf_depth) + 1);
  	if (!nleaf) {
  		brelse(obh);
  		return -ENOSPC;
  	}
  	bn = nbh->b_blocknr;
b3b94faa5   David Teigland   [GFS2] The core o...
930

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
931
  	/*  Compute the start and len of leaf pointers in the hash table.  */
b3b94faa5   David Teigland   [GFS2] The core o...
932
933
934
  	len = 1 << (dip->i_di.di_depth - be16_to_cpu(oleaf->lf_depth));
  	half_len = len >> 1;
  	if (!half_len) {
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
935
936
  		printk(KERN_WARNING "di_depth %u lf_depth %u index %u
  ", dip->i_di.di_depth, be16_to_cpu(oleaf->lf_depth), index);
b3b94faa5   David Teigland   [GFS2] The core o...
937
938
939
940
941
942
943
944
945
946
  		gfs2_consist_inode(dip);
  		error = -EIO;
  		goto fail_brelse;
  	}
  
  	start = (index & ~(len - 1));
  
  	/* Change the pointers.
  	   Don't bother distinguishing stuffed from non-stuffed.
  	   This code is complicated enough already. */
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
947
  	lp = kmalloc(half_len * sizeof(__be64), GFP_NOFS | __GFP_NOFAIL);
b3b94faa5   David Teigland   [GFS2] The core o...
948
  	/*  Change the pointers  */
b3b94faa5   David Teigland   [GFS2] The core o...
949
950
  	for (x = 0; x < half_len; x++)
  		lp[x] = cpu_to_be64(bn);
cd915493f   Steven Whitehouse   [GFS2] Change all...
951
952
953
  	error = gfs2_dir_write_data(dip, (char *)lp, start * sizeof(u64),
  				    half_len * sizeof(u64));
  	if (error != half_len * sizeof(u64)) {
b3b94faa5   David Teigland   [GFS2] The core o...
954
955
956
957
958
959
960
961
  		if (error >= 0)
  			error = -EIO;
  		goto fail_lpfree;
  	}
  
  	kfree(lp);
  
  	/*  Compute the divider  */
b3b94faa5   David Teigland   [GFS2] The core o...
962
963
964
  	divider = (start + half_len) << (32 - dip->i_di.di_depth);
  
  	/*  Copy the entries  */
b3b94faa5   David Teigland   [GFS2] The core o...
965
966
967
968
969
970
971
972
973
  	dirent_first(dip, obh, &dent);
  
  	do {
  		next = dent;
  		if (dirent_next(dip, obh, &next))
  			next = NULL;
  
  		if (dent->de_inum.no_addr &&
  		    be32_to_cpu(dent->de_hash) < divider) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
974
975
976
977
  			struct qstr str;
  			str.name = (char*)(dent+1);
  			str.len = be16_to_cpu(dent->de_name_len);
  			str.hash = be32_to_cpu(dent->de_hash);
71b86f562   Steven Whitehouse   [GFS2] Further up...
978
  			new = gfs2_dirent_alloc(inode, nbh, &str);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
979
980
981
982
  			if (IS_ERR(new)) {
  				error = PTR_ERR(new);
  				break;
  			}
b3b94faa5   David Teigland   [GFS2] The core o...
983
984
  
  			new->de_inum = dent->de_inum; /* No endian worries */
b3b94faa5   David Teigland   [GFS2] The core o...
985
  			new->de_type = dent->de_type; /* No endian worries */
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
986
  			nleaf->lf_entries = cpu_to_be16(be16_to_cpu(nleaf->lf_entries)+1);
b3b94faa5   David Teigland   [GFS2] The core o...
987
988
989
990
991
  
  			dirent_del(dip, obh, prev, dent);
  
  			if (!oleaf->lf_entries)
  				gfs2_consist_inode(dip);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
992
  			oleaf->lf_entries = cpu_to_be16(be16_to_cpu(oleaf->lf_entries)-1);
b3b94faa5   David Teigland   [GFS2] The core o...
993
994
995
996
997
  
  			if (!prev)
  				prev = dent;
  
  			moved = 1;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
998
  		} else {
b3b94faa5   David Teigland   [GFS2] The core o...
999
  			prev = dent;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1000
  		}
b3b94faa5   David Teigland   [GFS2] The core o...
1001
  		dent = next;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1002
  	} while (dent);
b3b94faa5   David Teigland   [GFS2] The core o...
1003

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1004
  	oleaf->lf_depth = nleaf->lf_depth;
b3b94faa5   David Teigland   [GFS2] The core o...
1005
1006
  
  	error = gfs2_meta_inode_buffer(dip, &dibh);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1007
  	if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) {
b3b94faa5   David Teigland   [GFS2] The core o...
1008
1009
1010
1011
1012
1013
1014
1015
1016
  		dip->i_di.di_blocks++;
  		gfs2_dinode_out(&dip->i_di, dibh->b_data);
  		brelse(dibh);
  	}
  
  	brelse(obh);
  	brelse(nbh);
  
  	return error;
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
1017
  fail_lpfree:
b3b94faa5   David Teigland   [GFS2] The core o...
1018
  	kfree(lp);
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
1019
  fail_brelse:
b3b94faa5   David Teigland   [GFS2] The core o...
1020
  	brelse(obh);
b3b94faa5   David Teigland   [GFS2] The core o...
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
  	brelse(nbh);
  	return error;
  }
  
  /**
   * dir_double_exhash - Double size of ExHash table
   * @dip: The GFS2 dinode
   *
   * Returns: 0 on success, error code on failure
   */
  
  static int dir_double_exhash(struct gfs2_inode *dip)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1034
  	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
b3b94faa5   David Teigland   [GFS2] The core o...
1035
  	struct buffer_head *dibh;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1036
1037
1038
1039
  	u32 hsize;
  	u64 *buf;
  	u64 *from, *to;
  	u64 block;
b3b94faa5   David Teigland   [GFS2] The core o...
1040
1041
1042
1043
  	int x;
  	int error = 0;
  
  	hsize = 1 << dip->i_di.di_depth;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1044
  	if (hsize * sizeof(u64) != dip->i_di.di_size) {
b3b94faa5   David Teigland   [GFS2] The core o...
1045
1046
1047
1048
1049
1050
1051
1052
1053
  		gfs2_consist_inode(dip);
  		return -EIO;
  	}
  
  	/*  Allocate both the "from" and "to" buffers in one big chunk  */
  
  	buf = kcalloc(3, sdp->sd_hash_bsize, GFP_KERNEL | __GFP_NOFAIL);
  
  	for (block = dip->i_di.di_size >> sdp->sd_hash_bsize_shift; block--;) {
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
1054
  		error = gfs2_dir_read_data(dip, (char *)buf,
b3b94faa5   David Teigland   [GFS2] The core o...
1055
  					    block * sdp->sd_hash_bsize,
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
1056
  					    sdp->sd_hash_bsize, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
1057
1058
1059
1060
1061
1062
1063
  		if (error != sdp->sd_hash_bsize) {
  			if (error >= 0)
  				error = -EIO;
  			goto fail;
  		}
  
  		from = buf;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1064
  		to = (u64 *)((char *)buf + sdp->sd_hash_bsize);
b3b94faa5   David Teigland   [GFS2] The core o...
1065
1066
1067
1068
1069
  
  		for (x = sdp->sd_hash_ptrs; x--; from++) {
  			*to++ = *from;	/*  No endianess worries  */
  			*to++ = *from;
  		}
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
1070
  		error = gfs2_dir_write_data(dip,
b3b94faa5   David Teigland   [GFS2] The core o...
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
  					     (char *)buf + sdp->sd_hash_bsize,
  					     block * sdp->sd_sb.sb_bsize,
  					     sdp->sd_sb.sb_bsize);
  		if (error != sdp->sd_sb.sb_bsize) {
  			if (error >= 0)
  				error = -EIO;
  			goto fail;
  		}
  	}
  
  	kfree(buf);
  
  	error = gfs2_meta_inode_buffer(dip, &dibh);
  	if (!gfs2_assert_withdraw(sdp, !error)) {
  		dip->i_di.di_depth++;
  		gfs2_dinode_out(&dip->i_di, dibh->b_data);
  		brelse(dibh);
  	}
  
  	return error;
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1091
  fail:
b3b94faa5   David Teigland   [GFS2] The core o...
1092
  	kfree(buf);
b3b94faa5   David Teigland   [GFS2] The core o...
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
  	return error;
  }
  
  /**
   * compare_dents - compare directory entries by hash value
   * @a: first dent
   * @b: second dent
   *
   * When comparing the hash entries of @a to @b:
   *   gt: returns 1
   *   lt: returns -1
   *   eq: returns 0
   */
  
  static int compare_dents(const void *a, const void *b)
  {
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
1109
  	const struct gfs2_dirent *dent_a, *dent_b;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1110
  	u32 hash_a, hash_b;
b3b94faa5   David Teigland   [GFS2] The core o...
1111
  	int ret = 0;
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
1112
  	dent_a = *(const struct gfs2_dirent **)a;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1113
  	hash_a = be32_to_cpu(dent_a->de_hash);
b3b94faa5   David Teigland   [GFS2] The core o...
1114

2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
1115
  	dent_b = *(const struct gfs2_dirent **)b;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1116
  	hash_b = be32_to_cpu(dent_b->de_hash);
b3b94faa5   David Teigland   [GFS2] The core o...
1117
1118
1119
1120
1121
1122
  
  	if (hash_a > hash_b)
  		ret = 1;
  	else if (hash_a < hash_b)
  		ret = -1;
  	else {
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
1123
1124
  		unsigned int len_a = be16_to_cpu(dent_a->de_name_len);
  		unsigned int len_b = be16_to_cpu(dent_b->de_name_len);
b3b94faa5   David Teigland   [GFS2] The core o...
1125
1126
1127
1128
1129
1130
  
  		if (len_a > len_b)
  			ret = 1;
  		else if (len_a < len_b)
  			ret = -1;
  		else
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
1131
  			ret = memcmp(dent_a + 1, dent_b + 1, len_a);
b3b94faa5   David Teigland   [GFS2] The core o...
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
  	}
  
  	return ret;
  }
  
  /**
   * do_filldir_main - read out directory entries
   * @dip: The GFS2 inode
   * @offset: The offset in the file to read from
   * @opaque: opaque data to pass to filldir
   * @filldir: The function to pass entries to
   * @darr: an array of struct gfs2_dirent pointers to read
   * @entries: the number of entries in darr
   * @copied: pointer to int that's non-zero if a entry has been copied out
   *
   * Jump through some hoops to make sure that if there are hash collsions,
   * they are read out at the beginning of a buffer.  We want to minimize
   * the possibility that they will fall into different readdir buffers or
   * that someone will want to seek to that location.
   *
   * Returns: errno, >0 on exception from filldir
   */
cd915493f   Steven Whitehouse   [GFS2] Change all...
1154
  static int do_filldir_main(struct gfs2_inode *dip, u64 *offset,
b3b94faa5   David Teigland   [GFS2] The core o...
1155
  			   void *opaque, gfs2_filldir_t filldir,
cd915493f   Steven Whitehouse   [GFS2] Change all...
1156
  			   const struct gfs2_dirent **darr, u32 entries,
b3b94faa5   David Teigland   [GFS2] The core o...
1157
1158
  			   int *copied)
  {
71b86f562   Steven Whitehouse   [GFS2] Further up...
1159
  	const struct gfs2_dirent *dent, *dent_next;
629a21e7e   Al Viro   [GFS2] split and ...
1160
  	struct gfs2_inum_host inum;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1161
  	u64 off, off_next;
b3b94faa5   David Teigland   [GFS2] The core o...
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
  	unsigned int x, y;
  	int run = 0;
  	int error = 0;
  
  	sort(darr, entries, sizeof(struct gfs2_dirent *), compare_dents, NULL);
  
  	dent_next = darr[0];
  	off_next = be32_to_cpu(dent_next->de_hash);
  	off_next = gfs2_disk_hash2offset(off_next);
  
  	for (x = 0, y = 1; x < entries; x++, y++) {
  		dent = dent_next;
  		off = off_next;
  
  		if (y < entries) {
  			dent_next = darr[y];
  			off_next = be32_to_cpu(dent_next->de_hash);
  			off_next = gfs2_disk_hash2offset(off_next);
  
  			if (off < *offset)
  				continue;
  			*offset = off;
  
  			if (off_next == off) {
  				if (*copied && !run)
  					return 1;
  				run = 1;
  			} else
  				run = 0;
  		} else {
  			if (off < *offset)
  				continue;
  			*offset = off;
  		}
  
  		gfs2_inum_in(&inum, (char *)&dent->de_inum);
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
1198
  		error = filldir(opaque, (const char *)(dent + 1),
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
1199
  				be16_to_cpu(dent->de_name_len),
b3b94faa5   David Teigland   [GFS2] The core o...
1200
  				off, &inum,
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
1201
  				be16_to_cpu(dent->de_type));
b3b94faa5   David Teigland   [GFS2] The core o...
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
  		if (error)
  			return 1;
  
  		*copied = 1;
  	}
  
  	/* Increment the *offset by one, so the next time we come into the
  	   do_filldir fxn, we get the next entry instead of the last one in the
  	   current leaf */
  
  	(*offset)++;
  
  	return 0;
  }
71b86f562   Steven Whitehouse   [GFS2] Further up...
1216
1217
1218
  static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
  			      gfs2_filldir_t filldir, int *copied,
  			      unsigned *depth, u64 leaf_no)
b3b94faa5   David Teigland   [GFS2] The core o...
1219
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1220
  	struct gfs2_inode *ip = GFS2_I(inode);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
  	struct buffer_head *bh;
  	struct gfs2_leaf *lf;
  	unsigned entries = 0;
  	unsigned leaves = 0;
  	const struct gfs2_dirent **darr, *dent;
  	struct dirent_gather g;
  	struct buffer_head **larr;
  	int leaf = 0;
  	int error, i;
  	u64 lfn = leaf_no;
b3b94faa5   David Teigland   [GFS2] The core o...
1231

b3b94faa5   David Teigland   [GFS2] The core o...
1232
  	do {
71b86f562   Steven Whitehouse   [GFS2] Further up...
1233
  		error = get_leaf(ip, lfn, &bh);
b3b94faa5   David Teigland   [GFS2] The core o...
1234
  		if (error)
71b86f562   Steven Whitehouse   [GFS2] Further up...
1235
1236
1237
1238
1239
1240
1241
1242
1243
  			goto out;
  		lf = (struct gfs2_leaf *)bh->b_data;
  		if (leaves == 0)
  			*depth = be16_to_cpu(lf->lf_depth);
  		entries += be16_to_cpu(lf->lf_entries);
  		leaves++;
  		lfn = be64_to_cpu(lf->lf_next);
  		brelse(bh);
  	} while(lfn);
b3b94faa5   David Teigland   [GFS2] The core o...
1244
1245
1246
  
  	if (!entries)
  		return 0;
71b86f562   Steven Whitehouse   [GFS2] Further up...
1247
  	error = -ENOMEM;
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
1248
  	larr = vmalloc((leaves + entries) * sizeof(void *));
71b86f562   Steven Whitehouse   [GFS2] Further up...
1249
1250
1251
1252
1253
1254
  	if (!larr)
  		goto out;
  	darr = (const struct gfs2_dirent **)(larr + leaves);
  	g.pdent = darr;
  	g.offset = 0;
  	lfn = leaf_no;
b3b94faa5   David Teigland   [GFS2] The core o...
1255

71b86f562   Steven Whitehouse   [GFS2] Further up...
1256
1257
  	do {
  		error = get_leaf(ip, lfn, &bh);
b3b94faa5   David Teigland   [GFS2] The core o...
1258
  		if (error)
71b86f562   Steven Whitehouse   [GFS2] Further up...
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
  			goto out_kfree;
  		lf = (struct gfs2_leaf *)bh->b_data;
  		lfn = be64_to_cpu(lf->lf_next);
  		if (lf->lf_entries) {
  			dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size,
  						gfs2_dirent_gather, NULL, &g);
  			error = PTR_ERR(dent);
  			if (IS_ERR(dent)) {
  				goto out_kfree;
  			}
  			error = 0;
  			larr[leaf++] = bh;
b3b94faa5   David Teigland   [GFS2] The core o...
1271
  		} else {
71b86f562   Steven Whitehouse   [GFS2] Further up...
1272
  			brelse(bh);
b3b94faa5   David Teigland   [GFS2] The core o...
1273
  		}
71b86f562   Steven Whitehouse   [GFS2] Further up...
1274
  	} while(lfn);
b3b94faa5   David Teigland   [GFS2] The core o...
1275

71b86f562   Steven Whitehouse   [GFS2] Further up...
1276
  	error = do_filldir_main(ip, offset, opaque, filldir, darr,
b3b94faa5   David Teigland   [GFS2] The core o...
1277
  				entries, copied);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1278
1279
1280
  out_kfree:
  	for(i = 0; i < leaf; i++)
  		brelse(larr[i]);
fe1bdedc6   Steven Whitehouse   [GFS2] Use vmallo...
1281
  	vfree(larr);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1282
  out:
b3b94faa5   David Teigland   [GFS2] The core o...
1283
1284
1285
1286
  	return error;
  }
  
  /**
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1287
1288
1289
1290
1291
   * dir_e_read - Reads the entries from a directory into a filldir buffer
   * @dip: dinode pointer
   * @offset: the hash of the last entry read shifted to the right once
   * @opaque: buffer for the filldir function to fill
   * @filldir: points to the filldir function to use
b3b94faa5   David Teigland   [GFS2] The core o...
1292
   *
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1293
   * Returns: errno
b3b94faa5   David Teigland   [GFS2] The core o...
1294
   */
cd915493f   Steven Whitehouse   [GFS2] Change all...
1295
  static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1296
  		      gfs2_filldir_t filldir)
b3b94faa5   David Teigland   [GFS2] The core o...
1297
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1298
1299
  	struct gfs2_inode *dip = GFS2_I(inode);
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
cd915493f   Steven Whitehouse   [GFS2] Change all...
1300
1301
1302
  	u32 hsize, len = 0;
  	u32 ht_offset, lp_offset, ht_offset_cur = -1;
  	u32 hash, index;
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
1303
  	__be64 *lp;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1304
1305
  	int copied = 0;
  	int error = 0;
4da3c6463   Steven Whitehouse   [GFS2] Fix a coup...
1306
  	unsigned depth = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1307
1308
  
  	hsize = 1 << dip->i_di.di_depth;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1309
  	if (hsize * sizeof(u64) != dip->i_di.di_size) {
b3b94faa5   David Teigland   [GFS2] The core o...
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
  		gfs2_consist_inode(dip);
  		return -EIO;
  	}
  
  	hash = gfs2_dir_offset2hash(*offset);
  	index = hash >> (32 - dip->i_di.di_depth);
  
  	lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL);
  	if (!lp)
  		return -ENOMEM;
  
  	while (index < hsize) {
  		lp_offset = index & (sdp->sd_hash_ptrs - 1);
  		ht_offset = index - lp_offset;
  
  		if (ht_offset_cur != ht_offset) {
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
1326
  			error = gfs2_dir_read_data(dip, (char *)lp,
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
1327
  						ht_offset * sizeof(__be64),
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
1328
  						sdp->sd_hash_bsize, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
1329
1330
1331
1332
1333
1334
1335
  			if (error != sdp->sd_hash_bsize) {
  				if (error >= 0)
  					error = -EIO;
  				goto out;
  			}
  			ht_offset_cur = ht_offset;
  		}
71b86f562   Steven Whitehouse   [GFS2] Further up...
1336
1337
1338
  		error = gfs2_dir_read_leaf(inode, offset, opaque, filldir,
  					   &copied, &depth,
  					   be64_to_cpu(lp[lp_offset]));
b3b94faa5   David Teigland   [GFS2] The core o...
1339
  		if (error)
71b86f562   Steven Whitehouse   [GFS2] Further up...
1340
  			break;
b3b94faa5   David Teigland   [GFS2] The core o...
1341

71b86f562   Steven Whitehouse   [GFS2] Further up...
1342
  		len = 1 << (dip->i_di.di_depth - depth);
b3b94faa5   David Teigland   [GFS2] The core o...
1343
1344
  		index = (index & ~(len - 1)) + len;
  	}
71b86f562   Steven Whitehouse   [GFS2] Further up...
1345
  out:
b3b94faa5   David Teigland   [GFS2] The core o...
1346
  	kfree(lp);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1347
1348
  	if (error > 0)
  		error = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1349
1350
  	return error;
  }
cd915493f   Steven Whitehouse   [GFS2] Change all...
1351
  int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
71b86f562   Steven Whitehouse   [GFS2] Further up...
1352
  		  gfs2_filldir_t filldir)
b3b94faa5   David Teigland   [GFS2] The core o...
1353
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1354
  	struct gfs2_inode *dip = GFS2_I(inode);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1355
1356
  	struct dirent_gather g;
  	const struct gfs2_dirent **darr, *dent;
b3b94faa5   David Teigland   [GFS2] The core o...
1357
1358
1359
  	struct buffer_head *dibh;
  	int copied = 0;
  	int error;
71b86f562   Steven Whitehouse   [GFS2] Further up...
1360
1361
1362
1363
1364
  	if (!dip->i_di.di_entries)
  		return 0;
  
  	if (dip->i_di.di_flags & GFS2_DIF_EXHASH)
  		return dir_e_read(inode, offset, opaque, filldir);
b3b94faa5   David Teigland   [GFS2] The core o...
1365
1366
1367
1368
  	if (!gfs2_is_stuffed(dip)) {
  		gfs2_consist_inode(dip);
  		return -EIO;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
1369
1370
1371
  	error = gfs2_meta_inode_buffer(dip, &dibh);
  	if (error)
  		return error;
71b86f562   Steven Whitehouse   [GFS2] Further up...
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
  	error = -ENOMEM;
  	darr = kmalloc(dip->i_di.di_entries * sizeof(struct gfs2_dirent *),
  		       GFP_KERNEL);
  	if (darr) {
  		g.pdent = darr;
  		g.offset = 0;
  		dent = gfs2_dirent_scan(inode, dibh->b_data, dibh->b_size,
  					gfs2_dirent_gather, NULL, &g);
  		if (IS_ERR(dent)) {
  			error = PTR_ERR(dent);
  			goto out;
  		}
  		error = do_filldir_main(dip, offset, opaque, filldir, darr,
  					dip->i_di.di_entries, &copied);
  out:
  		kfree(darr);
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
1389
1390
1391
1392
1393
1394
1395
  	if (error > 0)
  		error = 0;
  
  	brelse(dibh);
  
  	return error;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
  /**
   * gfs2_dir_search - Search a directory
   * @dip: The GFS2 inode
   * @filename:
   * @inode:
   *
   * This routine searches a directory for a file or another directory.
   * Assumes a glock is held on dip.
   *
   * Returns: errno
   */
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1407
  int gfs2_dir_search(struct inode *dir, const struct qstr *name,
629a21e7e   Al Viro   [GFS2] split and ...
1408
  		    struct gfs2_inum_host *inum, unsigned int *type)
b3b94faa5   David Teigland   [GFS2] The core o...
1409
  {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
  	struct buffer_head *bh;
  	struct gfs2_dirent *dent;
  
  	dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
  	if (dent) {
  		if (IS_ERR(dent))
  			return PTR_ERR(dent);
  		if (inum)
  			gfs2_inum_in(inum, (char *)&dent->de_inum);
  		if (type)
  			*type = be16_to_cpu(dent->de_type);
  		brelse(bh);
  		return 0;
  	}
  	return -ENOENT;
  }
  
  static int dir_new_leaf(struct inode *inode, const struct qstr *name)
  {
  	struct buffer_head *bh, *obh;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1430
  	struct gfs2_inode *ip = GFS2_I(inode);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1431
  	struct gfs2_leaf *leaf, *oleaf;
b3b94faa5   David Teigland   [GFS2] The core o...
1432
  	int error;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1433
1434
  	u32 index;
  	u64 bn;
b3b94faa5   David Teigland   [GFS2] The core o...
1435

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
  	index = name->hash >> (32 - ip->i_di.di_depth);
  	error = get_first_leaf(ip, index, &obh);
  	if (error)
  		return error;
  	do {
  		oleaf = (struct gfs2_leaf *)obh->b_data;
  		bn = be64_to_cpu(oleaf->lf_next);
  		if (!bn)
  			break;
  		brelse(obh);
  		error = get_leaf(ip, bn, &obh);
  		if (error)
  			return error;
  	} while(1);
b3b94faa5   David Teigland   [GFS2] The core o...
1450

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1451
1452
1453
1454
1455
1456
1457
  	gfs2_trans_add_bh(ip->i_gl, obh, 1);
  
  	leaf = new_leaf(inode, &bh, be16_to_cpu(oleaf->lf_depth));
  	if (!leaf) {
  		brelse(obh);
  		return -ENOSPC;
  	}
4d8012b60   Steven Whitehouse   [GFS2] Fix bug wh...
1458
  	oleaf->lf_next = cpu_to_be64(bh->b_blocknr);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
  	brelse(bh);
  	brelse(obh);
  
  	error = gfs2_meta_inode_buffer(ip, &bh);
  	if (error)
  		return error;
  	gfs2_trans_add_bh(ip->i_gl, bh, 1);
  	ip->i_di.di_blocks++;
  	gfs2_dinode_out(&ip->i_di, bh->b_data);
  	brelse(bh);
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
  }
  
  /**
   * gfs2_dir_add - Add new filename into directory
   * @dip: The GFS2 inode
   * @filename: The new name
   * @inode: The inode number of the entry
   * @type: The type of the entry
   *
   * Returns: 0 on success, error code on failure
   */
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1481
  int gfs2_dir_add(struct inode *inode, const struct qstr *name,
629a21e7e   Al Viro   [GFS2] split and ...
1482
  		 const struct gfs2_inum_host *inum, unsigned type)
b3b94faa5   David Teigland   [GFS2] The core o...
1483
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1484
  	struct gfs2_inode *ip = GFS2_I(inode);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1485
1486
1487
  	struct buffer_head *bh;
  	struct gfs2_dirent *dent;
  	struct gfs2_leaf *leaf;
b3b94faa5   David Teigland   [GFS2] The core o...
1488
  	int error;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
  	while(1) {
  		dent = gfs2_dirent_search(inode, name, gfs2_dirent_find_space,
  					  &bh);
  		if (dent) {
  			if (IS_ERR(dent))
  				return PTR_ERR(dent);
  			dent = gfs2_init_dirent(inode, dent, name, bh);
  			gfs2_inum_out(inum, (char *)&dent->de_inum);
  			dent->de_type = cpu_to_be16(type);
  			if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
  				leaf = (struct gfs2_leaf *)bh->b_data;
  				leaf->lf_entries = cpu_to_be16(be16_to_cpu(leaf->lf_entries) + 1);
  			}
  			brelse(bh);
  			error = gfs2_meta_inode_buffer(ip, &bh);
  			if (error)
  				break;
  			gfs2_trans_add_bh(ip->i_gl, bh, 1);
  			ip->i_di.di_entries++;
  			ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds();
  			gfs2_dinode_out(&ip->i_di, bh->b_data);
  			brelse(bh);
  			error = 0;
  			break;
  		}
  		if (!(ip->i_di.di_flags & GFS2_DIF_EXHASH)) {
  			error = dir_make_exhash(inode);
  			if (error)
  				break;
  			continue;
  		}
  		error = dir_split_leaf(inode, name);
  		if (error == 0)
  			continue;
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
1523
  		if (error < 0)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1524
1525
1526
1527
1528
1529
  			break;
  		if (ip->i_di.di_depth < GFS2_DIR_MAX_DEPTH) {
  			error = dir_double_exhash(ip);
  			if (error)
  				break;
  			error = dir_split_leaf(inode, name);
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
1530
  			if (error < 0)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1531
  				break;
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
1532
1533
  			if (error == 0)
  				continue;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1534
1535
1536
1537
1538
1539
1540
  		}
  		error = dir_new_leaf(inode, name);
  		if (!error)
  			continue;
  		error = -ENOSPC;
  		break;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
1541
1542
  	return error;
  }
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1543

b3b94faa5   David Teigland   [GFS2] The core o...
1544
1545
1546
1547
1548
1549
1550
  /**
   * gfs2_dir_del - Delete a directory entry
   * @dip: The GFS2 inode
   * @filename: The filename
   *
   * Returns: 0 on success, error code on failure
   */
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1551
  int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
b3b94faa5   David Teigland   [GFS2] The core o...
1552
  {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1553
1554
  	struct gfs2_dirent *dent, *prev = NULL;
  	struct buffer_head *bh;
b3b94faa5   David Teigland   [GFS2] The core o...
1555
  	int error;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1556
1557
  	/* Returns _either_ the entry (if its first in block) or the
  	   previous entry otherwise */
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1558
  	dent = gfs2_dirent_search(&dip->i_inode, name, gfs2_dirent_prev, &bh);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1559
1560
1561
1562
1563
1564
1565
1566
1567
  	if (!dent) {
  		gfs2_consist_inode(dip);
  		return -EIO;
  	}
  	if (IS_ERR(dent)) {
  		gfs2_consist_inode(dip);
  		return PTR_ERR(dent);
  	}
  	/* If not first in block, adjust pointers accordingly */
71b86f562   Steven Whitehouse   [GFS2] Further up...
1568
  	if (gfs2_dirent_find(dent, name, NULL) == 0) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
  		prev = dent;
  		dent = (struct gfs2_dirent *)((char *)dent + be16_to_cpu(prev->de_rec_len));
  	}
  
  	dirent_del(dip, bh, prev, dent);
  	if (dip->i_di.di_flags & GFS2_DIF_EXHASH) {
  		struct gfs2_leaf *leaf = (struct gfs2_leaf *)bh->b_data;
  		u16 entries = be16_to_cpu(leaf->lf_entries);
  		if (!entries)
  			gfs2_consist_inode(dip);
  		leaf->lf_entries = cpu_to_be16(--entries);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1580
  	}
ed3865079   Steven Whitehouse   [GFS2] Finally ge...
1581
  	brelse(bh);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
  
  	error = gfs2_meta_inode_buffer(dip, &bh);
  	if (error)
  		return error;
  
  	if (!dip->i_di.di_entries)
  		gfs2_consist_inode(dip);
  	gfs2_trans_add_bh(dip->i_gl, bh, 1);
  	dip->i_di.di_entries--;
  	dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds();
  	gfs2_dinode_out(&dip->i_di, bh->b_data);
  	brelse(bh);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1594
  	mark_inode_dirty(&dip->i_inode);
b3b94faa5   David Teigland   [GFS2] The core o...
1595
1596
1597
  
  	return error;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
  /**
   * gfs2_dir_mvino - Change inode number of directory entry
   * @dip: The GFS2 inode
   * @filename:
   * @new_inode:
   *
   * This routine changes the inode number of a directory entry.  It's used
   * by rename to change ".." when a directory is moved.
   * Assumes a glock is held on dvp.
   *
   * Returns: errno
   */
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1610
  int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
629a21e7e   Al Viro   [GFS2] split and ...
1611
  		   struct gfs2_inum_host *inum, unsigned int new_type)
b3b94faa5   David Teigland   [GFS2] The core o...
1612
  {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1613
1614
  	struct buffer_head *bh;
  	struct gfs2_dirent *dent;
b3b94faa5   David Teigland   [GFS2] The core o...
1615
  	int error;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1616
  	dent = gfs2_dirent_search(&dip->i_inode, filename, gfs2_dirent_find, &bh);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1617
1618
1619
1620
1621
1622
  	if (!dent) {
  		gfs2_consist_inode(dip);
  		return -EIO;
  	}
  	if (IS_ERR(dent))
  		return PTR_ERR(dent);
b3b94faa5   David Teigland   [GFS2] The core o...
1623

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
  	gfs2_trans_add_bh(dip->i_gl, bh, 1);
  	gfs2_inum_out(inum, (char *)&dent->de_inum);
  	dent->de_type = cpu_to_be16(new_type);
  
  	if (dip->i_di.di_flags & GFS2_DIF_EXHASH) {
  		brelse(bh);
  		error = gfs2_meta_inode_buffer(dip, &bh);
  		if (error)
  			return error;
  		gfs2_trans_add_bh(dip->i_gl, bh, 1);
  	}
  
  	dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds();
  	gfs2_dinode_out(&dip->i_di, bh->b_data);
  	brelse(bh);
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
  }
  
  /**
   * foreach_leaf - call a function for each leaf in a directory
   * @dip: the directory
   * @lc: the function to call for each each
   * @data: private data to pass to it
   *
   * Returns: errno
   */
  
  static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1653
  	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
b3b94faa5   David Teigland   [GFS2] The core o...
1654
  	struct buffer_head *bh;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1655
  	struct gfs2_leaf *leaf;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1656
1657
1658
  	u32 hsize, len;
  	u32 ht_offset, lp_offset, ht_offset_cur = -1;
  	u32 index = 0;
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
1659
  	__be64 *lp;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1660
  	u64 leaf_no;
b3b94faa5   David Teigland   [GFS2] The core o...
1661
1662
1663
  	int error = 0;
  
  	hsize = 1 << dip->i_di.di_depth;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1664
  	if (hsize * sizeof(u64) != dip->i_di.di_size) {
b3b94faa5   David Teigland   [GFS2] The core o...
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
  		gfs2_consist_inode(dip);
  		return -EIO;
  	}
  
  	lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL);
  	if (!lp)
  		return -ENOMEM;
  
  	while (index < hsize) {
  		lp_offset = index & (sdp->sd_hash_ptrs - 1);
  		ht_offset = index - lp_offset;
  
  		if (ht_offset_cur != ht_offset) {
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
1678
  			error = gfs2_dir_read_data(dip, (char *)lp,
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
1679
  						ht_offset * sizeof(__be64),
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
1680
  						sdp->sd_hash_bsize, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
  			if (error != sdp->sd_hash_bsize) {
  				if (error >= 0)
  					error = -EIO;
  				goto out;
  			}
  			ht_offset_cur = ht_offset;
  		}
  
  		leaf_no = be64_to_cpu(lp[lp_offset]);
  		if (leaf_no) {
  			error = get_leaf(dip, leaf_no, &bh);
  			if (error)
  				goto out;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1694
  			leaf = (struct gfs2_leaf *)bh->b_data;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1695
  			len = 1 << (dip->i_di.di_depth - be16_to_cpu(leaf->lf_depth));
634ee0b9f   Steven Whitehouse   [GFS2] Fix use af...
1696
  			brelse(bh);
b3b94faa5   David Teigland   [GFS2] The core o...
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
  
  			error = lc(dip, index, len, leaf_no, data);
  			if (error)
  				goto out;
  
  			index = (index & ~(len - 1)) + len;
  		} else
  			index++;
  	}
  
  	if (index != hsize) {
  		gfs2_consist_inode(dip);
  		error = -EIO;
  	}
634ee0b9f   Steven Whitehouse   [GFS2] Fix use af...
1711
  out:
b3b94faa5   David Teigland   [GFS2] The core o...
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
  	kfree(lp);
  
  	return error;
  }
  
  /**
   * leaf_dealloc - Deallocate a directory leaf
   * @dip: the directory
   * @index: the hash table offset in the directory
   * @len: the number of pointers to this leaf
   * @leaf_no: the leaf number
   * @data: not used
   *
   * Returns: errno
   */
cd915493f   Steven Whitehouse   [GFS2] Change all...
1727
1728
  static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
  			u64 leaf_no, void *data)
b3b94faa5   David Teigland   [GFS2] The core o...
1729
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1730
  	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1731
  	struct gfs2_leaf *tmp_leaf;
b3b94faa5   David Teigland   [GFS2] The core o...
1732
1733
  	struct gfs2_rgrp_list rlist;
  	struct buffer_head *bh, *dibh;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1734
  	u64 blk, nblk;
b3b94faa5   David Teigland   [GFS2] The core o...
1735
1736
  	unsigned int rg_blocks = 0, l_blocks = 0;
  	char *ht;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1737
  	unsigned int x, size = len * sizeof(u64);
b3b94faa5   David Teigland   [GFS2] The core o...
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
  	int error;
  
  	memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
  
  	ht = kzalloc(size, GFP_KERNEL);
  	if (!ht)
  		return -ENOMEM;
  
  	gfs2_alloc_get(dip);
  
  	error = gfs2_quota_hold(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
  	if (error)
  		goto out;
  
  	error = gfs2_rindex_hold(sdp, &dip->i_alloc.al_ri_gh);
  	if (error)
  		goto out_qs;
  
  	/*  Count the number of leaves  */
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1757
  	for (blk = leaf_no; blk; blk = nblk) {
b3b94faa5   David Teigland   [GFS2] The core o...
1758
1759
1760
  		error = get_leaf(dip, blk, &bh);
  		if (error)
  			goto out_rlist;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1761
1762
  		tmp_leaf = (struct gfs2_leaf *)bh->b_data;
  		nblk = be64_to_cpu(tmp_leaf->lf_next);
b3b94faa5   David Teigland   [GFS2] The core o...
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
  		brelse(bh);
  
  		gfs2_rlist_add(sdp, &rlist, blk);
  		l_blocks++;
  	}
  
  	gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, 0);
  
  	for (x = 0; x < rlist.rl_rgrps; x++) {
  		struct gfs2_rgrpd *rgd;
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
1773
  		rgd = rlist.rl_ghs[x].gh_gl->gl_object;
b3b94faa5   David Teigland   [GFS2] The core o...
1774
1775
1776
1777
1778
1779
1780
1781
  		rg_blocks += rgd->rd_ri.ri_length;
  	}
  
  	error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
  	if (error)
  		goto out_rlist;
  
  	error = gfs2_trans_begin(sdp,
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
1782
  			rg_blocks + (DIV_ROUND_UP(size, sdp->sd_jbsize) + 1) +
b3b94faa5   David Teigland   [GFS2] The core o...
1783
1784
1785
  			RES_DINODE + RES_STATFS + RES_QUOTA, l_blocks);
  	if (error)
  		goto out_rg_gunlock;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1786
  	for (blk = leaf_no; blk; blk = nblk) {
b3b94faa5   David Teigland   [GFS2] The core o...
1787
1788
1789
  		error = get_leaf(dip, blk, &bh);
  		if (error)
  			goto out_end_trans;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1790
1791
  		tmp_leaf = (struct gfs2_leaf *)bh->b_data;
  		nblk = be64_to_cpu(tmp_leaf->lf_next);
b3b94faa5   David Teigland   [GFS2] The core o...
1792
1793
1794
1795
1796
1797
1798
1799
  		brelse(bh);
  
  		gfs2_free_meta(dip, blk, 1);
  
  		if (!dip->i_di.di_blocks)
  			gfs2_consist_inode(dip);
  		dip->i_di.di_blocks--;
  	}
cd915493f   Steven Whitehouse   [GFS2] Change all...
1800
  	error = gfs2_dir_write_data(dip, ht, index * sizeof(u64), size);
b3b94faa5   David Teigland   [GFS2] The core o...
1801
1802
1803
1804
1805
1806
1807
1808
1809
  	if (error != size) {
  		if (error >= 0)
  			error = -EIO;
  		goto out_end_trans;
  	}
  
  	error = gfs2_meta_inode_buffer(dip, &dibh);
  	if (error)
  		goto out_end_trans;
d4e9c4c3b   Steven Whitehouse   [GFS2] Add an add...
1810
  	gfs2_trans_add_bh(dip->i_gl, dibh, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
1811
1812
  	gfs2_dinode_out(&dip->i_di, dibh->b_data);
  	brelse(dibh);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1813
  out_end_trans:
b3b94faa5   David Teigland   [GFS2] The core o...
1814
  	gfs2_trans_end(sdp);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1815
  out_rg_gunlock:
b3b94faa5   David Teigland   [GFS2] The core o...
1816
  	gfs2_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1817
  out_rlist:
b3b94faa5   David Teigland   [GFS2] The core o...
1818
1819
  	gfs2_rlist_free(&rlist);
  	gfs2_glock_dq_uninit(&dip->i_alloc.al_ri_gh);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1820
  out_qs:
b3b94faa5   David Teigland   [GFS2] The core o...
1821
  	gfs2_quota_unhold(dip);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1822
  out:
b3b94faa5   David Teigland   [GFS2] The core o...
1823
1824
  	gfs2_alloc_put(dip);
  	kfree(ht);
b3b94faa5   David Teigland   [GFS2] The core o...
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
  	return error;
  }
  
  /**
   * gfs2_dir_exhash_dealloc - free all the leaf blocks in a directory
   * @dip: the directory
   *
   * Dealloc all on-disk directory leaves to FREEMETA state
   * Change on-disk inode type to "regular file"
   *
   * Returns: errno
   */
  
  int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1840
  	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
b3b94faa5   David Teigland   [GFS2] The core o...
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
  	struct buffer_head *bh;
  	int error;
  
  	/* Dealloc on-disk leaves to FREEMETA state */
  	error = foreach_leaf(dip, leaf_dealloc, NULL);
  	if (error)
  		return error;
  
  	/* Make this a regular file in case we crash.
  	   (We don't want to free these blocks a second time.)  */
  
  	error = gfs2_trans_begin(sdp, RES_DINODE, 0);
  	if (error)
  		return error;
  
  	error = gfs2_meta_inode_buffer(dip, &bh);
  	if (!error) {
d4e9c4c3b   Steven Whitehouse   [GFS2] Add an add...
1858
  		gfs2_trans_add_bh(dip->i_gl, bh, 1);
568f4c965   Steven Whitehouse   [GFS2] 80 Column ...
1859
1860
  		((struct gfs2_dinode *)bh->b_data)->di_mode =
  						cpu_to_be32(S_IFREG);
b3b94faa5   David Teigland   [GFS2] The core o...
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
  		brelse(bh);
  	}
  
  	gfs2_trans_end(sdp);
  
  	return error;
  }
  
  /**
   * gfs2_diradd_alloc_required - find if adding entry will require an allocation
   * @ip: the file being written to
   * @filname: the filename that's going to be added
b3b94faa5   David Teigland   [GFS2] The core o...
1873
   *
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1874
   * Returns: 1 if alloc required, 0 if not, -ve on error
b3b94faa5   David Teigland   [GFS2] The core o...
1875
   */
4d8012b60   Steven Whitehouse   [GFS2] Fix bug wh...
1876
  int gfs2_diradd_alloc_required(struct inode *inode, const struct qstr *name)
b3b94faa5   David Teigland   [GFS2] The core o...
1877
  {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1878
1879
  	struct gfs2_dirent *dent;
  	struct buffer_head *bh;
b3b94faa5   David Teigland   [GFS2] The core o...
1880

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1881
  	dent = gfs2_dirent_search(inode, name, gfs2_dirent_find_space, &bh);
ed3865079   Steven Whitehouse   [GFS2] Finally ge...
1882
  	if (!dent) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1883
  		return 1;
ed3865079   Steven Whitehouse   [GFS2] Finally ge...
1884
  	}
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1885
1886
1887
1888
  	if (IS_ERR(dent))
  		return PTR_ERR(dent);
  	brelse(bh);
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1889
  }