Blame view

fs/gfs2/dir.c 47.3 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
   * 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
   *
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
39
   * dip->i_diskflags & GFS2_DIF_EXHASH is true
61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
   *
   * 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

b3b94faa5   David Teigland   [GFS2] The core o...
56
57
  #include <linux/slab.h>
  #include <linux/spinlock.h>
b3b94faa5   David Teigland   [GFS2] The core o...
58
59
  #include <linux/buffer_head.h>
  #include <linux/sort.h>
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
60
  #include <linux/gfs2_ondisk.h>
71b86f562   Steven Whitehouse   [GFS2] Further up...
61
  #include <linux/crc32.h>
fe1bdedc6   Steven Whitehouse   [GFS2] Use vmallo...
62
  #include <linux/vmalloc.h>
b3b94faa5   David Teigland   [GFS2] The core o...
63
64
  
  #include "gfs2.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
65
  #include "incore.h"
b3b94faa5   David Teigland   [GFS2] The core o...
66
67
68
  #include "dir.h"
  #include "glock.h"
  #include "inode.h"
b3b94faa5   David Teigland   [GFS2] The core o...
69
70
71
72
  #include "meta_io.h"
  #include "quota.h"
  #include "rgrp.h"
  #include "trans.h"
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
73
  #include "bmap.h"
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
74
  #include "util.h"
b3b94faa5   David Teigland   [GFS2] The core o...
75
76
77
  
  #define IS_LEAF     1 /* Hashed (leaf) directory */
  #define IS_DINODE   2 /* Linear (stuffed dinode block) directory */
dfe4d34b3   Bob Peterson   GFS2: Add readahe...
78
  #define MAX_RA_BLOCKS 32 /* max read-ahead blocks */
cd915493f   Steven Whitehouse   [GFS2] Change all...
79
80
  #define gfs2_disk_hash2offset(h) (((u64)(h)) >> 1)
  #define gfs2_dir_offset2hash(p) ((u32)(((u64)(p)) << 1))
b3b94faa5   David Teigland   [GFS2] The core o...
81

8d1235852   Steven Whitehouse   GFS2: Make . and ...
82
83
  struct qstr gfs2_qdot __read_mostly;
  struct qstr gfs2_qdotdot __read_mostly;
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
84
85
  typedef int (*gfs2_dscan_t)(const struct gfs2_dirent *dent,
  			    const struct qstr *name, void *opaque);
b3b94faa5   David Teigland   [GFS2] The core o...
86

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

61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
92
93
94
95
  	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...
96
97
98
  	*bhp = bh;
  	return 0;
  }
cd915493f   Steven Whitehouse   [GFS2] Change all...
99
  static int gfs2_dir_get_existing_buffer(struct gfs2_inode *ip, u64 block,
61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
100
101
102
103
  					struct buffer_head **bhp)
  {
  	struct buffer_head *bh;
  	int error;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
104

7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
105
  	error = gfs2_meta_read(ip->i_gl, block, DIO_WAIT, &bh);
61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
106
107
  	if (error)
  		return error;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
108
  	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) {
61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
109
110
111
112
113
114
  		brelse(bh);
  		return -EIO;
  	}
  	*bhp = bh;
  	return 0;
  }
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
115
116
117
  
  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...
118
119
120
121
122
123
124
125
126
  {
  	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...
127
  	memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size);
a2e0f7993   Steven Whitehouse   GFS2: Remove i_di...
128
129
  	if (ip->i_inode.i_size < offset + size)
  		i_size_write(&ip->i_inode, offset + size);
4bd91ba18   Steven Whitehouse   [GFS2] Add nanose...
130
  	ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
131
  	gfs2_dinode_out(ip, dibh->b_data);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  
  	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...
150
  			       u64 offset, unsigned int size)
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
151
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
152
  	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
153
  	struct buffer_head *dibh;
cd915493f   Steven Whitehouse   [GFS2] Change all...
154
155
  	u64 lblock, dblock;
  	u32 extlen = 0;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
156
157
158
  	unsigned int o;
  	int copied = 0;
  	int error = 0;
9b8c81d1d   Steven Whitehouse   [GFS2] Allow bmap...
159
  	int new = 0;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
160
161
162
163
164
165
  
  	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 ...
166
167
  		return gfs2_dir_write_stuffed(ip, buf, (unsigned int)offset,
  					      size);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
168
169
170
171
172
  
  	if (gfs2_assert_warn(sdp, gfs2_is_jdata(ip)))
  		return -EINVAL;
  
  	if (gfs2_is_stuffed(ip)) {
f25ef0c1b   Steven Whitehouse   [GFS2] Tidy gfs2_...
173
  		error = gfs2_unstuff_dinode(ip, NULL);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
174
  		if (error)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
175
  			return error;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
176
177
178
179
180
181
182
183
  	}
  
  	lblock = offset;
  	o = do_div(lblock, sdp->sd_jbsize) + sizeof(struct gfs2_meta_header);
  
  	while (copied < size) {
  		unsigned int amount;
  		struct buffer_head *bh;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
184
185
186
187
188
189
190
  
  		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...
191
  			error = gfs2_extent_map(&ip->i_inode, lblock, &new,
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
192
  						&dblock, &extlen);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
193
194
195
196
197
198
  			if (error)
  				goto fail;
  			error = -EIO;
  			if (gfs2_assert_withdraw(sdp, dblock))
  				goto fail;
  		}
61e085a88   Steven Whitehouse   [GFS2] Tidy up di...
199
200
201
202
  		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...
203
204
205
206
207
208
  		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...
209

899bb2645   Steven Whitehouse   [GFS2] Fix bug in...
210
  		buf += amount;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
211
212
213
214
215
216
217
218
219
220
221
222
  		copied += amount;
  		lblock++;
  		dblock++;
  		extlen--;
  
  		o = sizeof(struct gfs2_meta_header);
  	}
  
  out:
  	error = gfs2_meta_inode_buffer(ip, &dibh);
  	if (error)
  		return error;
a2e0f7993   Steven Whitehouse   GFS2: Remove i_di...
223
224
  	if (ip->i_inode.i_size < offset + copied)
  		i_size_write(&ip->i_inode, offset + copied);
4bd91ba18   Steven Whitehouse   [GFS2] Add nanose...
225
  	ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
226
227
  
  	gfs2_trans_add_bh(ip->i_gl, dibh, 1);
539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
228
  	gfs2_dinode_out(ip, dibh->b_data);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
229
230
231
232
233
234
235
236
  	brelse(dibh);
  
  	return copied;
  fail:
  	if (copied)
  		goto out;
  	return error;
  }
4c28d3380   Steven Whitehouse   GFS2: Clean up di...
237
238
  static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, __be64 *buf,
  				 unsigned int size)
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
239
240
241
242
243
244
  {
  	struct buffer_head *dibh;
  	int error;
  
  	error = gfs2_meta_inode_buffer(ip, &dibh);
  	if (!error) {
4c28d3380   Steven Whitehouse   GFS2: Clean up di...
245
  		memcpy(buf, dibh->b_data + sizeof(struct gfs2_dinode), size);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
246
247
248
249
250
251
252
253
254
255
256
  		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
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
257
258
259
260
   * @size: Amount of data to transfer
   *
   * Returns: The amount of data actually copied or the error
   */
4c28d3380   Steven Whitehouse   GFS2: Clean up di...
261
262
  static int gfs2_dir_read_data(struct gfs2_inode *ip, __be64 *buf,
  			      unsigned int size)
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
263
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
264
  	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
cd915493f   Steven Whitehouse   [GFS2] Change all...
265
266
  	u64 lblock, dblock;
  	u32 extlen = 0;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
267
268
269
  	unsigned int o;
  	int copied = 0;
  	int error = 0;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
270
271
  
  	if (gfs2_is_stuffed(ip))
4c28d3380   Steven Whitehouse   GFS2: Clean up di...
272
  		return gfs2_dir_read_stuffed(ip, buf, size);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
273
274
275
  
  	if (gfs2_assert_warn(sdp, gfs2_is_jdata(ip)))
  		return -EINVAL;
4c28d3380   Steven Whitehouse   GFS2: Clean up di...
276
  	lblock = 0;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
277
278
279
280
281
282
283
284
285
286
287
288
289
  	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...
290
  			error = gfs2_extent_map(&ip->i_inode, lblock, &new,
fd88de569   Steven Whitehouse   [GFS2] Readpages ...
291
  						&dblock, &extlen);
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
292
  			if (error || !dblock)
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
293
  				goto fail;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
294
  			BUG_ON(extlen < 1);
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
295
  			bh = gfs2_meta_ra(ip->i_gl, dblock, extlen);
b7d8ac3e1   Adrian Bunk   [GFS2] gfs2_dir_r...
296
  		} else {
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
297
  			error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, &bh);
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
298
299
  			if (error)
  				goto fail;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
300
301
302
303
304
305
306
307
  		}
  		error = gfs2_metatype_check(sdp, bh, GFS2_METATYPE_JD);
  		if (error) {
  			brelse(bh);
  			goto fail;
  		}
  		dblock++;
  		extlen--;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
308
309
  		memcpy(buf, bh->b_data + o, amount);
  		brelse(bh);
4c28d3380   Steven Whitehouse   GFS2: Clean up di...
310
  		buf += (amount/sizeof(__be64));
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
311
312
  		copied += amount;
  		lblock++;
e13940ba5   Steven Whitehouse   [GFS2] Make dir.c...
313
314
315
316
317
318
319
  		o = sizeof(struct gfs2_meta_header);
  	}
  
  	return copied;
  fail:
  	return (copied) ? copied : error;
  }
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
  /**
   * gfs2_dir_get_hash_table - Get pointer to the dir hash table
   * @ip: The inode in question
   *
   * Returns: The hash table or an error
   */
  
  static __be64 *gfs2_dir_get_hash_table(struct gfs2_inode *ip)
  {
  	struct inode *inode = &ip->i_inode;
  	int ret;
  	u32 hsize;
  	__be64 *hc;
  
  	BUG_ON(!(ip->i_diskflags & GFS2_DIF_EXHASH));
  
  	hc = ip->i_hash_cache;
  	if (hc)
  		return hc;
  
  	hsize = 1 << ip->i_depth;
  	hsize *= sizeof(__be64);
  	if (hsize != i_size_read(&ip->i_inode)) {
  		gfs2_consist_inode(ip);
  		return ERR_PTR(-EIO);
  	}
  
  	hc = kmalloc(hsize, GFP_NOFS);
  	ret = -ENOMEM;
  	if (hc == NULL)
  		return ERR_PTR(-ENOMEM);
4c28d3380   Steven Whitehouse   GFS2: Clean up di...
351
  	ret = gfs2_dir_read_data(ip, hc, hsize);
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
  	if (ret < 0) {
  		kfree(hc);
  		return ERR_PTR(ret);
  	}
  
  	spin_lock(&inode->i_lock);
  	if (ip->i_hash_cache)
  		kfree(hc);
  	else
  		ip->i_hash_cache = hc;
  	spin_unlock(&inode->i_lock);
  
  	return ip->i_hash_cache;
  }
  
  /**
   * gfs2_dir_hash_inval - Invalidate dir hash
   * @ip: The directory inode
   *
   * Must be called with an exclusive glock, or during glock invalidation.
   */
  void gfs2_dir_hash_inval(struct gfs2_inode *ip)
  {
  	__be64 *hc = ip->i_hash_cache;
  	ip->i_hash_cache = NULL;
  	kfree(hc);
  }
5e7d65cd9   Steven Whitehouse   [GFS2] Make senti...
379
380
381
382
  static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent)
  {
  	return dent->de_inum.no_addr == 0 || dent->de_inum.no_formal_ino == 0;
  }
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
383
384
385
  static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent,
  				     const struct qstr *name, int ret)
  {
5e7d65cd9   Steven Whitehouse   [GFS2] Make senti...
386
  	if (!gfs2_dirent_sentinel(dent) &&
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
387
388
  	    be32_to_cpu(dent->de_hash) == name->hash &&
  	    be16_to_cpu(dent->de_name_len) == name->len &&
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
389
  	    memcmp(dent+1, name->name, name->len) == 0)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
390
391
392
393
394
  		return ret;
  	return 0;
  }
  
  static int gfs2_dirent_find(const struct gfs2_dirent *dent,
71b86f562   Steven Whitehouse   [GFS2] Further up...
395
396
  			    const struct qstr *name,
  			    void *opaque)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
397
398
399
400
401
  {
  	return __gfs2_dirent_find(dent, name, 1);
  }
  
  static int gfs2_dirent_prev(const struct gfs2_dirent *dent,
71b86f562   Steven Whitehouse   [GFS2] Further up...
402
403
  			    const struct qstr *name,
  			    void *opaque)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
404
405
406
407
408
409
410
  {
  	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...
411
   */
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
412
  static int gfs2_dirent_last(const struct gfs2_dirent *dent,
71b86f562   Steven Whitehouse   [GFS2] Further up...
413
414
  			    const struct qstr *name,
  			    void *opaque)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
415
416
417
418
419
420
421
  {
  	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...
422

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
423
  static int gfs2_dirent_find_space(const struct gfs2_dirent *dent,
71b86f562   Steven Whitehouse   [GFS2] Further up...
424
425
  				  const struct qstr *name,
  				  void *opaque)
b3b94faa5   David Teigland   [GFS2] The core o...
426
  {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
427
428
429
  	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);
5e7d65cd9   Steven Whitehouse   [GFS2] Make senti...
430
  	if (gfs2_dirent_sentinel(dent))
728a756b8   Bob Peterson   GFS2: rename caus...
431
  		actual = 0;
c53921248   Jan Engelhardt   [GFS2] More style...
432
  	if (totlen - actual >= required)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
433
434
435
  		return 1;
  	return 0;
  }
71b86f562   Steven Whitehouse   [GFS2] Further up...
436
437
438
439
440
441
442
443
444
445
  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;
5e7d65cd9   Steven Whitehouse   [GFS2] Make senti...
446
  	if (!gfs2_dirent_sentinel(dent)) {
71b86f562   Steven Whitehouse   [GFS2] Further up...
447
448
449
450
  		g->pdent[g->offset++] = dent;
  	}
  	return 0;
  }
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
  /*
   * 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";
5e7d65cd9   Steven Whitehouse   [GFS2] Make senti...
473
  	if (unlikely(!first && gfs2_dirent_sentinel(dent)))
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
474
475
  		goto error;
  	msg = "name length is greater than space in dirent";
5e7d65cd9   Steven Whitehouse   [GFS2] Make senti...
476
  	if (!gfs2_dirent_sentinel(dent) &&
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
477
478
479
480
481
482
483
484
485
  	    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...
486
  }
71b86f562   Steven Whitehouse   [GFS2] Further up...
487
  static int gfs2_dirent_offset(const void *buf)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
488
  {
71b86f562   Steven Whitehouse   [GFS2] Further up...
489
490
  	const struct gfs2_meta_header *h = buf;
  	int offset;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
491
492
  
  	BUG_ON(buf == NULL);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
493

e3167ded1   Steven Whitehouse   [GFS] Fix bug in ...
494
  	switch(be32_to_cpu(h->mh_type)) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
495
496
497
498
499
500
501
502
503
  	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...
504
505
506
507
  	return offset;
  wrong_type:
  	printk(KERN_WARNING "gfs2_scan_dirent: wrong block type %u
  ",
e3167ded1   Steven Whitehouse   [GFS] Fix bug in ...
508
  	       be32_to_cpu(h->mh_type));
71b86f562   Steven Whitehouse   [GFS2] Further up...
509
510
  	return -1;
  }
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
511
  static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
71b86f562   Steven Whitehouse   [GFS2] Further up...
512
513
514
515
516
517
518
519
  					    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...
520

71b86f562   Steven Whitehouse   [GFS2] Further up...
521
522
523
524
525
  	ret = gfs2_dirent_offset(buf);
  	if (ret < 0)
  		goto consist_inode;
  
  	offset = ret;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
526
  	prev = NULL;
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
527
  	dent = buf + offset;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
528
529
530
531
  	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...
532
  		ret = scan(dent, name, opaque);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
533
534
535
536
537
538
  		if (ret)
  			break;
  		offset += size;
  		if (offset == len)
  			break;
  		prev = dent;
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
539
  		dent = buf + offset;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
  		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...
556
  consist_inode:
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
557
  	gfs2_consist_inode(GFS2_I(inode));
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
558
559
  	return ERR_PTR(-EIO);
  }
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
  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...
577
578
579
580
581
582
583
584
585
586
587
588
  /**
   * 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 ...
589
590
591
  	struct gfs2_dirent *cur = *dent, *tmp;
  	char *bh_end = bh->b_data + bh->b_size;
  	int ret;
b3b94faa5   David Teigland   [GFS2] The core o...
592

2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
593
594
595
  	ret = dirent_check_reclen(dip, cur, bh_end);
  	if (ret < 0)
  		return ret;
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
596

2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
597
598
599
600
  	tmp = (void *)cur + ret;
  	ret = dirent_check_reclen(dip, tmp, bh_end);
  	if (ret == -EIO)
  		return ret;
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
601

b3b94faa5   David Teigland   [GFS2] The core o...
602
          /* Only the first dent could ever have de_inum.no_addr == 0 */
5e7d65cd9   Steven Whitehouse   [GFS2] Make senti...
603
  	if (gfs2_dirent_sentinel(tmp)) {
b3b94faa5   David Teigland   [GFS2] The core o...
604
605
606
607
608
  		gfs2_consist_inode(dip);
  		return -EIO;
  	}
  
  	*dent = tmp;
b3b94faa5   David Teigland   [GFS2] The core o...
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
  	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...
624
  	u16 cur_rec_len, prev_rec_len;
b3b94faa5   David Teigland   [GFS2] The core o...
625

5e7d65cd9   Steven Whitehouse   [GFS2] Make senti...
626
  	if (gfs2_dirent_sentinel(cur)) {
b3b94faa5   David Teigland   [GFS2] The core o...
627
628
629
  		gfs2_consist_inode(dip);
  		return;
  	}
d4e9c4c3b   Steven Whitehouse   [GFS2] Add an add...
630
  	gfs2_trans_add_bh(dip->i_gl, bh, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
631
632
633
634
635
636
  
  	/* 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) {
5e7d65cd9   Steven Whitehouse   [GFS2] Make senti...
637
638
  		cur->de_inum.no_addr = 0;
  		cur->de_inum.no_formal_ino = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
639
640
641
642
  		return;
  	}
  
  	/*  Combine this dentry with the previous one.  */
fc69d0d33   Steven Whitehouse   [GFS2] Change ond...
643
644
  	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...
645
646
647
648
649
650
651
  
  	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...
652
  	prev->de_rec_len = cpu_to_be16(prev_rec_len);
b3b94faa5   David Teigland   [GFS2] The core o...
653
  }
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
654
655
656
  /*
   * Takes a dent from which to grab space as an argument. Returns the
   * newly created dent.
b3b94faa5   David Teigland   [GFS2] The core o...
657
   */
08bc2dbc7   Adrian Bunk   [GFS2] [-mm patch...
658
659
660
661
  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...
662
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
663
  	struct gfs2_inode *ip = GFS2_I(inode);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
664
665
  	struct gfs2_dirent *ndent;
  	unsigned offset = 0, totlen;
5e7d65cd9   Steven Whitehouse   [GFS2] Make senti...
666
  	if (!gfs2_dirent_sentinel(dent))
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
667
668
669
670
671
672
673
674
  		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...
675
  }
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
676
677
678
  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...
679
680
  {
  	struct gfs2_dirent *dent;
907b9bceb   Steven Whitehouse   [GFS2/DLM] Fix tr...
681
  	dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size,
71b86f562   Steven Whitehouse   [GFS2] Further up...
682
  				gfs2_dirent_find_space, name, NULL);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
683
684
685
  	if (!dent || IS_ERR(dent))
  		return dent;
  	return gfs2_init_dirent(inode, dent, name, bh);
b3b94faa5   David Teigland   [GFS2] The core o...
686
  }
cd915493f   Steven Whitehouse   [GFS2] Change all...
687
  static int get_leaf(struct gfs2_inode *dip, u64 leaf_no,
b3b94faa5   David Teigland   [GFS2] The core o...
688
689
690
  		    struct buffer_head **bhp)
  {
  	int error;
7276b3b0c   Steven Whitehouse   [GFS2] Tidy up me...
691
  	error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_WAIT, bhp);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
692
693
694
  	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...
695
  		error = -EIO;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
696
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
697
698
699
700
701
702
703
704
705
706
707
708
  
  	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...
709
710
  static int get_leaf_nr(struct gfs2_inode *dip, u32 index,
  		       u64 *leaf_out)
b3b94faa5   David Teigland   [GFS2] The core o...
711
  {
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
712
  	__be64 *hash;
b3b94faa5   David Teigland   [GFS2] The core o...
713

17d539f04   Steven Whitehouse   GFS2: Cache dir h...
714
715
716
717
  	hash = gfs2_dir_get_hash_table(dip);
  	if (IS_ERR(hash))
  		return PTR_ERR(hash);
  	*leaf_out = be64_to_cpu(*(hash + index));
b3b94faa5   David Teigland   [GFS2] The core o...
718
719
  	return 0;
  }
cd915493f   Steven Whitehouse   [GFS2] Change all...
720
  static int get_first_leaf(struct gfs2_inode *dip, u32 index,
b3b94faa5   David Teigland   [GFS2] The core o...
721
722
  			  struct buffer_head **bh_out)
  {
cd915493f   Steven Whitehouse   [GFS2] Change all...
723
  	u64 leaf_no;
b3b94faa5   David Teigland   [GFS2] The core o...
724
725
726
727
728
729
730
731
  	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...
732
733
734
735
  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...
736
  {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
737
738
  	struct buffer_head *bh;
  	struct gfs2_dirent *dent;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
739
  	struct gfs2_inode *ip = GFS2_I(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
740
  	int error;
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
741
  	if (ip->i_diskflags & GFS2_DIF_EXHASH) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
742
  		struct gfs2_leaf *leaf;
9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
743
  		unsigned hsize = 1 << ip->i_depth;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
744
745
  		unsigned index;
  		u64 ln;
a2e0f7993   Steven Whitehouse   GFS2: Remove i_di...
746
  		if (hsize * sizeof(u64) != i_size_read(inode)) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
747
748
749
  			gfs2_consist_inode(ip);
  			return ERR_PTR(-EIO);
  		}
907b9bceb   Steven Whitehouse   [GFS2/DLM] Fix tr...
750

9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
751
  		index = name->hash >> (32 - ip->i_depth);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
752
753
754
755
756
  		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...
757
  						scan, name, NULL);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
758
759
760
761
  			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...
762
  			brelse(bh);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
763
764
  			if (!ln)
  				break;
907b9bceb   Steven Whitehouse   [GFS2/DLM] Fix tr...
765

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

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

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

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
773
774
775
  	error = gfs2_meta_inode_buffer(ip, &bh);
  	if (error)
  		return ERR_PTR(error);
71b86f562   Steven Whitehouse   [GFS2] Further up...
776
  	dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, scan, name, NULL);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
777
  got_dent:
f4154ea03   Steven Whitehouse   [GFS2] Update jou...
778
  	if (unlikely(dent == NULL || IS_ERR(dent))) {
ed3865079   Steven Whitehouse   [GFS2] Finally ge...
779
780
781
  		brelse(bh);
  		bh = NULL;
  	}
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
782
783
784
  	*pbh = bh;
  	return dent;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
785

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
786
787
  static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, u16 depth)
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
788
  	struct gfs2_inode *ip = GFS2_I(inode);
b45e41d7d   Steven Whitehouse   [GFS2] Add extent...
789
  	unsigned int n = 1;
090109783   Steven Whitehouse   GFS2: Improve res...
790
791
792
  	u64 bn;
  	int error;
  	struct buffer_head *bh;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
793
794
  	struct gfs2_leaf *leaf;
  	struct gfs2_dirent *dent;
71b86f562   Steven Whitehouse   [GFS2] Further up...
795
  	struct qstr name = { .name = "", .len = 0, .hash = 0 };
090109783   Steven Whitehouse   GFS2: Improve res...
796

6e87ed0fc   Bob Peterson   GFS2: move toward...
797
  	error = gfs2_alloc_blocks(ip, &bn, &n, 0, NULL);
090109783   Steven Whitehouse   GFS2: Improve res...
798
799
800
  	if (error)
  		return NULL;
  	bh = gfs2_meta_new(ip->i_gl, bn);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
801
802
  	if (!bh)
  		return NULL;
090109783   Steven Whitehouse   GFS2: Improve res...
803

5731be53e   Steven Whitehouse   [GFS2] Update gfs...
804
  	gfs2_trans_add_unrevoke(GFS2_SB(inode), bn, 1);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
805
806
807
808
  	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 ...
809
  	leaf->lf_entries = 0;
a2d7d021d   Al Viro   [GFS2] gfs2 endia...
810
  	leaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE);
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
811
  	leaf->lf_next = 0;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
812
813
  	memset(leaf->lf_reserved, 0, sizeof(leaf->lf_reserved));
  	dent = (struct gfs2_dirent *)(leaf+1);
71b86f562   Steven Whitehouse   [GFS2] Further up...
814
  	gfs2_qstr2dirent(&name, bh->b_size - sizeof(struct gfs2_leaf), dent);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
815
816
  	*pbh = bh;
  	return leaf;
b3b94faa5   David Teigland   [GFS2] The core o...
817
818
819
820
821
822
823
824
  }
  
  /**
   * 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...
825
  static int dir_make_exhash(struct inode *inode)
b3b94faa5   David Teigland   [GFS2] The core o...
826
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
827
828
  	struct gfs2_inode *dip = GFS2_I(inode);
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
829
  	struct gfs2_dirent *dent;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
830
  	struct qstr args;
b3b94faa5   David Teigland   [GFS2] The core o...
831
832
833
  	struct buffer_head *bh, *dibh;
  	struct gfs2_leaf *leaf;
  	int y;
cd915493f   Steven Whitehouse   [GFS2] Change all...
834
  	u32 x;
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
835
836
  	__be64 *lp;
  	u64 bn;
b3b94faa5   David Teigland   [GFS2] The core o...
837
838
839
840
841
  	int error;
  
  	error = gfs2_meta_inode_buffer(dip, &dibh);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
842
  	/*  Turn over a new leaf  */
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
843
844
845
846
  	leaf = new_leaf(inode, &bh, 0);
  	if (!leaf)
  		return -ENOSPC;
  	bn = bh->b_blocknr;
b3b94faa5   David Teigland   [GFS2] The core o...
847

ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
848
849
  	gfs2_assert(sdp, dip->i_entries < (1 << 16));
  	leaf->lf_entries = cpu_to_be16(dip->i_entries);
b3b94faa5   David Teigland   [GFS2] The core o...
850
851
852
853
854
855
856
857
858
  
  	/*  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...
859
860
861
  	args.len = bh->b_size - sizeof(struct gfs2_dinode) +
  		   sizeof(struct gfs2_leaf);
  	args.name = bh->b_data;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
862
  	dent = gfs2_dirent_scan(&dip->i_inode, bh->b_data, bh->b_size,
71b86f562   Steven Whitehouse   [GFS2] Further up...
863
  				gfs2_dirent_last, &args, NULL);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
864
865
866
867
868
869
870
871
872
  	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...
873
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
874
875
876
  
  	/*  Adjust the last dirent's record length
  	   (Remember that dent still points to the last entry.)  */
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
877
  	dent->de_rec_len = cpu_to_be16(be16_to_cpu(dent->de_rec_len) +
b3b94faa5   David Teigland   [GFS2] The core o...
878
  		sizeof(struct gfs2_dinode) -
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
879
  		sizeof(struct gfs2_leaf));
b3b94faa5   David Teigland   [GFS2] The core o...
880
881
882
883
884
  
  	brelse(bh);
  
  	/*  We're done with the new leaf block, now setup the new
  	    hash table.  */
d4e9c4c3b   Steven Whitehouse   [GFS2] Add an add...
885
  	gfs2_trans_add_bh(dip->i_gl, dibh, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
886
  	gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
887
  	lp = (__be64 *)(dibh->b_data + sizeof(struct gfs2_dinode));
b3b94faa5   David Teigland   [GFS2] The core o...
888
889
890
  
  	for (x = sdp->sd_hash_ptrs; x--; lp++)
  		*lp = cpu_to_be64(bn);
a2e0f7993   Steven Whitehouse   GFS2: Remove i_di...
891
  	i_size_write(inode, sdp->sd_sb.sb_bsize / 2);
77658aad2   Steven Whitehouse   [GFS2] Eliminate ...
892
  	gfs2_add_inode_blocks(&dip->i_inode, 1);
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
893
  	dip->i_diskflags |= GFS2_DIF_EXHASH;
b3b94faa5   David Teigland   [GFS2] The core o...
894
895
  
  	for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ;
9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
896
  	dip->i_depth = y;
b3b94faa5   David Teigland   [GFS2] The core o...
897

539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
898
  	gfs2_dinode_out(dip, dibh->b_data);
b3b94faa5   David Teigland   [GFS2] The core o...
899
900
901
902
903
904
905
906
907
908
909
910
911
912
  
  	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...
913
  static int dir_split_leaf(struct inode *inode, const struct qstr *name)
b3b94faa5   David Teigland   [GFS2] The core o...
914
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
915
  	struct gfs2_inode *dip = GFS2_I(inode);
b3b94faa5   David Teigland   [GFS2] The core o...
916
917
  	struct buffer_head *nbh, *obh, *dibh;
  	struct gfs2_leaf *nleaf, *oleaf;
4da3c6463   Steven Whitehouse   [GFS2] Fix a coup...
918
  	struct gfs2_dirent *dent = NULL, *prev = NULL, *next = NULL, *new;
cd915493f   Steven Whitehouse   [GFS2] Change all...
919
  	u32 start, len, half_len, divider;
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
920
921
  	u64 bn, leaf_no;
  	__be64 *lp;
cd915493f   Steven Whitehouse   [GFS2] Change all...
922
  	u32 index;
b3b94faa5   David Teigland   [GFS2] The core o...
923
924
  	int x, moved = 0;
  	int error;
9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
925
  	index = name->hash >> (32 - dip->i_depth);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
926
927
928
  	error = get_leaf_nr(dip, index, &leaf_no);
  	if (error)
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
929
930
  
  	/*  Get the old leaf block  */
b3b94faa5   David Teigland   [GFS2] The core o...
931
932
  	error = get_leaf(dip, leaf_no, &obh);
  	if (error)
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
933
  		return error;
b3b94faa5   David Teigland   [GFS2] The core o...
934

b3b94faa5   David Teigland   [GFS2] The core o...
935
  	oleaf = (struct gfs2_leaf *)obh->b_data;
9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
936
  	if (dip->i_depth == be16_to_cpu(oleaf->lf_depth)) {
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
937
938
939
940
941
  		brelse(obh);
  		return 1; /* can't split */
  	}
  
  	gfs2_trans_add_bh(dip->i_gl, obh, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
942

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
943
944
945
946
947
948
  	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...
949

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
950
  	/*  Compute the start and len of leaf pointers in the hash table.  */
9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
951
  	len = 1 << (dip->i_depth - be16_to_cpu(oleaf->lf_depth));
b3b94faa5   David Teigland   [GFS2] The core o...
952
953
  	half_len = len >> 1;
  	if (!half_len) {
9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
954
955
  		printk(KERN_WARNING "i_depth %u lf_depth %u index %u
  ", dip->i_depth, be16_to_cpu(oleaf->lf_depth), index);
b3b94faa5   David Teigland   [GFS2] The core o...
956
957
958
959
960
961
962
963
964
965
  		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. */
4244b52e1   David Rientjes   GFS2: remove depe...
966
967
968
969
970
  	lp = kmalloc(half_len * sizeof(__be64), GFP_NOFS);
  	if (!lp) {
  		error = -ENOMEM;
  		goto fail_brelse;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
971
  	/*  Change the pointers  */
b3b94faa5   David Teigland   [GFS2] The core o...
972
973
  	for (x = 0; x < half_len; x++)
  		lp[x] = cpu_to_be64(bn);
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
974
  	gfs2_dir_hash_inval(dip);
cd915493f   Steven Whitehouse   [GFS2] Change all...
975
976
977
  	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...
978
979
980
981
982
983
984
985
  		if (error >= 0)
  			error = -EIO;
  		goto fail_lpfree;
  	}
  
  	kfree(lp);
  
  	/*  Compute the divider  */
9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
986
  	divider = (start + half_len) << (32 - dip->i_depth);
b3b94faa5   David Teigland   [GFS2] The core o...
987
988
  
  	/*  Copy the entries  */
1579343a7   Steven Whitehouse   GFS2: Remove dire...
989
  	dent = (struct gfs2_dirent *)(obh->b_data + sizeof(struct gfs2_leaf));
b3b94faa5   David Teigland   [GFS2] The core o...
990
991
992
993
994
  
  	do {
  		next = dent;
  		if (dirent_next(dip, obh, &next))
  			next = NULL;
5e7d65cd9   Steven Whitehouse   [GFS2] Make senti...
995
  		if (!gfs2_dirent_sentinel(dent) &&
b3b94faa5   David Teigland   [GFS2] The core o...
996
  		    be32_to_cpu(dent->de_hash) < divider) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
997
998
999
1000
  			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...
1001
  			new = gfs2_dirent_alloc(inode, nbh, &str);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1002
1003
1004
1005
  			if (IS_ERR(new)) {
  				error = PTR_ERR(new);
  				break;
  			}
b3b94faa5   David Teigland   [GFS2] The core o...
1006
1007
  
  			new->de_inum = dent->de_inum; /* No endian worries */
b3b94faa5   David Teigland   [GFS2] The core o...
1008
  			new->de_type = dent->de_type; /* No endian worries */
bb16b342b   Marcin Slusarz   [GFS2] be*_add_cp...
1009
  			be16_add_cpu(&nleaf->lf_entries, 1);
b3b94faa5   David Teigland   [GFS2] The core o...
1010
1011
1012
1013
1014
  
  			dirent_del(dip, obh, prev, dent);
  
  			if (!oleaf->lf_entries)
  				gfs2_consist_inode(dip);
bb16b342b   Marcin Slusarz   [GFS2] be*_add_cp...
1015
  			be16_add_cpu(&oleaf->lf_entries, -1);
b3b94faa5   David Teigland   [GFS2] The core o...
1016
1017
1018
1019
1020
  
  			if (!prev)
  				prev = dent;
  
  			moved = 1;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1021
  		} else {
b3b94faa5   David Teigland   [GFS2] The core o...
1022
  			prev = dent;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1023
  		}
b3b94faa5   David Teigland   [GFS2] The core o...
1024
  		dent = next;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1025
  	} while (dent);
b3b94faa5   David Teigland   [GFS2] The core o...
1026

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1027
  	oleaf->lf_depth = nleaf->lf_depth;
b3b94faa5   David Teigland   [GFS2] The core o...
1028
1029
  
  	error = gfs2_meta_inode_buffer(dip, &dibh);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1030
  	if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) {
382e6e256   Steven Whitehouse   [GFS2] Add a miss...
1031
  		gfs2_trans_add_bh(dip->i_gl, dibh, 1);
77658aad2   Steven Whitehouse   [GFS2] Eliminate ...
1032
  		gfs2_add_inode_blocks(&dip->i_inode, 1);
539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
1033
  		gfs2_dinode_out(dip, dibh->b_data);
b3b94faa5   David Teigland   [GFS2] The core o...
1034
1035
1036
1037
1038
1039
1040
  		brelse(dibh);
  	}
  
  	brelse(obh);
  	brelse(nbh);
  
  	return error;
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
1041
  fail_lpfree:
b3b94faa5   David Teigland   [GFS2] The core o...
1042
  	kfree(lp);
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
1043
  fail_brelse:
b3b94faa5   David Teigland   [GFS2] The core o...
1044
  	brelse(obh);
b3b94faa5   David Teigland   [GFS2] The core o...
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
  	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)
  {
b3b94faa5   David Teigland   [GFS2] The core o...
1058
  	struct buffer_head *dibh;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1059
  	u32 hsize;
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1060
1061
1062
  	u32 hsize_bytes;
  	__be64 *hc;
  	__be64 *hc2, *h;
b3b94faa5   David Teigland   [GFS2] The core o...
1063
1064
  	int x;
  	int error = 0;
9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
1065
  	hsize = 1 << dip->i_depth;
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1066
  	hsize_bytes = hsize * sizeof(__be64);
b3b94faa5   David Teigland   [GFS2] The core o...
1067

17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1068
1069
1070
  	hc = gfs2_dir_get_hash_table(dip);
  	if (IS_ERR(hc))
  		return PTR_ERR(hc);
b3b94faa5   David Teigland   [GFS2] The core o...
1071

17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1072
1073
  	h = hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS);
  	if (!hc2)
4244b52e1   David Rientjes   GFS2: remove depe...
1074
  		return -ENOMEM;
b3b94faa5   David Teigland   [GFS2] The core o...
1075

17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1076
1077
1078
  	error = gfs2_meta_inode_buffer(dip, &dibh);
  	if (error)
  		goto out_kfree;
b3b94faa5   David Teigland   [GFS2] The core o...
1079

17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1080
1081
1082
1083
  	for (x = 0; x < hsize; x++) {
  		*h++ = *hc;
  		*h++ = *hc;
  		hc++;
b3b94faa5   David Teigland   [GFS2] The core o...
1084
  	}
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1085
1086
1087
  	error = gfs2_dir_write_data(dip, (char *)hc2, 0, hsize_bytes * 2);
  	if (error != (hsize_bytes * 2))
  		goto fail;
b3b94faa5   David Teigland   [GFS2] The core o...
1088

17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1089
1090
1091
1092
1093
1094
  	gfs2_dir_hash_inval(dip);
  	dip->i_hash_cache = hc2;
  	dip->i_depth++;
  	gfs2_dinode_out(dip, dibh->b_data);
  	brelse(dibh);
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1095

a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1096
  fail:
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1097
1098
1099
1100
1101
1102
1103
  	/* Replace original hash table & size */
  	gfs2_dir_write_data(dip, (char *)hc, 0, hsize_bytes);
  	i_size_write(&dip->i_inode, hsize_bytes);
  	gfs2_dinode_out(dip, dibh->b_data);
  	brelse(dibh);
  out_kfree:
  	kfree(hc2);
b3b94faa5   David Teigland   [GFS2] The core o...
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
  	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 ...
1120
  	const struct gfs2_dirent *dent_a, *dent_b;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1121
  	u32 hash_a, hash_b;
b3b94faa5   David Teigland   [GFS2] The core o...
1122
  	int ret = 0;
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
1123
  	dent_a = *(const struct gfs2_dirent **)a;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1124
  	hash_a = be32_to_cpu(dent_a->de_hash);
b3b94faa5   David Teigland   [GFS2] The core o...
1125

2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
1126
  	dent_b = *(const struct gfs2_dirent **)b;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1127
  	hash_b = be32_to_cpu(dent_b->de_hash);
b3b94faa5   David Teigland   [GFS2] The core o...
1128
1129
1130
1131
1132
1133
  
  	if (hash_a > hash_b)
  		ret = 1;
  	else if (hash_a < hash_b)
  		ret = -1;
  	else {
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
1134
1135
  		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...
1136
1137
1138
1139
1140
1141
  
  		if (len_a > len_b)
  			ret = 1;
  		else if (len_a < len_b)
  			ret = -1;
  		else
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
1142
  			ret = memcmp(dent_a + 1, dent_b + 1, len_a);
b3b94faa5   David Teigland   [GFS2] The core o...
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
  	}
  
  	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...
1165
  static int do_filldir_main(struct gfs2_inode *dip, u64 *offset,
3699e3a44   Steven Whitehouse   [GFS2] Clean up/s...
1166
  			   void *opaque, filldir_t filldir,
cd915493f   Steven Whitehouse   [GFS2] Change all...
1167
  			   const struct gfs2_dirent **darr, u32 entries,
b3b94faa5   David Teigland   [GFS2] The core o...
1168
1169
  			   int *copied)
  {
71b86f562   Steven Whitehouse   [GFS2] Further up...
1170
  	const struct gfs2_dirent *dent, *dent_next;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1171
  	u64 off, off_next;
b3b94faa5   David Teigland   [GFS2] The core o...
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
1198
1199
1200
1201
1202
1203
1204
1205
  	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;
  		}
2bdbc5d73   Steven Whitehouse   [GFS2] Directory ...
1206
  		error = filldir(opaque, (const char *)(dent + 1),
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
1207
  				be16_to_cpu(dent->de_name_len),
3699e3a44   Steven Whitehouse   [GFS2] Clean up/s...
1208
  				off, be64_to_cpu(dent->de_inum.no_addr),
4dd651adb   Steven Whitehouse   [GFS2] Fix the bu...
1209
  				be16_to_cpu(dent->de_type));
b3b94faa5   David Teigland   [GFS2] The core o...
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
  		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;
  }
d2a97a4e9   Steven Whitehouse   GFS2: Use kmalloc...
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
  static void *gfs2_alloc_sort_buffer(unsigned size)
  {
  	void *ptr = NULL;
  
  	if (size < KMALLOC_MAX_SIZE)
  		ptr = kmalloc(size, GFP_NOFS | __GFP_NOWARN);
  	if (!ptr)
  		ptr = __vmalloc(size, GFP_NOFS, PAGE_KERNEL);
  	return ptr;
  }
  
  static void gfs2_free_sort_buffer(void *ptr)
  {
  	if (is_vmalloc_addr(ptr))
  		vfree(ptr);
  	else
  		kfree(ptr);
  }
71b86f562   Steven Whitehouse   [GFS2] Further up...
1242
  static int gfs2_dir_read_leaf(struct inode *inode, u64 *offset, void *opaque,
3699e3a44   Steven Whitehouse   [GFS2] Clean up/s...
1243
1244
  			      filldir_t filldir, int *copied, unsigned *depth,
  			      u64 leaf_no)
b3b94faa5   David Teigland   [GFS2] The core o...
1245
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1246
  	struct gfs2_inode *ip = GFS2_I(inode);
bdd19a22f   Steven Whitehouse   [GFS2] Patch to d...
1247
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1248
1249
  	struct buffer_head *bh;
  	struct gfs2_leaf *lf;
bdd19a22f   Steven Whitehouse   [GFS2] Patch to d...
1250
  	unsigned entries = 0, entries2 = 0;
71b86f562   Steven Whitehouse   [GFS2] Further up...
1251
1252
1253
1254
1255
1256
1257
  	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...
1258

b3b94faa5   David Teigland   [GFS2] The core o...
1259
  	do {
71b86f562   Steven Whitehouse   [GFS2] Further up...
1260
  		error = get_leaf(ip, lfn, &bh);
b3b94faa5   David Teigland   [GFS2] The core o...
1261
  		if (error)
71b86f562   Steven Whitehouse   [GFS2] Further up...
1262
1263
1264
1265
1266
1267
1268
1269
1270
  			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...
1271
1272
1273
  
  	if (!entries)
  		return 0;
71b86f562   Steven Whitehouse   [GFS2] Further up...
1274
  	error = -ENOMEM;
bdd19a22f   Steven Whitehouse   [GFS2] Patch to d...
1275
1276
1277
1278
1279
1280
  	/*
  	 * The extra 99 entries are not normally used, but are a buffer
  	 * zone in case the number of entries in the leaf is corrupt.
  	 * 99 is the maximum number of entries that can fit in a single
  	 * leaf block.
  	 */
d2a97a4e9   Steven Whitehouse   GFS2: Use kmalloc...
1281
  	larr = gfs2_alloc_sort_buffer((leaves + entries + 99) * sizeof(void *));
71b86f562   Steven Whitehouse   [GFS2] Further up...
1282
1283
1284
1285
1286
1287
  	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...
1288

71b86f562   Steven Whitehouse   [GFS2] Further up...
1289
1290
  	do {
  		error = get_leaf(ip, lfn, &bh);
b3b94faa5   David Teigland   [GFS2] The core o...
1291
  		if (error)
d2a97a4e9   Steven Whitehouse   GFS2: Use kmalloc...
1292
  			goto out_free;
71b86f562   Steven Whitehouse   [GFS2] Further up...
1293
1294
1295
  		lf = (struct gfs2_leaf *)bh->b_data;
  		lfn = be64_to_cpu(lf->lf_next);
  		if (lf->lf_entries) {
bdd19a22f   Steven Whitehouse   [GFS2] Patch to d...
1296
  			entries2 += be16_to_cpu(lf->lf_entries);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1297
1298
1299
  			dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size,
  						gfs2_dirent_gather, NULL, &g);
  			error = PTR_ERR(dent);
bdd19a22f   Steven Whitehouse   [GFS2] Patch to d...
1300
  			if (IS_ERR(dent))
d2a97a4e9   Steven Whitehouse   GFS2: Use kmalloc...
1301
  				goto out_free;
bdd19a22f   Steven Whitehouse   [GFS2] Patch to d...
1302
  			if (entries2 != g.offset) {
f391a4ead   akpm@linux-foundation.org   [GFS2] printk war...
1303
1304
1305
1306
1307
1308
  				fs_warn(sdp, "Number of entries corrupt in dir "
  						"leaf %llu, entries2 (%u) != "
  						"g.offset (%u)
  ",
  					(unsigned long long)bh->b_blocknr,
  					entries2, g.offset);
bdd19a22f   Steven Whitehouse   [GFS2] Patch to d...
1309
1310
  					
  				error = -EIO;
d2a97a4e9   Steven Whitehouse   GFS2: Use kmalloc...
1311
  				goto out_free;
71b86f562   Steven Whitehouse   [GFS2] Further up...
1312
1313
1314
  			}
  			error = 0;
  			larr[leaf++] = bh;
b3b94faa5   David Teigland   [GFS2] The core o...
1315
  		} else {
71b86f562   Steven Whitehouse   [GFS2] Further up...
1316
  			brelse(bh);
b3b94faa5   David Teigland   [GFS2] The core o...
1317
  		}
71b86f562   Steven Whitehouse   [GFS2] Further up...
1318
  	} while(lfn);
b3b94faa5   David Teigland   [GFS2] The core o...
1319

bdd19a22f   Steven Whitehouse   [GFS2] Patch to d...
1320
  	BUG_ON(entries2 != entries);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1321
  	error = do_filldir_main(ip, offset, opaque, filldir, darr,
b3b94faa5   David Teigland   [GFS2] The core o...
1322
  				entries, copied);
d2a97a4e9   Steven Whitehouse   GFS2: Use kmalloc...
1323
  out_free:
71b86f562   Steven Whitehouse   [GFS2] Further up...
1324
1325
  	for(i = 0; i < leaf; i++)
  		brelse(larr[i]);
d2a97a4e9   Steven Whitehouse   GFS2: Use kmalloc...
1326
  	gfs2_free_sort_buffer(larr);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1327
  out:
b3b94faa5   David Teigland   [GFS2] The core o...
1328
1329
  	return error;
  }
79c4c379c   Steven Whitehouse   GFS2: f_ra is alw...
1330
1331
  /**
   * gfs2_dir_readahead - Issue read-ahead requests for leaf blocks.
dfe4d34b3   Bob Peterson   GFS2: Add readahe...
1332
1333
1334
1335
   *
   * Note: we can't calculate each index like dir_e_read can because we don't
   * have the leaf, and therefore we don't have the depth, and therefore we
   * don't have the length. So we have to just read enough ahead to make up
79c4c379c   Steven Whitehouse   GFS2: f_ra is alw...
1336
1337
   * for the loss of information.
   */
dfe4d34b3   Bob Peterson   GFS2: Add readahe...
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
  static void gfs2_dir_readahead(struct inode *inode, unsigned hsize, u32 index,
  			       struct file_ra_state *f_ra)
  {
  	struct gfs2_inode *ip = GFS2_I(inode);
  	struct gfs2_glock *gl = ip->i_gl;
  	struct buffer_head *bh;
  	u64 blocknr = 0, last;
  	unsigned count;
  
  	/* First check if we've already read-ahead for the whole range. */
79c4c379c   Steven Whitehouse   GFS2: f_ra is alw...
1348
  	if (index + MAX_RA_BLOCKS < f_ra->start)
dfe4d34b3   Bob Peterson   GFS2: Add readahe...
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
  		return;
  
  	f_ra->start = max((pgoff_t)index, f_ra->start);
  	for (count = 0; count < MAX_RA_BLOCKS; count++) {
  		if (f_ra->start >= hsize) /* if exceeded the hash table */
  			break;
  
  		last = blocknr;
  		blocknr = be64_to_cpu(ip->i_hash_cache[f_ra->start]);
  		f_ra->start++;
  		if (blocknr == last)
  			continue;
  
  		bh = gfs2_getbuf(gl, blocknr, 1);
  		if (trylock_buffer(bh)) {
  			if (buffer_uptodate(bh)) {
  				unlock_buffer(bh);
  				brelse(bh);
  				continue;
  			}
  			bh->b_end_io = end_buffer_read_sync;
  			submit_bh(READA | REQ_META, bh);
  			continue;
  		}
  		brelse(bh);
  	}
  }
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1376

b3b94faa5   David Teigland   [GFS2] The core o...
1377
  /**
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1378
1379
1380
1381
1382
   * 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...
1383
   *
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1384
   * Returns: errno
b3b94faa5   David Teigland   [GFS2] The core o...
1385
   */
cd915493f   Steven Whitehouse   [GFS2] Change all...
1386
  static int dir_e_read(struct inode *inode, u64 *offset, void *opaque,
dfe4d34b3   Bob Peterson   GFS2: Add readahe...
1387
  		      filldir_t filldir, struct file_ra_state *f_ra)
b3b94faa5   David Teigland   [GFS2] The core o...
1388
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1389
  	struct gfs2_inode *dip = GFS2_I(inode);
cd915493f   Steven Whitehouse   [GFS2] Change all...
1390
  	u32 hsize, len = 0;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1391
  	u32 hash, index;
b44b84d76   Al Viro   [GFS2] gfs2 misc ...
1392
  	__be64 *lp;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1393
1394
  	int copied = 0;
  	int error = 0;
4da3c6463   Steven Whitehouse   [GFS2] Fix a coup...
1395
  	unsigned depth = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1396

9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
1397
  	hsize = 1 << dip->i_depth;
b3b94faa5   David Teigland   [GFS2] The core o...
1398
  	hash = gfs2_dir_offset2hash(*offset);
9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
1399
  	index = hash >> (32 - dip->i_depth);
b3b94faa5   David Teigland   [GFS2] The core o...
1400

79c4c379c   Steven Whitehouse   GFS2: f_ra is alw...
1401
  	if (dip->i_hash_cache == NULL)
dfe4d34b3   Bob Peterson   GFS2: Add readahe...
1402
  		f_ra->start = 0;
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1403
1404
1405
  	lp = gfs2_dir_get_hash_table(dip);
  	if (IS_ERR(lp))
  		return PTR_ERR(lp);
b3b94faa5   David Teigland   [GFS2] The core o...
1406

dfe4d34b3   Bob Peterson   GFS2: Add readahe...
1407
  	gfs2_dir_readahead(inode, hsize, index, f_ra);
b3b94faa5   David Teigland   [GFS2] The core o...
1408
  	while (index < hsize) {
71b86f562   Steven Whitehouse   [GFS2] Further up...
1409
1410
  		error = gfs2_dir_read_leaf(inode, offset, opaque, filldir,
  					   &copied, &depth,
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1411
  					   be64_to_cpu(lp[index]));
b3b94faa5   David Teigland   [GFS2] The core o...
1412
  		if (error)
71b86f562   Steven Whitehouse   [GFS2] Further up...
1413
  			break;
b3b94faa5   David Teigland   [GFS2] The core o...
1414

9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
1415
  		len = 1 << (dip->i_depth - depth);
b3b94faa5   David Teigland   [GFS2] The core o...
1416
1417
  		index = (index & ~(len - 1)) + len;
  	}
71b86f562   Steven Whitehouse   [GFS2] Further up...
1418
1419
  	if (error > 0)
  		error = 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1420
1421
  	return error;
  }
cd915493f   Steven Whitehouse   [GFS2] Change all...
1422
  int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
dfe4d34b3   Bob Peterson   GFS2: Add readahe...
1423
  		  filldir_t filldir, struct file_ra_state *f_ra)
b3b94faa5   David Teigland   [GFS2] The core o...
1424
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1425
  	struct gfs2_inode *dip = GFS2_I(inode);
bdd19a22f   Steven Whitehouse   [GFS2] Patch to d...
1426
  	struct gfs2_sbd *sdp = GFS2_SB(inode);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1427
1428
  	struct dirent_gather g;
  	const struct gfs2_dirent **darr, *dent;
b3b94faa5   David Teigland   [GFS2] The core o...
1429
1430
1431
  	struct buffer_head *dibh;
  	int copied = 0;
  	int error;
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
1432
  	if (!dip->i_entries)
71b86f562   Steven Whitehouse   [GFS2] Further up...
1433
  		return 0;
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
1434
  	if (dip->i_diskflags & GFS2_DIF_EXHASH)
dfe4d34b3   Bob Peterson   GFS2: Add readahe...
1435
  		return dir_e_read(inode, offset, opaque, filldir, f_ra);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1436

b3b94faa5   David Teigland   [GFS2] The core o...
1437
1438
1439
1440
  	if (!gfs2_is_stuffed(dip)) {
  		gfs2_consist_inode(dip);
  		return -EIO;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
1441
1442
1443
  	error = gfs2_meta_inode_buffer(dip, &dibh);
  	if (error)
  		return error;
71b86f562   Steven Whitehouse   [GFS2] Further up...
1444
  	error = -ENOMEM;
bdd19a22f   Steven Whitehouse   [GFS2] Patch to d...
1445
  	/* 96 is max number of dirents which can be stuffed into an inode */
16c5f06f1   Josef Bacik   [GFS2] fix GFP_KE...
1446
  	darr = kmalloc(96 * sizeof(struct gfs2_dirent *), GFP_NOFS);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1447
1448
1449
1450
1451
1452
1453
1454
1455
  	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;
  		}
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
1456
  		if (dip->i_entries != g.offset) {
bdd19a22f   Steven Whitehouse   [GFS2] Patch to d...
1457
  			fs_warn(sdp, "Number of entries corrupt in dir %llu, "
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
1458
1459
  				"ip->i_entries (%u) != g.offset (%u)
  ",
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
1460
  				(unsigned long long)dip->i_no_addr,
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
1461
  				dip->i_entries,
bdd19a22f   Steven Whitehouse   [GFS2] Patch to d...
1462
1463
1464
1465
  				g.offset);
  			error = -EIO;
  			goto out;
  		}
71b86f562   Steven Whitehouse   [GFS2] Further up...
1466
  		error = do_filldir_main(dip, offset, opaque, filldir, darr,
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
1467
  					dip->i_entries, &copied);
71b86f562   Steven Whitehouse   [GFS2] Further up...
1468
1469
1470
  out:
  		kfree(darr);
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
1471
1472
1473
1474
1475
1476
1477
  	if (error > 0)
  		error = 0;
  
  	brelse(dibh);
  
  	return error;
  }
b3b94faa5   David Teigland   [GFS2] The core o...
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
  /**
   * 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
   */
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
1489
  struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name)
b3b94faa5   David Teigland   [GFS2] The core o...
1490
  {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1491
1492
  	struct buffer_head *bh;
  	struct gfs2_dirent *dent;
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
1493
1494
1495
1496
1497
  	struct inode *inode;
  
  	dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
  	if (dent) {
  		if (IS_ERR(dent))
e231c2ee6   David Howells   Convert ERR_PTR(P...
1498
  			return ERR_CAST(dent);
bb9bcf061   Wendy Cheng   [GFS2] Obtaining ...
1499
1500
1501
  		inode = gfs2_inode_lookup(dir->i_sb, 
  				be16_to_cpu(dent->de_type),
  				be64_to_cpu(dent->de_inum.no_addr),
44ad37d69   Bob Peterson   GFS2: filesystem ...
1502
  				be64_to_cpu(dent->de_inum.no_formal_ino), 0);
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
  		brelse(bh);
  		return inode;
  	}
  	return ERR_PTR(-ENOENT);
  }
  
  int gfs2_dir_check(struct inode *dir, const struct qstr *name,
  		   const struct gfs2_inode *ip)
  {
  	struct buffer_head *bh;
  	struct gfs2_dirent *dent;
  	int ret = -ENOENT;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1515
1516
1517
1518
1519
  
  	dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
  	if (dent) {
  		if (IS_ERR(dent))
  			return PTR_ERR(dent);
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
  		if (ip) {
  			if (be64_to_cpu(dent->de_inum.no_addr) != ip->i_no_addr)
  				goto out;
  			if (be64_to_cpu(dent->de_inum.no_formal_ino) !=
  			    ip->i_no_formal_ino)
  				goto out;
  			if (unlikely(IF2DT(ip->i_inode.i_mode) !=
  			    be16_to_cpu(dent->de_type))) {
  				gfs2_consist_inode(GFS2_I(dir));
  				ret = -EIO;
  				goto out;
  			}
  		}
  		ret = 0;
  out:
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1535
  		brelse(bh);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1536
  	}
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
1537
  	return ret;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1538
1539
1540
1541
1542
  }
  
  static int dir_new_leaf(struct inode *inode, const struct qstr *name)
  {
  	struct buffer_head *bh, *obh;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1543
  	struct gfs2_inode *ip = GFS2_I(inode);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1544
  	struct gfs2_leaf *leaf, *oleaf;
b3b94faa5   David Teigland   [GFS2] The core o...
1545
  	int error;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1546
1547
  	u32 index;
  	u64 bn;
b3b94faa5   David Teigland   [GFS2] The core o...
1548

9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
1549
  	index = name->hash >> (32 - ip->i_depth);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
  	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...
1563

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1564
1565
1566
1567
1568
1569
1570
  	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...
1571
  	oleaf->lf_next = cpu_to_be64(bh->b_blocknr);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1572
1573
1574
1575
1576
1577
1578
  	brelse(bh);
  	brelse(obh);
  
  	error = gfs2_meta_inode_buffer(ip, &bh);
  	if (error)
  		return error;
  	gfs2_trans_add_bh(ip->i_gl, bh, 1);
77658aad2   Steven Whitehouse   [GFS2] Eliminate ...
1579
  	gfs2_add_inode_blocks(&ip->i_inode, 1);
539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
1580
  	gfs2_dinode_out(ip, bh->b_data);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1581
1582
  	brelse(bh);
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
  }
  
  /**
   * 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...
1594
  int gfs2_dir_add(struct inode *inode, const struct qstr *name,
3d6ecb7d1   Steven Whitehouse   GFS2: When adding...
1595
  		 const struct gfs2_inode *nip)
b3b94faa5   David Teigland   [GFS2] The core o...
1596
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1597
  	struct gfs2_inode *ip = GFS2_I(inode);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1598
1599
1600
  	struct buffer_head *bh;
  	struct gfs2_dirent *dent;
  	struct gfs2_leaf *leaf;
b3b94faa5   David Teigland   [GFS2] The core o...
1601
  	int error;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1602
1603
1604
1605
1606
1607
1608
  	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);
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
1609
  			gfs2_inum_out(nip, dent);
3d6ecb7d1   Steven Whitehouse   GFS2: When adding...
1610
  			dent->de_type = cpu_to_be16(IF2DT(nip->i_inode.i_mode));
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
1611
  			if (ip->i_diskflags & GFS2_DIF_EXHASH) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1612
  				leaf = (struct gfs2_leaf *)bh->b_data;
bb16b342b   Marcin Slusarz   [GFS2] be*_add_cp...
1613
  				be16_add_cpu(&leaf->lf_entries, 1);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1614
1615
1616
1617
1618
1619
  			}
  			brelse(bh);
  			error = gfs2_meta_inode_buffer(ip, &bh);
  			if (error)
  				break;
  			gfs2_trans_add_bh(ip->i_gl, bh, 1);
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
1620
  			ip->i_entries++;
4bd91ba18   Steven Whitehouse   [GFS2] Add nanose...
1621
  			ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
3d6ecb7d1   Steven Whitehouse   GFS2: When adding...
1622
1623
  			if (S_ISDIR(nip->i_inode.i_mode))
  				inc_nlink(&ip->i_inode);
539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
1624
  			gfs2_dinode_out(ip, bh->b_data);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1625
1626
1627
1628
  			brelse(bh);
  			error = 0;
  			break;
  		}
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
1629
  		if (!(ip->i_diskflags & GFS2_DIF_EXHASH)) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1630
1631
1632
1633
1634
1635
1636
1637
  			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...
1638
  		if (error < 0)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1639
  			break;
9a0045088   Steven Whitehouse   [GFS2] Shrink & r...
1640
  		if (ip->i_depth < GFS2_DIR_MAX_DEPTH) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1641
1642
1643
1644
  			error = dir_double_exhash(ip);
  			if (error)
  				break;
  			error = dir_split_leaf(inode, name);
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
1645
  			if (error < 0)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1646
  				break;
e90deff53   Steven Whitehouse   [GFS2] Fix bug in...
1647
1648
  			if (error == 0)
  				continue;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1649
1650
1651
1652
1653
1654
1655
  		}
  		error = dir_new_leaf(inode, name);
  		if (!error)
  			continue;
  		error = -ENOSPC;
  		break;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
1656
1657
  	return error;
  }
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1658

b3b94faa5   David Teigland   [GFS2] The core o...
1659
1660
1661
1662
1663
1664
1665
  /**
   * gfs2_dir_del - Delete a directory entry
   * @dip: The GFS2 inode
   * @filename: The filename
   *
   * Returns: 0 on success, error code on failure
   */
855d23ce2   Steven Whitehouse   GFS2: Make gfs2_d...
1666
  int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry)
b3b94faa5   David Teigland   [GFS2] The core o...
1667
  {
855d23ce2   Steven Whitehouse   GFS2: Make gfs2_d...
1668
  	const struct qstr *name = &dentry->d_name;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1669
1670
  	struct gfs2_dirent *dent, *prev = NULL;
  	struct buffer_head *bh;
b3b94faa5   David Teigland   [GFS2] The core o...
1671

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1672
1673
  	/* Returns _either_ the entry (if its first in block) or the
  	   previous entry otherwise */
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1674
  	dent = gfs2_dirent_search(&dip->i_inode, name, gfs2_dirent_prev, &bh);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1675
1676
1677
1678
1679
1680
1681
1682
1683
  	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...
1684
  	if (gfs2_dirent_find(dent, name, NULL) == 0) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1685
1686
1687
1688
1689
  		prev = dent;
  		dent = (struct gfs2_dirent *)((char *)dent + be16_to_cpu(prev->de_rec_len));
  	}
  
  	dirent_del(dip, bh, prev, dent);
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
1690
  	if (dip->i_diskflags & GFS2_DIF_EXHASH) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1691
1692
1693
1694
1695
  		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...
1696
  	}
ed3865079   Steven Whitehouse   [GFS2] Finally ge...
1697
  	brelse(bh);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1698

ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
1699
  	if (!dip->i_entries)
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1700
  		gfs2_consist_inode(dip);
ad6203f2b   Steven Whitehouse   GFS2: Move "entri...
1701
  	dip->i_entries--;
4bd91ba18   Steven Whitehouse   [GFS2] Add nanose...
1702
  	dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
855d23ce2   Steven Whitehouse   GFS2: Make gfs2_d...
1703
1704
  	if (S_ISDIR(dentry->d_inode->i_mode))
  		drop_nlink(&dip->i_inode);
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1705
  	mark_inode_dirty(&dip->i_inode);
b3b94faa5   David Teigland   [GFS2] The core o...
1706

ab9bbda02   Steven Whitehouse   GFS2: Use ->dirty...
1707
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1708
  }
b3b94faa5   David Teigland   [GFS2] The core o...
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
  /**
   * 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...
1721
  int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
1722
  		   const struct gfs2_inode *nip, unsigned int new_type)
b3b94faa5   David Teigland   [GFS2] The core o...
1723
  {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1724
1725
  	struct buffer_head *bh;
  	struct gfs2_dirent *dent;
b3b94faa5   David Teigland   [GFS2] The core o...
1726
  	int error;
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1727
  	dent = gfs2_dirent_search(&dip->i_inode, filename, gfs2_dirent_find, &bh);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1728
1729
1730
1731
1732
1733
  	if (!dent) {
  		gfs2_consist_inode(dip);
  		return -EIO;
  	}
  	if (IS_ERR(dent))
  		return PTR_ERR(dent);
b3b94faa5   David Teigland   [GFS2] The core o...
1734

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1735
  	gfs2_trans_add_bh(dip->i_gl, bh, 1);
dbb7cae2a   Steven Whitehouse   [GFS2] Clean up i...
1736
  	gfs2_inum_out(nip, dent);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1737
  	dent->de_type = cpu_to_be16(new_type);
383f01fbf   Steven Whitehouse   GFS2: Banish stru...
1738
  	if (dip->i_diskflags & GFS2_DIF_EXHASH) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1739
1740
1741
1742
1743
1744
  		brelse(bh);
  		error = gfs2_meta_inode_buffer(dip, &bh);
  		if (error)
  			return error;
  		gfs2_trans_add_bh(dip->i_gl, bh, 1);
  	}
4bd91ba18   Steven Whitehouse   [GFS2] Add nanose...
1745
  	dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
1746
  	gfs2_dinode_out(dip, bh->b_data);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1747
1748
  	brelse(bh);
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1749
1750
1751
  }
  
  /**
b3b94faa5   David Teigland   [GFS2] The core o...
1752
1753
1754
1755
1756
   * 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
ec038c826   Bob Peterson   GFS2: pass leaf_b...
1757
   * @leaf_bh: buffer_head for the starting leaf
d24a7a439   Bob Peterson   GFS2: Combine tra...
1758
   * last_dealloc: 1 if this is the final dealloc for the leaf, else 0
b3b94faa5   David Teigland   [GFS2] The core o...
1759
1760
1761
   *
   * Returns: errno
   */
cd915493f   Steven Whitehouse   [GFS2] Change all...
1762
  static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
ec038c826   Bob Peterson   GFS2: pass leaf_b...
1763
1764
  			u64 leaf_no, struct buffer_head *leaf_bh,
  			int last_dealloc)
b3b94faa5   David Teigland   [GFS2] The core o...
1765
  {
feaa7bba0   Steven Whitehouse   [GFS2] Fix unlink...
1766
  	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1767
  	struct gfs2_leaf *tmp_leaf;
b3b94faa5   David Teigland   [GFS2] The core o...
1768
1769
  	struct gfs2_rgrp_list rlist;
  	struct buffer_head *bh, *dibh;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1770
  	u64 blk, nblk;
b3b94faa5   David Teigland   [GFS2] The core o...
1771
1772
  	unsigned int rg_blocks = 0, l_blocks = 0;
  	char *ht;
cd915493f   Steven Whitehouse   [GFS2] Change all...
1773
  	unsigned int x, size = len * sizeof(u64);
b3b94faa5   David Teigland   [GFS2] The core o...
1774
1775
1776
  	int error;
  
  	memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
16c5f06f1   Josef Bacik   [GFS2] fix GFP_KE...
1777
  	ht = kzalloc(size, GFP_NOFS);
b3b94faa5   David Teigland   [GFS2] The core o...
1778
1779
  	if (!ht)
  		return -ENOMEM;
564e12b11   Bob Peterson   GFS2: decouple qu...
1780
  	if (!gfs2_qadata_get(dip)) {
182fe5abd   Cyrill Gorcunov   [GFS2] possible n...
1781
1782
1783
  		error = -ENOMEM;
  		goto out;
  	}
b3b94faa5   David Teigland   [GFS2] The core o...
1784
1785
1786
  
  	error = gfs2_quota_hold(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
  	if (error)
182fe5abd   Cyrill Gorcunov   [GFS2] possible n...
1787
  		goto out_put;
b3b94faa5   David Teigland   [GFS2] The core o...
1788

b3b94faa5   David Teigland   [GFS2] The core o...
1789
  	/*  Count the number of leaves  */
ec038c826   Bob Peterson   GFS2: pass leaf_b...
1790
  	bh = leaf_bh;
b3b94faa5   David Teigland   [GFS2] The core o...
1791

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1792
  	for (blk = leaf_no; blk; blk = nblk) {
ec038c826   Bob Peterson   GFS2: pass leaf_b...
1793
1794
1795
1796
1797
  		if (blk != leaf_no) {
  			error = get_leaf(dip, blk, &bh);
  			if (error)
  				goto out_rlist;
  		}
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1798
1799
  		tmp_leaf = (struct gfs2_leaf *)bh->b_data;
  		nblk = be64_to_cpu(tmp_leaf->lf_next);
ec038c826   Bob Peterson   GFS2: pass leaf_b...
1800
1801
  		if (blk != leaf_no)
  			brelse(bh);
b3b94faa5   David Teigland   [GFS2] The core o...
1802

70b0c3656   Steven Whitehouse   GFS2: Use cached ...
1803
  		gfs2_rlist_add(dip, &rlist, blk);
b3b94faa5   David Teigland   [GFS2] The core o...
1804
1805
  		l_blocks++;
  	}
fe6c991c5   Bob Peterson   [GFS2] Get rid of...
1806
  	gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE);
b3b94faa5   David Teigland   [GFS2] The core o...
1807
1808
1809
  
  	for (x = 0; x < rlist.rl_rgrps; x++) {
  		struct gfs2_rgrpd *rgd;
5c676f6d3   Steven Whitehouse   [GFS2] Macros rem...
1810
  		rgd = rlist.rl_ghs[x].gh_gl->gl_object;
bb8d8a6f5   Steven Whitehouse   [GFS2] Fix sign p...
1811
  		rg_blocks += rgd->rd_length;
b3b94faa5   David Teigland   [GFS2] The core o...
1812
1813
1814
1815
1816
1817
1818
  	}
  
  	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...
1819
  			rg_blocks + (DIV_ROUND_UP(size, sdp->sd_jbsize) + 1) +
b3b94faa5   David Teigland   [GFS2] The core o...
1820
1821
1822
  			RES_DINODE + RES_STATFS + RES_QUOTA, l_blocks);
  	if (error)
  		goto out_rg_gunlock;
ec038c826   Bob Peterson   GFS2: pass leaf_b...
1823
  	bh = leaf_bh;
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1824
  	for (blk = leaf_no; blk; blk = nblk) {
ec038c826   Bob Peterson   GFS2: pass leaf_b...
1825
1826
1827
1828
1829
  		if (blk != leaf_no) {
  			error = get_leaf(dip, blk, &bh);
  			if (error)
  				goto out_end_trans;
  		}
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1830
1831
  		tmp_leaf = (struct gfs2_leaf *)bh->b_data;
  		nblk = be64_to_cpu(tmp_leaf->lf_next);
ec038c826   Bob Peterson   GFS2: pass leaf_b...
1832
1833
  		if (blk != leaf_no)
  			brelse(bh);
b3b94faa5   David Teigland   [GFS2] The core o...
1834
1835
  
  		gfs2_free_meta(dip, blk, 1);
77658aad2   Steven Whitehouse   [GFS2] Eliminate ...
1836
  		gfs2_add_inode_blocks(&dip->i_inode, -1);
b3b94faa5   David Teigland   [GFS2] The core o...
1837
  	}
cd915493f   Steven Whitehouse   [GFS2] Change all...
1838
  	error = gfs2_dir_write_data(dip, ht, index * sizeof(u64), size);
b3b94faa5   David Teigland   [GFS2] The core o...
1839
1840
1841
1842
1843
1844
1845
1846
1847
  	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...
1848
  	gfs2_trans_add_bh(dip->i_gl, dibh, 1);
d24a7a439   Bob Peterson   GFS2: Combine tra...
1849
1850
1851
1852
  	/* On the last dealloc, make this a regular file in case we crash.
  	   (We don't want to free these blocks a second time.)  */
  	if (last_dealloc)
  		dip->i_inode.i_mode = S_IFREG;
539e5d6b7   Steven Whitehouse   [GFS2] Change arg...
1853
  	gfs2_dinode_out(dip, dibh->b_data);
b3b94faa5   David Teigland   [GFS2] The core o...
1854
  	brelse(dibh);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1855
  out_end_trans:
b3b94faa5   David Teigland   [GFS2] The core o...
1856
  	gfs2_trans_end(sdp);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1857
  out_rg_gunlock:
b3b94faa5   David Teigland   [GFS2] The core o...
1858
  	gfs2_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs);
a91ea69ff   Steven Whitehouse   [GFS2] Align all ...
1859
  out_rlist:
b3b94faa5   David Teigland   [GFS2] The core o...
1860
  	gfs2_rlist_free(&rlist);
b3b94faa5   David Teigland   [GFS2] The core o...
1861
  	gfs2_quota_unhold(dip);
182fe5abd   Cyrill Gorcunov   [GFS2] possible n...
1862
  out_put:
564e12b11   Bob Peterson   GFS2: decouple qu...
1863
  	gfs2_qadata_put(dip);
182fe5abd   Cyrill Gorcunov   [GFS2] possible n...
1864
  out:
b3b94faa5   David Teigland   [GFS2] The core o...
1865
  	kfree(ht);
b3b94faa5   David Teigland   [GFS2] The core o...
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
  	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)
  {
556bb1799   Bob Peterson   GFS2: move functi...
1881
1882
1883
  	struct buffer_head *bh;
  	struct gfs2_leaf *leaf;
  	u32 hsize, len;
556bb1799   Bob Peterson   GFS2: move functi...
1884
1885
1886
1887
1888
1889
  	u32 index = 0, next_index;
  	__be64 *lp;
  	u64 leaf_no;
  	int error = 0, last;
  
  	hsize = 1 << dip->i_depth;
556bb1799   Bob Peterson   GFS2: move functi...
1890

17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1891
1892
1893
  	lp = gfs2_dir_get_hash_table(dip);
  	if (IS_ERR(lp))
  		return PTR_ERR(lp);
556bb1799   Bob Peterson   GFS2: move functi...
1894
1895
  
  	while (index < hsize) {
17d539f04   Steven Whitehouse   GFS2: Cache dir h...
1896
  		leaf_no = be64_to_cpu(lp[index]);
556bb1799   Bob Peterson   GFS2: move functi...
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
  		if (leaf_no) {
  			error = get_leaf(dip, leaf_no, &bh);
  			if (error)
  				goto out;
  			leaf = (struct gfs2_leaf *)bh->b_data;
  			len = 1 << (dip->i_depth - be16_to_cpu(leaf->lf_depth));
  
  			next_index = (index & ~(len - 1)) + len;
  			last = ((next_index >= hsize) ? 1 : 0);
  			error = leaf_dealloc(dip, index, len, leaf_no, bh,
  					     last);
  			brelse(bh);
  			if (error)
  				goto out;
  			index = next_index;
  		} else
  			index++;
  	}
  
  	if (index != hsize) {
  		gfs2_consist_inode(dip);
  		error = -EIO;
  	}
  
  out:
556bb1799   Bob Peterson   GFS2: move functi...
1922
1923
  
  	return error;
b3b94faa5   David Teigland   [GFS2] The core o...
1924
1925
1926
1927
1928
1929
  }
  
  /**
   * 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...
1930
   *
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1931
   * Returns: 1 if alloc required, 0 if not, -ve on error
b3b94faa5   David Teigland   [GFS2] The core o...
1932
   */
4d8012b60   Steven Whitehouse   [GFS2] Fix bug wh...
1933
  int gfs2_diradd_alloc_required(struct inode *inode, const struct qstr *name)
b3b94faa5   David Teigland   [GFS2] The core o...
1934
  {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1935
1936
  	struct gfs2_dirent *dent;
  	struct buffer_head *bh;
b3b94faa5   David Teigland   [GFS2] The core o...
1937

c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1938
  	dent = gfs2_dirent_search(inode, name, gfs2_dirent_find_space, &bh);
ed3865079   Steven Whitehouse   [GFS2] Finally ge...
1939
  	if (!dent) {
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1940
  		return 1;
ed3865079   Steven Whitehouse   [GFS2] Finally ge...
1941
  	}
c752666c1   Steven Whitehouse   [GFS2] Fix bug in...
1942
1943
1944
1945
  	if (IS_ERR(dent))
  		return PTR_ERR(dent);
  	brelse(bh);
  	return 0;
b3b94faa5   David Teigland   [GFS2] The core o...
1946
  }