xref: /openbmc/linux/fs/gfs2/dir.c (revision b181f7029bd71238ac2754ce7052dffd69432085)
17336d0e6SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2b3b94faaSDavid Teigland /*
3b3b94faaSDavid Teigland  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
43a8a9a10SSteven Whitehouse  * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
5b3b94faaSDavid Teigland  */
6b3b94faaSDavid Teigland 
7b3b94faaSDavid Teigland /*
8b3b94faaSDavid Teigland  * Implements Extendible Hashing as described in:
9b3b94faaSDavid Teigland  *   "Extendible Hashing" by Fagin, et al in
10b3b94faaSDavid Teigland  *     __ACM Trans. on Database Systems__, Sept 1979.
11b3b94faaSDavid Teigland  *
12b3b94faaSDavid Teigland  *
13b3b94faaSDavid Teigland  * Here's the layout of dirents which is essentially the same as that of ext2
14b3b94faaSDavid Teigland  * within a single block. The field de_name_len is the number of bytes
15b3b94faaSDavid Teigland  * actually required for the name (no null terminator). The field de_rec_len
16b3b94faaSDavid Teigland  * is the number of bytes allocated to the dirent. The offset of the next
17b3b94faaSDavid Teigland  * dirent in the block is (dirent + dirent->de_rec_len). When a dirent is
18b3b94faaSDavid Teigland  * deleted, the preceding dirent inherits its allocated space, ie
19b3b94faaSDavid Teigland  * prev->de_rec_len += deleted->de_rec_len. Since the next dirent is obtained
20b3b94faaSDavid Teigland  * by adding de_rec_len to the current dirent, this essentially causes the
21b3b94faaSDavid Teigland  * deleted dirent to get jumped over when iterating through all the dirents.
22b3b94faaSDavid Teigland  *
23b3b94faaSDavid Teigland  * When deleting the first dirent in a block, there is no previous dirent so
24b3b94faaSDavid Teigland  * the field de_ino is set to zero to designate it as deleted. When allocating
25b3b94faaSDavid Teigland  * a dirent, gfs2_dirent_alloc iterates through the dirents in a block. If the
26b3b94faaSDavid Teigland  * first dirent has (de_ino == 0) and de_rec_len is large enough, this first
27b3b94faaSDavid Teigland  * dirent is allocated. Otherwise it must go through all the 'used' dirents
28b3b94faaSDavid Teigland  * searching for one in which the amount of total space minus the amount of
29b3b94faaSDavid Teigland  * used space will provide enough space for the new dirent.
30b3b94faaSDavid Teigland  *
31b3b94faaSDavid Teigland  * There are two types of blocks in which dirents reside. In a stuffed dinode,
32b3b94faaSDavid Teigland  * the dirents begin at offset sizeof(struct gfs2_dinode) from the beginning of
33b3b94faaSDavid Teigland  * the block.  In leaves, they begin at offset sizeof(struct gfs2_leaf) from the
34b3b94faaSDavid Teigland  * beginning of the leaf block. The dirents reside in leaves when
35b3b94faaSDavid Teigland  *
36383f01fbSSteven Whitehouse  * dip->i_diskflags & GFS2_DIF_EXHASH is true
37b3b94faaSDavid Teigland  *
38b3b94faaSDavid Teigland  * Otherwise, the dirents are "linear", within a single stuffed dinode block.
39b3b94faaSDavid Teigland  *
40b3b94faaSDavid Teigland  * When the dirents are in leaves, the actual contents of the directory file are
41b3b94faaSDavid Teigland  * used as an array of 64-bit block pointers pointing to the leaf blocks. The
4261e085a8SSteven Whitehouse  * dirents are NOT in the directory file itself. There can be more than one
4361e085a8SSteven Whitehouse  * block pointer in the array that points to the same leaf. In fact, when a
4461e085a8SSteven Whitehouse  * directory is first converted from linear to exhash, all of the pointers
4561e085a8SSteven Whitehouse  * point to the same leaf.
46b3b94faaSDavid Teigland  *
47b3b94faaSDavid Teigland  * When a leaf is completely full, the size of the hash table can be
48b3b94faaSDavid Teigland  * doubled unless it is already at the maximum size which is hard coded into
49b3b94faaSDavid Teigland  * GFS2_DIR_MAX_DEPTH. After that, leaves are chained together in a linked list,
50b3b94faaSDavid Teigland  * but never before the maximum hash table size has been reached.
51b3b94faaSDavid Teigland  */
52b3b94faaSDavid Teigland 
53d77d1b58SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
54d77d1b58SJoe Perches 
55b3b94faaSDavid Teigland #include <linux/slab.h>
56b3b94faaSDavid Teigland #include <linux/spinlock.h>
57b3b94faaSDavid Teigland #include <linux/buffer_head.h>
58b3b94faaSDavid Teigland #include <linux/sort.h>
595c676f6dSSteven Whitehouse #include <linux/gfs2_ondisk.h>
6071b86f56SSteven Whitehouse #include <linux/crc32.h>
61fe1bdedcSSteven Whitehouse #include <linux/vmalloc.h>
622f8b5444SChristoph Hellwig #include <linux/bio.h>
63b3b94faaSDavid Teigland 
64b3b94faaSDavid Teigland #include "gfs2.h"
655c676f6dSSteven Whitehouse #include "incore.h"
66b3b94faaSDavid Teigland #include "dir.h"
67b3b94faaSDavid Teigland #include "glock.h"
68b3b94faaSDavid Teigland #include "inode.h"
69b3b94faaSDavid Teigland #include "meta_io.h"
70b3b94faaSDavid Teigland #include "quota.h"
71b3b94faaSDavid Teigland #include "rgrp.h"
72b3b94faaSDavid Teigland #include "trans.h"
73e13940baSSteven Whitehouse #include "bmap.h"
745c676f6dSSteven Whitehouse #include "util.h"
75b3b94faaSDavid Teigland 
76dfe4d34bSBob Peterson #define MAX_RA_BLOCKS 32 /* max read-ahead blocks */
77dfe4d34bSBob Peterson 
78cd915493SSteven Whitehouse #define gfs2_disk_hash2offset(h) (((u64)(h)) >> 1)
79cd915493SSteven Whitehouse #define gfs2_dir_offset2hash(p) ((u32)(((u64)(p)) << 1))
80471f3db2SBenjamin Marzinski #define GFS2_HASH_INDEX_MASK 0xffffc000
81471f3db2SBenjamin Marzinski #define GFS2_USE_HASH_FLAG 0x2000
82b3b94faaSDavid Teigland 
838d123585SSteven Whitehouse struct qstr gfs2_qdot __read_mostly;
848d123585SSteven Whitehouse struct qstr gfs2_qdotdot __read_mostly;
858d123585SSteven Whitehouse 
862bdbc5d7SSteven Whitehouse typedef int (*gfs2_dscan_t)(const struct gfs2_dirent *dent,
872bdbc5d7SSteven Whitehouse 			    const struct qstr *name, void *opaque);
88b3b94faaSDavid Teigland 
gfs2_dir_get_new_buffer(struct gfs2_inode * ip,u64 block,struct buffer_head ** bhp)89cd915493SSteven Whitehouse int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block,
90e13940baSSteven Whitehouse 			    struct buffer_head **bhp)
91e13940baSSteven Whitehouse {
92e13940baSSteven Whitehouse 	struct buffer_head *bh;
93e13940baSSteven Whitehouse 
94e13940baSSteven Whitehouse 	bh = gfs2_meta_new(ip->i_gl, block);
95350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(ip->i_gl, bh);
96e13940baSSteven Whitehouse 	gfs2_metatype_set(bh, GFS2_METATYPE_JD, GFS2_FORMAT_JD);
97e13940baSSteven Whitehouse 	gfs2_buffer_clear_tail(bh, sizeof(struct gfs2_meta_header));
9861e085a8SSteven Whitehouse 	*bhp = bh;
9961e085a8SSteven Whitehouse 	return 0;
10061e085a8SSteven Whitehouse }
10161e085a8SSteven Whitehouse 
gfs2_dir_get_existing_buffer(struct gfs2_inode * ip,u64 block,struct buffer_head ** bhp)102cd915493SSteven Whitehouse static int gfs2_dir_get_existing_buffer(struct gfs2_inode *ip, u64 block,
10361e085a8SSteven Whitehouse 					struct buffer_head **bhp)
10461e085a8SSteven Whitehouse {
10561e085a8SSteven Whitehouse 	struct buffer_head *bh;
10661e085a8SSteven Whitehouse 	int error;
10761e085a8SSteven Whitehouse 
108c8d57703SAndreas Gruenbacher 	error = gfs2_meta_read(ip->i_gl, block, DIO_WAIT, 0, &bh);
109e13940baSSteven Whitehouse 	if (error)
110e13940baSSteven Whitehouse 		return error;
111feaa7bbaSSteven Whitehouse 	if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) {
112e13940baSSteven Whitehouse 		brelse(bh);
113e13940baSSteven Whitehouse 		return -EIO;
114e13940baSSteven Whitehouse 	}
115e13940baSSteven Whitehouse 	*bhp = bh;
116e13940baSSteven Whitehouse 	return 0;
117e13940baSSteven Whitehouse }
118e13940baSSteven Whitehouse 
gfs2_dir_write_stuffed(struct gfs2_inode * ip,const char * buf,unsigned int offset,unsigned int size)119e13940baSSteven Whitehouse static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf,
120e13940baSSteven Whitehouse 				  unsigned int offset, unsigned int size)
121e13940baSSteven Whitehouse {
122e13940baSSteven Whitehouse 	struct buffer_head *dibh;
123e13940baSSteven Whitehouse 	int error;
124e13940baSSteven Whitehouse 
125e13940baSSteven Whitehouse 	error = gfs2_meta_inode_buffer(ip, &dibh);
126e13940baSSteven Whitehouse 	if (error)
127e13940baSSteven Whitehouse 		return error;
128e13940baSSteven Whitehouse 
129350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(ip->i_gl, dibh);
130c752666cSSteven Whitehouse 	memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size);
131a2e0f799SSteven Whitehouse 	if (ip->i_inode.i_size < offset + size)
132a2e0f799SSteven Whitehouse 		i_size_write(&ip->i_inode, offset + size);
1338a8b8d91SJeff Layton 	ip->i_inode.i_mtime = inode_set_ctime_current(&ip->i_inode);
134539e5d6bSSteven Whitehouse 	gfs2_dinode_out(ip, dibh->b_data);
135e13940baSSteven Whitehouse 
136e13940baSSteven Whitehouse 	brelse(dibh);
137e13940baSSteven Whitehouse 
138e13940baSSteven Whitehouse 	return size;
139e13940baSSteven Whitehouse }
140e13940baSSteven Whitehouse 
141e13940baSSteven Whitehouse 
142e13940baSSteven Whitehouse 
143e13940baSSteven Whitehouse /**
144e13940baSSteven Whitehouse  * gfs2_dir_write_data - Write directory information to the inode
145e13940baSSteven Whitehouse  * @ip: The GFS2 inode
146e13940baSSteven Whitehouse  * @buf: The buffer containing information to be written
147e13940baSSteven Whitehouse  * @offset: The file offset to start writing at
148e13940baSSteven Whitehouse  * @size: The amount of data to write
149e13940baSSteven Whitehouse  *
150e13940baSSteven Whitehouse  * Returns: The number of bytes correctly written or error code
151e13940baSSteven Whitehouse  */
gfs2_dir_write_data(struct gfs2_inode * ip,const char * buf,u64 offset,unsigned int size)152e13940baSSteven Whitehouse static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf,
153cd915493SSteven Whitehouse 			       u64 offset, unsigned int size)
154e13940baSSteven Whitehouse {
155feaa7bbaSSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
156e13940baSSteven Whitehouse 	struct buffer_head *dibh;
157cd915493SSteven Whitehouse 	u64 lblock, dblock;
158cd915493SSteven Whitehouse 	u32 extlen = 0;
159e13940baSSteven Whitehouse 	unsigned int o;
160e13940baSSteven Whitehouse 	int copied = 0;
161e13940baSSteven Whitehouse 	int error = 0;
1629153dac1SAndreas Gruenbacher 	bool new = false;
163e13940baSSteven Whitehouse 
164e13940baSSteven Whitehouse 	if (!size)
165e13940baSSteven Whitehouse 		return 0;
166e13940baSSteven Whitehouse 
167235628c5SAndreas Gruenbacher 	if (gfs2_is_stuffed(ip) && offset + size <= gfs2_max_stuffed_size(ip))
168568f4c96SSteven Whitehouse 		return gfs2_dir_write_stuffed(ip, buf, (unsigned int)offset,
169568f4c96SSteven Whitehouse 					      size);
170e13940baSSteven Whitehouse 
171e13940baSSteven Whitehouse 	if (gfs2_assert_warn(sdp, gfs2_is_jdata(ip)))
172e13940baSSteven Whitehouse 		return -EINVAL;
173e13940baSSteven Whitehouse 
174e13940baSSteven Whitehouse 	if (gfs2_is_stuffed(ip)) {
1757a607a41SAndreas Gruenbacher 		error = gfs2_unstuff_dinode(ip);
176e13940baSSteven Whitehouse 		if (error)
177e13940baSSteven Whitehouse 			return error;
178e13940baSSteven Whitehouse 	}
179e13940baSSteven Whitehouse 
180e13940baSSteven Whitehouse 	lblock = offset;
181e13940baSSteven Whitehouse 	o = do_div(lblock, sdp->sd_jbsize) + sizeof(struct gfs2_meta_header);
182e13940baSSteven Whitehouse 
183e13940baSSteven Whitehouse 	while (copied < size) {
184e13940baSSteven Whitehouse 		unsigned int amount;
185e13940baSSteven Whitehouse 		struct buffer_head *bh;
186e13940baSSteven Whitehouse 
187e13940baSSteven Whitehouse 		amount = size - copied;
188e13940baSSteven Whitehouse 		if (amount > sdp->sd_sb.sb_bsize - o)
189e13940baSSteven Whitehouse 			amount = sdp->sd_sb.sb_bsize - o;
190e13940baSSteven Whitehouse 
191e13940baSSteven Whitehouse 		if (!extlen) {
1929153dac1SAndreas Gruenbacher 			extlen = 1;
1939153dac1SAndreas Gruenbacher 			error = gfs2_alloc_extent(&ip->i_inode, lblock, &dblock,
1949153dac1SAndreas Gruenbacher 						  &extlen, &new);
195e13940baSSteven Whitehouse 			if (error)
196e13940baSSteven Whitehouse 				goto fail;
197e13940baSSteven Whitehouse 			error = -EIO;
198e13940baSSteven Whitehouse 			if (gfs2_assert_withdraw(sdp, dblock))
199e13940baSSteven Whitehouse 				goto fail;
200e13940baSSteven Whitehouse 		}
201e13940baSSteven Whitehouse 
20261e085a8SSteven Whitehouse 		if (amount == sdp->sd_jbsize || new)
20361e085a8SSteven Whitehouse 			error = gfs2_dir_get_new_buffer(ip, dblock, &bh);
20461e085a8SSteven Whitehouse 		else
20561e085a8SSteven Whitehouse 			error = gfs2_dir_get_existing_buffer(ip, dblock, &bh);
20661e085a8SSteven Whitehouse 
207e13940baSSteven Whitehouse 		if (error)
208e13940baSSteven Whitehouse 			goto fail;
209e13940baSSteven Whitehouse 
210350a9b0aSSteven Whitehouse 		gfs2_trans_add_meta(ip->i_gl, bh);
211e13940baSSteven Whitehouse 		memcpy(bh->b_data + o, buf, amount);
212e13940baSSteven Whitehouse 		brelse(bh);
213e13940baSSteven Whitehouse 
214899bb264SSteven Whitehouse 		buf += amount;
215e13940baSSteven Whitehouse 		copied += amount;
216e13940baSSteven Whitehouse 		lblock++;
217e13940baSSteven Whitehouse 		dblock++;
218e13940baSSteven Whitehouse 		extlen--;
219e13940baSSteven Whitehouse 
220e13940baSSteven Whitehouse 		o = sizeof(struct gfs2_meta_header);
221e13940baSSteven Whitehouse 	}
222e13940baSSteven Whitehouse 
223e13940baSSteven Whitehouse out:
224e13940baSSteven Whitehouse 	error = gfs2_meta_inode_buffer(ip, &dibh);
225e13940baSSteven Whitehouse 	if (error)
226e13940baSSteven Whitehouse 		return error;
227e13940baSSteven Whitehouse 
228a2e0f799SSteven Whitehouse 	if (ip->i_inode.i_size < offset + copied)
229a2e0f799SSteven Whitehouse 		i_size_write(&ip->i_inode, offset + copied);
2308a8b8d91SJeff Layton 	ip->i_inode.i_mtime = inode_set_ctime_current(&ip->i_inode);
231e13940baSSteven Whitehouse 
232350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(ip->i_gl, dibh);
233539e5d6bSSteven Whitehouse 	gfs2_dinode_out(ip, dibh->b_data);
234e13940baSSteven Whitehouse 	brelse(dibh);
235e13940baSSteven Whitehouse 
236e13940baSSteven Whitehouse 	return copied;
237e13940baSSteven Whitehouse fail:
238e13940baSSteven Whitehouse 	if (copied)
239e13940baSSteven Whitehouse 		goto out;
240e13940baSSteven Whitehouse 	return error;
241e13940baSSteven Whitehouse }
242e13940baSSteven Whitehouse 
gfs2_dir_read_stuffed(struct gfs2_inode * ip,__be64 * buf,unsigned int size)2434c28d338SSteven Whitehouse static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, __be64 *buf,
2444c28d338SSteven Whitehouse 				 unsigned int size)
245e13940baSSteven Whitehouse {
246e13940baSSteven Whitehouse 	struct buffer_head *dibh;
247e13940baSSteven Whitehouse 	int error;
248e13940baSSteven Whitehouse 
249e13940baSSteven Whitehouse 	error = gfs2_meta_inode_buffer(ip, &dibh);
250e13940baSSteven Whitehouse 	if (!error) {
2514c28d338SSteven Whitehouse 		memcpy(buf, dibh->b_data + sizeof(struct gfs2_dinode), size);
252e13940baSSteven Whitehouse 		brelse(dibh);
253e13940baSSteven Whitehouse 	}
254e13940baSSteven Whitehouse 
255e13940baSSteven Whitehouse 	return (error) ? error : size;
256e13940baSSteven Whitehouse }
257e13940baSSteven Whitehouse 
258e13940baSSteven Whitehouse 
259e13940baSSteven Whitehouse /**
260e13940baSSteven Whitehouse  * gfs2_dir_read_data - Read a data from a directory inode
261e13940baSSteven Whitehouse  * @ip: The GFS2 Inode
262e13940baSSteven Whitehouse  * @buf: The buffer to place result into
263e13940baSSteven Whitehouse  * @size: Amount of data to transfer
264e13940baSSteven Whitehouse  *
265e13940baSSteven Whitehouse  * Returns: The amount of data actually copied or the error
266e13940baSSteven Whitehouse  */
gfs2_dir_read_data(struct gfs2_inode * ip,__be64 * buf,unsigned int size)2674c28d338SSteven Whitehouse static int gfs2_dir_read_data(struct gfs2_inode *ip, __be64 *buf,
2684c28d338SSteven Whitehouse 			      unsigned int size)
269e13940baSSteven Whitehouse {
270feaa7bbaSSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
271cd915493SSteven Whitehouse 	u64 lblock, dblock;
272cd915493SSteven Whitehouse 	u32 extlen = 0;
273e13940baSSteven Whitehouse 	unsigned int o;
274e13940baSSteven Whitehouse 	int copied = 0;
275e13940baSSteven Whitehouse 	int error = 0;
276e13940baSSteven Whitehouse 
277e13940baSSteven Whitehouse 	if (gfs2_is_stuffed(ip))
2784c28d338SSteven Whitehouse 		return gfs2_dir_read_stuffed(ip, buf, size);
279e13940baSSteven Whitehouse 
280e13940baSSteven Whitehouse 	if (gfs2_assert_warn(sdp, gfs2_is_jdata(ip)))
281e13940baSSteven Whitehouse 		return -EINVAL;
282e13940baSSteven Whitehouse 
2834c28d338SSteven Whitehouse 	lblock = 0;
284e13940baSSteven Whitehouse 	o = do_div(lblock, sdp->sd_jbsize) + sizeof(struct gfs2_meta_header);
285e13940baSSteven Whitehouse 
286e13940baSSteven Whitehouse 	while (copied < size) {
287e13940baSSteven Whitehouse 		unsigned int amount;
288e13940baSSteven Whitehouse 		struct buffer_head *bh;
289e13940baSSteven Whitehouse 
290e13940baSSteven Whitehouse 		amount = size - copied;
291e13940baSSteven Whitehouse 		if (amount > sdp->sd_sb.sb_bsize - o)
292e13940baSSteven Whitehouse 			amount = sdp->sd_sb.sb_bsize - o;
293e13940baSSteven Whitehouse 
294e13940baSSteven Whitehouse 		if (!extlen) {
2959153dac1SAndreas Gruenbacher 			extlen = 32;
2969153dac1SAndreas Gruenbacher 			error = gfs2_get_extent(&ip->i_inode, lblock,
297fd88de56SSteven Whitehouse 						&dblock, &extlen);
2987276b3b0SSteven Whitehouse 			if (error || !dblock)
2997276b3b0SSteven Whitehouse 				goto fail;
3007276b3b0SSteven Whitehouse 			BUG_ON(extlen < 1);
3017276b3b0SSteven Whitehouse 			bh = gfs2_meta_ra(ip->i_gl, dblock, extlen);
302b7d8ac3eSAdrian Bunk 		} else {
303c8d57703SAndreas Gruenbacher 			error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, 0, &bh);
304e13940baSSteven Whitehouse 			if (error)
305e13940baSSteven Whitehouse 				goto fail;
306e13940baSSteven Whitehouse 		}
3077276b3b0SSteven Whitehouse 		error = gfs2_metatype_check(sdp, bh, GFS2_METATYPE_JD);
3087276b3b0SSteven Whitehouse 		if (error) {
3097276b3b0SSteven Whitehouse 			brelse(bh);
310e13940baSSteven Whitehouse 			goto fail;
3117276b3b0SSteven Whitehouse 		}
312e13940baSSteven Whitehouse 		dblock++;
313e13940baSSteven Whitehouse 		extlen--;
314e13940baSSteven Whitehouse 		memcpy(buf, bh->b_data + o, amount);
315e13940baSSteven Whitehouse 		brelse(bh);
3164c28d338SSteven Whitehouse 		buf += (amount/sizeof(__be64));
317e13940baSSteven Whitehouse 		copied += amount;
318e13940baSSteven Whitehouse 		lblock++;
319e13940baSSteven Whitehouse 		o = sizeof(struct gfs2_meta_header);
320e13940baSSteven Whitehouse 	}
321e13940baSSteven Whitehouse 
322e13940baSSteven Whitehouse 	return copied;
323e13940baSSteven Whitehouse fail:
324e13940baSSteven Whitehouse 	return (copied) ? copied : error;
325e13940baSSteven Whitehouse }
326e13940baSSteven Whitehouse 
32717d539f0SSteven Whitehouse /**
32817d539f0SSteven Whitehouse  * gfs2_dir_get_hash_table - Get pointer to the dir hash table
32917d539f0SSteven Whitehouse  * @ip: The inode in question
33017d539f0SSteven Whitehouse  *
33117d539f0SSteven Whitehouse  * Returns: The hash table or an error
33217d539f0SSteven Whitehouse  */
33317d539f0SSteven Whitehouse 
gfs2_dir_get_hash_table(struct gfs2_inode * ip)33417d539f0SSteven Whitehouse static __be64 *gfs2_dir_get_hash_table(struct gfs2_inode *ip)
33517d539f0SSteven Whitehouse {
33617d539f0SSteven Whitehouse 	struct inode *inode = &ip->i_inode;
33717d539f0SSteven Whitehouse 	int ret;
33817d539f0SSteven Whitehouse 	u32 hsize;
33917d539f0SSteven Whitehouse 	__be64 *hc;
34017d539f0SSteven Whitehouse 
34117d539f0SSteven Whitehouse 	BUG_ON(!(ip->i_diskflags & GFS2_DIF_EXHASH));
34217d539f0SSteven Whitehouse 
34317d539f0SSteven Whitehouse 	hc = ip->i_hash_cache;
34417d539f0SSteven Whitehouse 	if (hc)
34517d539f0SSteven Whitehouse 		return hc;
34617d539f0SSteven Whitehouse 
34747a9a527SFabian Frederick 	hsize = BIT(ip->i_depth);
34817d539f0SSteven Whitehouse 	hsize *= sizeof(__be64);
34917d539f0SSteven Whitehouse 	if (hsize != i_size_read(&ip->i_inode)) {
35017d539f0SSteven Whitehouse 		gfs2_consist_inode(ip);
35117d539f0SSteven Whitehouse 		return ERR_PTR(-EIO);
35217d539f0SSteven Whitehouse 	}
35317d539f0SSteven Whitehouse 
354e8830d88SBob Peterson 	hc = kmalloc(hsize, GFP_NOFS | __GFP_NOWARN);
355e8830d88SBob Peterson 	if (hc == NULL)
35688dca4caSChristoph Hellwig 		hc = __vmalloc(hsize, GFP_NOFS);
357e8830d88SBob Peterson 
35817d539f0SSteven Whitehouse 	if (hc == NULL)
35917d539f0SSteven Whitehouse 		return ERR_PTR(-ENOMEM);
36017d539f0SSteven Whitehouse 
3614c28d338SSteven Whitehouse 	ret = gfs2_dir_read_data(ip, hc, hsize);
36217d539f0SSteven Whitehouse 	if (ret < 0) {
3633cdcf63eSAl Viro 		kvfree(hc);
36417d539f0SSteven Whitehouse 		return ERR_PTR(ret);
36517d539f0SSteven Whitehouse 	}
36617d539f0SSteven Whitehouse 
36717d539f0SSteven Whitehouse 	spin_lock(&inode->i_lock);
3689265f1d0SAl Viro 	if (likely(!ip->i_hash_cache)) {
36917d539f0SSteven Whitehouse 		ip->i_hash_cache = hc;
3709265f1d0SAl Viro 		hc = NULL;
3719265f1d0SAl Viro 	}
37217d539f0SSteven Whitehouse 	spin_unlock(&inode->i_lock);
3739265f1d0SAl Viro 	kvfree(hc);
37417d539f0SSteven Whitehouse 
37517d539f0SSteven Whitehouse 	return ip->i_hash_cache;
37617d539f0SSteven Whitehouse }
37717d539f0SSteven Whitehouse 
37817d539f0SSteven Whitehouse /**
37917d539f0SSteven Whitehouse  * gfs2_dir_hash_inval - Invalidate dir hash
38017d539f0SSteven Whitehouse  * @ip: The directory inode
38117d539f0SSteven Whitehouse  *
38217d539f0SSteven Whitehouse  * Must be called with an exclusive glock, or during glock invalidation.
38317d539f0SSteven Whitehouse  */
gfs2_dir_hash_inval(struct gfs2_inode * ip)38417d539f0SSteven Whitehouse void gfs2_dir_hash_inval(struct gfs2_inode *ip)
38517d539f0SSteven Whitehouse {
386c36b97e9SBob Peterson 	__be64 *hc;
387c36b97e9SBob Peterson 
388c36b97e9SBob Peterson 	spin_lock(&ip->i_inode.i_lock);
389c36b97e9SBob Peterson 	hc = ip->i_hash_cache;
39017d539f0SSteven Whitehouse 	ip->i_hash_cache = NULL;
391c36b97e9SBob Peterson 	spin_unlock(&ip->i_inode.i_lock);
392c36b97e9SBob Peterson 
3933cdcf63eSAl Viro 	kvfree(hc);
39417d539f0SSteven Whitehouse }
39517d539f0SSteven Whitehouse 
gfs2_dirent_sentinel(const struct gfs2_dirent * dent)3965e7d65cdSSteven Whitehouse static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent)
3975e7d65cdSSteven Whitehouse {
3985e7d65cdSSteven Whitehouse 	return dent->de_inum.no_addr == 0 || dent->de_inum.no_formal_ino == 0;
3995e7d65cdSSteven Whitehouse }
4005e7d65cdSSteven Whitehouse 
__gfs2_dirent_find(const struct gfs2_dirent * dent,const struct qstr * name,int ret)401c752666cSSteven Whitehouse static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent,
402c752666cSSteven Whitehouse 				     const struct qstr *name, int ret)
403b3b94faaSDavid Teigland {
4045e7d65cdSSteven Whitehouse 	if (!gfs2_dirent_sentinel(dent) &&
405c752666cSSteven Whitehouse 	    be32_to_cpu(dent->de_hash) == name->hash &&
406c752666cSSteven Whitehouse 	    be16_to_cpu(dent->de_name_len) == name->len &&
4072bdbc5d7SSteven Whitehouse 	    memcmp(dent+1, name->name, name->len) == 0)
408c752666cSSteven Whitehouse 		return ret;
409b3b94faaSDavid Teigland 	return 0;
410b3b94faaSDavid Teigland }
411b3b94faaSDavid Teigland 
gfs2_dirent_find(const struct gfs2_dirent * dent,const struct qstr * name,void * opaque)412c752666cSSteven Whitehouse static int gfs2_dirent_find(const struct gfs2_dirent *dent,
41371b86f56SSteven Whitehouse 			    const struct qstr *name,
41471b86f56SSteven Whitehouse 			    void *opaque)
415c752666cSSteven Whitehouse {
416c752666cSSteven Whitehouse 	return __gfs2_dirent_find(dent, name, 1);
417c752666cSSteven Whitehouse }
418c752666cSSteven Whitehouse 
gfs2_dirent_prev(const struct gfs2_dirent * dent,const struct qstr * name,void * opaque)419c752666cSSteven Whitehouse static int gfs2_dirent_prev(const struct gfs2_dirent *dent,
42071b86f56SSteven Whitehouse 			    const struct qstr *name,
42171b86f56SSteven Whitehouse 			    void *opaque)
422c752666cSSteven Whitehouse {
423c752666cSSteven Whitehouse 	return __gfs2_dirent_find(dent, name, 2);
424c752666cSSteven Whitehouse }
425c752666cSSteven Whitehouse 
426c752666cSSteven Whitehouse /*
427c752666cSSteven Whitehouse  * name->name holds ptr to start of block.
428c752666cSSteven Whitehouse  * name->len holds size of block.
429c752666cSSteven Whitehouse  */
gfs2_dirent_last(const struct gfs2_dirent * dent,const struct qstr * name,void * opaque)430c752666cSSteven Whitehouse static int gfs2_dirent_last(const struct gfs2_dirent *dent,
43171b86f56SSteven Whitehouse 			    const struct qstr *name,
43271b86f56SSteven Whitehouse 			    void *opaque)
433c752666cSSteven Whitehouse {
434c752666cSSteven Whitehouse 	const char *start = name->name;
435c752666cSSteven Whitehouse 	const char *end = (const char *)dent + be16_to_cpu(dent->de_rec_len);
436c752666cSSteven Whitehouse 	if (name->len == (end - start))
437c752666cSSteven Whitehouse 		return 1;
438c752666cSSteven Whitehouse 	return 0;
439c752666cSSteven Whitehouse }
440c752666cSSteven Whitehouse 
44134017472SBenjamin Marzinski /* Look for the dirent that contains the offset specified in data. Once we
44234017472SBenjamin Marzinski  * find that dirent, there must be space available there for the new dirent */
gfs2_dirent_find_offset(const struct gfs2_dirent * dent,const struct qstr * name,void * ptr)44334017472SBenjamin Marzinski static int gfs2_dirent_find_offset(const struct gfs2_dirent *dent,
44434017472SBenjamin Marzinski 				  const struct qstr *name,
44534017472SBenjamin Marzinski 				  void *ptr)
44634017472SBenjamin Marzinski {
44734017472SBenjamin Marzinski 	unsigned required = GFS2_DIRENT_SIZE(name->len);
44834017472SBenjamin Marzinski 	unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len));
44934017472SBenjamin Marzinski 	unsigned totlen = be16_to_cpu(dent->de_rec_len);
45034017472SBenjamin Marzinski 
45134017472SBenjamin Marzinski 	if (ptr < (void *)dent || ptr >= (void *)dent + totlen)
45234017472SBenjamin Marzinski 		return 0;
45334017472SBenjamin Marzinski 	if (gfs2_dirent_sentinel(dent))
45434017472SBenjamin Marzinski 		actual = 0;
45534017472SBenjamin Marzinski 	if (ptr < (void *)dent + actual)
45634017472SBenjamin Marzinski 		return -1;
45734017472SBenjamin Marzinski 	if ((void *)dent + totlen >= ptr + required)
45834017472SBenjamin Marzinski 		return 1;
45934017472SBenjamin Marzinski 	return -1;
46034017472SBenjamin Marzinski }
46134017472SBenjamin Marzinski 
gfs2_dirent_find_space(const struct gfs2_dirent * dent,const struct qstr * name,void * opaque)462c752666cSSteven Whitehouse static int gfs2_dirent_find_space(const struct gfs2_dirent *dent,
46371b86f56SSteven Whitehouse 				  const struct qstr *name,
46471b86f56SSteven Whitehouse 				  void *opaque)
465c752666cSSteven Whitehouse {
466c752666cSSteven Whitehouse 	unsigned required = GFS2_DIRENT_SIZE(name->len);
467c752666cSSteven Whitehouse 	unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len));
468c752666cSSteven Whitehouse 	unsigned totlen = be16_to_cpu(dent->de_rec_len);
469c752666cSSteven Whitehouse 
4705e7d65cdSSteven Whitehouse 	if (gfs2_dirent_sentinel(dent))
471728a756bSBob Peterson 		actual = 0;
472c5392124SJan Engelhardt 	if (totlen - actual >= required)
473c752666cSSteven Whitehouse 		return 1;
474c752666cSSteven Whitehouse 	return 0;
475c752666cSSteven Whitehouse }
476c752666cSSteven Whitehouse 
47771b86f56SSteven Whitehouse struct dirent_gather {
47871b86f56SSteven Whitehouse 	const struct gfs2_dirent **pdent;
47971b86f56SSteven Whitehouse 	unsigned offset;
48071b86f56SSteven Whitehouse };
48171b86f56SSteven Whitehouse 
gfs2_dirent_gather(const struct gfs2_dirent * dent,const struct qstr * name,void * opaque)48271b86f56SSteven Whitehouse static int gfs2_dirent_gather(const struct gfs2_dirent *dent,
48371b86f56SSteven Whitehouse 			      const struct qstr *name,
48471b86f56SSteven Whitehouse 			      void *opaque)
48571b86f56SSteven Whitehouse {
48671b86f56SSteven Whitehouse 	struct dirent_gather *g = opaque;
4875e7d65cdSSteven Whitehouse 	if (!gfs2_dirent_sentinel(dent)) {
48871b86f56SSteven Whitehouse 		g->pdent[g->offset++] = dent;
48971b86f56SSteven Whitehouse 	}
49071b86f56SSteven Whitehouse 	return 0;
49171b86f56SSteven Whitehouse }
49271b86f56SSteven Whitehouse 
493c752666cSSteven Whitehouse /*
494c752666cSSteven Whitehouse  * Other possible things to check:
495c752666cSSteven Whitehouse  * - Inode located within filesystem size (and on valid block)
496c752666cSSteven Whitehouse  * - Valid directory entry type
497c752666cSSteven Whitehouse  * Not sure how heavy-weight we want to make this... could also check
498c752666cSSteven Whitehouse  * hash is correct for example, but that would take a lot of extra time.
499c752666cSSteven Whitehouse  * For now the most important thing is to check that the various sizes
500c752666cSSteven Whitehouse  * are correct.
501c752666cSSteven Whitehouse  */
gfs2_check_dirent(struct gfs2_sbd * sdp,struct gfs2_dirent * dent,unsigned int offset,unsigned int size,unsigned int len,int first)502e54c78a2SBob Peterson static int gfs2_check_dirent(struct gfs2_sbd *sdp,
503e54c78a2SBob Peterson 			     struct gfs2_dirent *dent, unsigned int offset,
504c752666cSSteven Whitehouse 			     unsigned int size, unsigned int len, int first)
505c752666cSSteven Whitehouse {
506c752666cSSteven Whitehouse 	const char *msg = "gfs2_dirent too small";
507c752666cSSteven Whitehouse 	if (unlikely(size < sizeof(struct gfs2_dirent)))
508c752666cSSteven Whitehouse 		goto error;
509c752666cSSteven Whitehouse 	msg = "gfs2_dirent misaligned";
510c752666cSSteven Whitehouse 	if (unlikely(offset & 0x7))
511c752666cSSteven Whitehouse 		goto error;
512c752666cSSteven Whitehouse 	msg = "gfs2_dirent points beyond end of block";
513c752666cSSteven Whitehouse 	if (unlikely(offset + size > len))
514c752666cSSteven Whitehouse 		goto error;
515c752666cSSteven Whitehouse 	msg = "zero inode number";
5165e7d65cdSSteven Whitehouse 	if (unlikely(!first && gfs2_dirent_sentinel(dent)))
517c752666cSSteven Whitehouse 		goto error;
518c752666cSSteven Whitehouse 	msg = "name length is greater than space in dirent";
5195e7d65cdSSteven Whitehouse 	if (!gfs2_dirent_sentinel(dent) &&
520c752666cSSteven Whitehouse 	    unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) >
521c752666cSSteven Whitehouse 		     size))
522c752666cSSteven Whitehouse 		goto error;
523c752666cSSteven Whitehouse 	return 0;
524c752666cSSteven Whitehouse error:
525e54c78a2SBob Peterson 	fs_warn(sdp, "%s: %s (%s)\n",
526d77d1b58SJoe Perches 		__func__, msg, first ? "first in block" : "not first in block");
527c752666cSSteven Whitehouse 	return -EIO;
528c752666cSSteven Whitehouse }
529c752666cSSteven Whitehouse 
gfs2_dirent_offset(struct gfs2_sbd * sdp,const void * buf)530e54c78a2SBob Peterson static int gfs2_dirent_offset(struct gfs2_sbd *sdp, const void *buf)
531c752666cSSteven Whitehouse {
53271b86f56SSteven Whitehouse 	const struct gfs2_meta_header *h = buf;
53371b86f56SSteven Whitehouse 	int offset;
534c752666cSSteven Whitehouse 
535c752666cSSteven Whitehouse 	BUG_ON(buf == NULL);
536c752666cSSteven Whitehouse 
537e3167dedSSteven Whitehouse 	switch(be32_to_cpu(h->mh_type)) {
538c752666cSSteven Whitehouse 	case GFS2_METATYPE_LF:
539c752666cSSteven Whitehouse 		offset = sizeof(struct gfs2_leaf);
540c752666cSSteven Whitehouse 		break;
541c752666cSSteven Whitehouse 	case GFS2_METATYPE_DI:
542c752666cSSteven Whitehouse 		offset = sizeof(struct gfs2_dinode);
543c752666cSSteven Whitehouse 		break;
544c752666cSSteven Whitehouse 	default:
545c752666cSSteven Whitehouse 		goto wrong_type;
546c752666cSSteven Whitehouse 	}
54771b86f56SSteven Whitehouse 	return offset;
54871b86f56SSteven Whitehouse wrong_type:
549e54c78a2SBob Peterson 	fs_warn(sdp, "%s: wrong block type %u\n", __func__,
550e54c78a2SBob Peterson 		be32_to_cpu(h->mh_type));
55171b86f56SSteven Whitehouse 	return -1;
55271b86f56SSteven Whitehouse }
553c752666cSSteven Whitehouse 
gfs2_dirent_scan(struct inode * inode,void * buf,unsigned int len,gfs2_dscan_t scan,const struct qstr * name,void * opaque)5542bdbc5d7SSteven Whitehouse static struct gfs2_dirent *gfs2_dirent_scan(struct inode *inode, void *buf,
55571b86f56SSteven Whitehouse 					    unsigned int len, gfs2_dscan_t scan,
55671b86f56SSteven Whitehouse 					    const struct qstr *name,
55771b86f56SSteven Whitehouse 					    void *opaque)
55871b86f56SSteven Whitehouse {
55971b86f56SSteven Whitehouse 	struct gfs2_dirent *dent, *prev;
56071b86f56SSteven Whitehouse 	unsigned offset;
56171b86f56SSteven Whitehouse 	unsigned size;
56271b86f56SSteven Whitehouse 	int ret = 0;
56371b86f56SSteven Whitehouse 
564e54c78a2SBob Peterson 	ret = gfs2_dirent_offset(GFS2_SB(inode), buf);
56571b86f56SSteven Whitehouse 	if (ret < 0)
56671b86f56SSteven Whitehouse 		goto consist_inode;
56771b86f56SSteven Whitehouse 
56871b86f56SSteven Whitehouse 	offset = ret;
569c752666cSSteven Whitehouse 	prev = NULL;
5702bdbc5d7SSteven Whitehouse 	dent = buf + offset;
571c752666cSSteven Whitehouse 	size = be16_to_cpu(dent->de_rec_len);
572e54c78a2SBob Peterson 	if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size, len, 1))
573c752666cSSteven Whitehouse 		goto consist_inode;
574c752666cSSteven Whitehouse 	do {
57571b86f56SSteven Whitehouse 		ret = scan(dent, name, opaque);
576c752666cSSteven Whitehouse 		if (ret)
577c752666cSSteven Whitehouse 			break;
578c752666cSSteven Whitehouse 		offset += size;
579c752666cSSteven Whitehouse 		if (offset == len)
580c752666cSSteven Whitehouse 			break;
581c752666cSSteven Whitehouse 		prev = dent;
5822bdbc5d7SSteven Whitehouse 		dent = buf + offset;
583c752666cSSteven Whitehouse 		size = be16_to_cpu(dent->de_rec_len);
584e54c78a2SBob Peterson 		if (gfs2_check_dirent(GFS2_SB(inode), dent, offset, size,
585e54c78a2SBob Peterson 				      len, 0))
586c752666cSSteven Whitehouse 			goto consist_inode;
587c752666cSSteven Whitehouse 	} while(1);
588c752666cSSteven Whitehouse 
589c752666cSSteven Whitehouse 	switch(ret) {
590c752666cSSteven Whitehouse 	case 0:
591c752666cSSteven Whitehouse 		return NULL;
592c752666cSSteven Whitehouse 	case 1:
593c752666cSSteven Whitehouse 		return dent;
594c752666cSSteven Whitehouse 	case 2:
595c752666cSSteven Whitehouse 		return prev ? prev : dent;
596c752666cSSteven Whitehouse 	default:
597c752666cSSteven Whitehouse 		BUG_ON(ret > 0);
598c752666cSSteven Whitehouse 		return ERR_PTR(ret);
599c752666cSSteven Whitehouse 	}
600c752666cSSteven Whitehouse 
601c752666cSSteven Whitehouse consist_inode:
602feaa7bbaSSteven Whitehouse 	gfs2_consist_inode(GFS2_I(inode));
603c752666cSSteven Whitehouse 	return ERR_PTR(-EIO);
604c752666cSSteven Whitehouse }
605c752666cSSteven Whitehouse 
dirent_check_reclen(struct gfs2_inode * dip,const struct gfs2_dirent * d,const void * end_p)6062bdbc5d7SSteven Whitehouse static int dirent_check_reclen(struct gfs2_inode *dip,
6072bdbc5d7SSteven Whitehouse 			       const struct gfs2_dirent *d, const void *end_p)
6082bdbc5d7SSteven Whitehouse {
6092bdbc5d7SSteven Whitehouse 	const void *ptr = d;
6102bdbc5d7SSteven Whitehouse 	u16 rec_len = be16_to_cpu(d->de_rec_len);
6112bdbc5d7SSteven Whitehouse 
6122bdbc5d7SSteven Whitehouse 	if (unlikely(rec_len < sizeof(struct gfs2_dirent)))
6132bdbc5d7SSteven Whitehouse 		goto broken;
6142bdbc5d7SSteven Whitehouse 	ptr += rec_len;
6152bdbc5d7SSteven Whitehouse 	if (ptr < end_p)
6162bdbc5d7SSteven Whitehouse 		return rec_len;
6172bdbc5d7SSteven Whitehouse 	if (ptr == end_p)
6182bdbc5d7SSteven Whitehouse 		return -ENOENT;
6192bdbc5d7SSteven Whitehouse broken:
6202bdbc5d7SSteven Whitehouse 	gfs2_consist_inode(dip);
6212bdbc5d7SSteven Whitehouse 	return -EIO;
6222bdbc5d7SSteven Whitehouse }
6232bdbc5d7SSteven Whitehouse 
624b3b94faaSDavid Teigland /**
625b3b94faaSDavid Teigland  * dirent_next - Next dirent
626b3b94faaSDavid Teigland  * @dip: the directory
627b3b94faaSDavid Teigland  * @bh: The buffer
628b3b94faaSDavid Teigland  * @dent: Pointer to list of dirents
629b3b94faaSDavid Teigland  *
630b3b94faaSDavid Teigland  * Returns: 0 on success, error code otherwise
631b3b94faaSDavid Teigland  */
632b3b94faaSDavid Teigland 
dirent_next(struct gfs2_inode * dip,struct buffer_head * bh,struct gfs2_dirent ** dent)633b3b94faaSDavid Teigland static int dirent_next(struct gfs2_inode *dip, struct buffer_head *bh,
634b3b94faaSDavid Teigland 		       struct gfs2_dirent **dent)
635b3b94faaSDavid Teigland {
6362bdbc5d7SSteven Whitehouse 	struct gfs2_dirent *cur = *dent, *tmp;
6372bdbc5d7SSteven Whitehouse 	char *bh_end = bh->b_data + bh->b_size;
6382bdbc5d7SSteven Whitehouse 	int ret;
639b3b94faaSDavid Teigland 
6402bdbc5d7SSteven Whitehouse 	ret = dirent_check_reclen(dip, cur, bh_end);
6412bdbc5d7SSteven Whitehouse 	if (ret < 0)
6422bdbc5d7SSteven Whitehouse 		return ret;
643b3b94faaSDavid Teigland 
6442bdbc5d7SSteven Whitehouse 	tmp = (void *)cur + ret;
6452bdbc5d7SSteven Whitehouse 	ret = dirent_check_reclen(dip, tmp, bh_end);
6462bdbc5d7SSteven Whitehouse 	if (ret == -EIO)
6472bdbc5d7SSteven Whitehouse 		return ret;
6484dd651adSSteven Whitehouse 
649b3b94faaSDavid Teigland         /* Only the first dent could ever have de_inum.no_addr == 0 */
6505e7d65cdSSteven Whitehouse 	if (gfs2_dirent_sentinel(tmp)) {
651b3b94faaSDavid Teigland 		gfs2_consist_inode(dip);
652b3b94faaSDavid Teigland 		return -EIO;
653b3b94faaSDavid Teigland 	}
654b3b94faaSDavid Teigland 
655b3b94faaSDavid Teigland 	*dent = tmp;
656b3b94faaSDavid Teigland 	return 0;
657b3b94faaSDavid Teigland }
658b3b94faaSDavid Teigland 
659b3b94faaSDavid Teigland /**
660b3b94faaSDavid Teigland  * dirent_del - Delete a dirent
661b3b94faaSDavid Teigland  * @dip: The GFS2 inode
662b3b94faaSDavid Teigland  * @bh: The buffer
663b3b94faaSDavid Teigland  * @prev: The previous dirent
664b3b94faaSDavid Teigland  * @cur: The current dirent
665b3b94faaSDavid Teigland  *
666b3b94faaSDavid Teigland  */
667b3b94faaSDavid Teigland 
dirent_del(struct gfs2_inode * dip,struct buffer_head * bh,struct gfs2_dirent * prev,struct gfs2_dirent * cur)668b3b94faaSDavid Teigland static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh,
669b3b94faaSDavid Teigland 		       struct gfs2_dirent *prev, struct gfs2_dirent *cur)
670b3b94faaSDavid Teigland {
671cd915493SSteven Whitehouse 	u16 cur_rec_len, prev_rec_len;
672b3b94faaSDavid Teigland 
6735e7d65cdSSteven Whitehouse 	if (gfs2_dirent_sentinel(cur)) {
674b3b94faaSDavid Teigland 		gfs2_consist_inode(dip);
675b3b94faaSDavid Teigland 		return;
676b3b94faaSDavid Teigland 	}
677b3b94faaSDavid Teigland 
678350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(dip->i_gl, bh);
679b3b94faaSDavid Teigland 
680b3b94faaSDavid Teigland 	/* If there is no prev entry, this is the first entry in the block.
681b3b94faaSDavid Teigland 	   The de_rec_len is already as big as it needs to be.  Just zero
682b3b94faaSDavid Teigland 	   out the inode number and return.  */
683b3b94faaSDavid Teigland 
684b3b94faaSDavid Teigland 	if (!prev) {
6855e7d65cdSSteven Whitehouse 		cur->de_inum.no_addr = 0;
6865e7d65cdSSteven Whitehouse 		cur->de_inum.no_formal_ino = 0;
687b3b94faaSDavid Teigland 		return;
688b3b94faaSDavid Teigland 	}
689b3b94faaSDavid Teigland 
690b3b94faaSDavid Teigland 	/*  Combine this dentry with the previous one.  */
691b3b94faaSDavid Teigland 
692fc69d0d3SSteven Whitehouse 	prev_rec_len = be16_to_cpu(prev->de_rec_len);
693fc69d0d3SSteven Whitehouse 	cur_rec_len = be16_to_cpu(cur->de_rec_len);
694b3b94faaSDavid Teigland 
695b3b94faaSDavid Teigland 	if ((char *)prev + prev_rec_len != (char *)cur)
696b3b94faaSDavid Teigland 		gfs2_consist_inode(dip);
697b3b94faaSDavid Teigland 	if ((char *)cur + cur_rec_len > bh->b_data + bh->b_size)
698b3b94faaSDavid Teigland 		gfs2_consist_inode(dip);
699b3b94faaSDavid Teigland 
700b3b94faaSDavid Teigland 	prev_rec_len += cur_rec_len;
701fc69d0d3SSteven Whitehouse 	prev->de_rec_len = cpu_to_be16(prev_rec_len);
702b3b94faaSDavid Teigland }
703b3b94faaSDavid Teigland 
70434017472SBenjamin Marzinski 
do_init_dirent(struct inode * inode,struct gfs2_dirent * dent,const struct qstr * name,struct buffer_head * bh,unsigned offset)70534017472SBenjamin Marzinski static struct gfs2_dirent *do_init_dirent(struct inode *inode,
706c752666cSSteven Whitehouse 					  struct gfs2_dirent *dent,
707c752666cSSteven Whitehouse 					  const struct qstr *name,
70834017472SBenjamin Marzinski 					  struct buffer_head *bh,
70934017472SBenjamin Marzinski 					  unsigned offset)
710b3b94faaSDavid Teigland {
711feaa7bbaSSteven Whitehouse 	struct gfs2_inode *ip = GFS2_I(inode);
712c752666cSSteven Whitehouse 	struct gfs2_dirent *ndent;
71334017472SBenjamin Marzinski 	unsigned totlen;
714b3b94faaSDavid Teigland 
715c752666cSSteven Whitehouse 	totlen = be16_to_cpu(dent->de_rec_len);
716c752666cSSteven Whitehouse 	BUG_ON(offset + name->len > totlen);
717350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(ip->i_gl, bh);
718c752666cSSteven Whitehouse 	ndent = (struct gfs2_dirent *)((char *)dent + offset);
719c752666cSSteven Whitehouse 	dent->de_rec_len = cpu_to_be16(offset);
720c752666cSSteven Whitehouse 	gfs2_qstr2dirent(name, totlen - offset, ndent);
721c752666cSSteven Whitehouse 	return ndent;
722b3b94faaSDavid Teigland }
723b3b94faaSDavid Teigland 
72434017472SBenjamin Marzinski 
72534017472SBenjamin Marzinski /*
72634017472SBenjamin Marzinski  * Takes a dent from which to grab space as an argument. Returns the
72734017472SBenjamin Marzinski  * newly created dent.
72834017472SBenjamin Marzinski  */
gfs2_init_dirent(struct inode * inode,struct gfs2_dirent * dent,const struct qstr * name,struct buffer_head * bh)72934017472SBenjamin Marzinski static struct gfs2_dirent *gfs2_init_dirent(struct inode *inode,
73034017472SBenjamin Marzinski 					    struct gfs2_dirent *dent,
73134017472SBenjamin Marzinski 					    const struct qstr *name,
73234017472SBenjamin Marzinski 					    struct buffer_head *bh)
73334017472SBenjamin Marzinski {
73434017472SBenjamin Marzinski 	unsigned offset = 0;
73534017472SBenjamin Marzinski 
73634017472SBenjamin Marzinski 	if (!gfs2_dirent_sentinel(dent))
73734017472SBenjamin Marzinski 		offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len));
73834017472SBenjamin Marzinski 	return do_init_dirent(inode, dent, name, bh, offset);
73934017472SBenjamin Marzinski }
74034017472SBenjamin Marzinski 
gfs2_dirent_split_alloc(struct inode * inode,struct buffer_head * bh,const struct qstr * name,void * ptr)74134017472SBenjamin Marzinski static struct gfs2_dirent *gfs2_dirent_split_alloc(struct inode *inode,
742c752666cSSteven Whitehouse 						   struct buffer_head *bh,
74334017472SBenjamin Marzinski 						   const struct qstr *name,
74434017472SBenjamin Marzinski 						   void *ptr)
745b3b94faaSDavid Teigland {
746b3b94faaSDavid Teigland 	struct gfs2_dirent *dent;
74771b86f56SSteven Whitehouse 	dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size,
74834017472SBenjamin Marzinski 				gfs2_dirent_find_offset, name, ptr);
74915a798f7SKefeng Wang 	if (IS_ERR_OR_NULL(dent))
750c752666cSSteven Whitehouse 		return dent;
75134017472SBenjamin Marzinski 	return do_init_dirent(inode, dent, name, bh,
75234017472SBenjamin Marzinski 			      (unsigned)(ptr - (void *)dent));
753b3b94faaSDavid Teigland }
754b3b94faaSDavid Teigland 
get_leaf(struct gfs2_inode * dip,u64 leaf_no,struct buffer_head ** bhp)755cd915493SSteven Whitehouse static int get_leaf(struct gfs2_inode *dip, u64 leaf_no,
756b3b94faaSDavid Teigland 		    struct buffer_head **bhp)
757b3b94faaSDavid Teigland {
758b3b94faaSDavid Teigland 	int error;
759b3b94faaSDavid Teigland 
760c8d57703SAndreas Gruenbacher 	error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_WAIT, 0, bhp);
761feaa7bbaSSteven Whitehouse 	if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) {
762d77d1b58SJoe Perches 		/* pr_info("block num=%llu\n", leaf_no); */
763b3b94faaSDavid Teigland 		error = -EIO;
764feaa7bbaSSteven Whitehouse 	}
765b3b94faaSDavid Teigland 
766b3b94faaSDavid Teigland 	return error;
767b3b94faaSDavid Teigland }
768b3b94faaSDavid Teigland 
769b3b94faaSDavid Teigland /**
770b3b94faaSDavid Teigland  * get_leaf_nr - Get a leaf number associated with the index
771b3b94faaSDavid Teigland  * @dip: The GFS2 inode
7723ae3a7d6SBob Peterson  * @index: hash table index of the targeted leaf
7733ae3a7d6SBob Peterson  * @leaf_out: Resulting leaf block number
774b3b94faaSDavid Teigland  *
775b3b94faaSDavid Teigland  * Returns: 0 on success, error code otherwise
776b3b94faaSDavid Teigland  */
777b3b94faaSDavid Teigland 
get_leaf_nr(struct gfs2_inode * dip,u32 index,u64 * leaf_out)7783ae3a7d6SBob Peterson static int get_leaf_nr(struct gfs2_inode *dip, u32 index, u64 *leaf_out)
779b3b94faaSDavid Teigland {
78017d539f0SSteven Whitehouse 	__be64 *hash;
781287980e4SArnd Bergmann 	int error;
782b3b94faaSDavid Teigland 
78317d539f0SSteven Whitehouse 	hash = gfs2_dir_get_hash_table(dip);
784287980e4SArnd Bergmann 	error = PTR_ERR_OR_ZERO(hash);
785287980e4SArnd Bergmann 
786287980e4SArnd Bergmann 	if (!error)
78717d539f0SSteven Whitehouse 		*leaf_out = be64_to_cpu(*(hash + index));
788287980e4SArnd Bergmann 
789287980e4SArnd Bergmann 	return error;
790b3b94faaSDavid Teigland }
791b3b94faaSDavid Teigland 
get_first_leaf(struct gfs2_inode * dip,u32 index,struct buffer_head ** bh_out)792cd915493SSteven Whitehouse static int get_first_leaf(struct gfs2_inode *dip, u32 index,
793b3b94faaSDavid Teigland 			  struct buffer_head **bh_out)
794b3b94faaSDavid Teigland {
795cd915493SSteven Whitehouse 	u64 leaf_no;
796b3b94faaSDavid Teigland 	int error;
797b3b94faaSDavid Teigland 
798b3b94faaSDavid Teigland 	error = get_leaf_nr(dip, index, &leaf_no);
799287980e4SArnd Bergmann 	if (!error)
800b3b94faaSDavid Teigland 		error = get_leaf(dip, leaf_no, bh_out);
801b3b94faaSDavid Teigland 
802b3b94faaSDavid Teigland 	return error;
803b3b94faaSDavid Teigland }
804b3b94faaSDavid Teigland 
gfs2_dirent_search(struct inode * inode,const struct qstr * name,gfs2_dscan_t scan,struct buffer_head ** pbh)805c752666cSSteven Whitehouse static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
806c752666cSSteven Whitehouse 					      const struct qstr *name,
807c752666cSSteven Whitehouse 					      gfs2_dscan_t scan,
808c752666cSSteven Whitehouse 					      struct buffer_head **pbh)
809b3b94faaSDavid Teigland {
810c752666cSSteven Whitehouse 	struct buffer_head *bh;
811c752666cSSteven Whitehouse 	struct gfs2_dirent *dent;
812feaa7bbaSSteven Whitehouse 	struct gfs2_inode *ip = GFS2_I(inode);
813c752666cSSteven Whitehouse 	int error;
814c752666cSSteven Whitehouse 
815383f01fbSSteven Whitehouse 	if (ip->i_diskflags & GFS2_DIF_EXHASH) {
816b3b94faaSDavid Teigland 		struct gfs2_leaf *leaf;
81747a9a527SFabian Frederick 		unsigned int hsize = BIT(ip->i_depth);
81847a9a527SFabian Frederick 		unsigned int index;
819c752666cSSteven Whitehouse 		u64 ln;
820a2e0f799SSteven Whitehouse 		if (hsize * sizeof(u64) != i_size_read(inode)) {
821c752666cSSteven Whitehouse 			gfs2_consist_inode(ip);
822c752666cSSteven Whitehouse 			return ERR_PTR(-EIO);
823b3b94faaSDavid Teigland 		}
824b3b94faaSDavid Teigland 
8259a004508SSteven Whitehouse 		index = name->hash >> (32 - ip->i_depth);
826c752666cSSteven Whitehouse 		error = get_first_leaf(ip, index, &bh);
827b3b94faaSDavid Teigland 		if (error)
828c752666cSSteven Whitehouse 			return ERR_PTR(error);
829b3b94faaSDavid Teigland 		do {
830c752666cSSteven Whitehouse 			dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size,
83171b86f56SSteven Whitehouse 						scan, name, NULL);
832c752666cSSteven Whitehouse 			if (dent)
833c752666cSSteven Whitehouse 				goto got_dent;
834c752666cSSteven Whitehouse 			leaf = (struct gfs2_leaf *)bh->b_data;
835c752666cSSteven Whitehouse 			ln = be64_to_cpu(leaf->lf_next);
836f4154ea0SSteven Whitehouse 			brelse(bh);
837c752666cSSteven Whitehouse 			if (!ln)
838b3b94faaSDavid Teigland 				break;
839feaa7bbaSSteven Whitehouse 
840c752666cSSteven Whitehouse 			error = get_leaf(ip, ln, &bh);
841c752666cSSteven Whitehouse 		} while(!error);
842b3b94faaSDavid Teigland 
843c752666cSSteven Whitehouse 		return error ? ERR_PTR(error) : NULL;
844b3b94faaSDavid Teigland 	}
845b3b94faaSDavid Teigland 
846feaa7bbaSSteven Whitehouse 
847c752666cSSteven Whitehouse 	error = gfs2_meta_inode_buffer(ip, &bh);
848c752666cSSteven Whitehouse 	if (error)
849c752666cSSteven Whitehouse 		return ERR_PTR(error);
85071b86f56SSteven Whitehouse 	dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, scan, name, NULL);
851c752666cSSteven Whitehouse got_dent:
85215a798f7SKefeng Wang 	if (IS_ERR_OR_NULL(dent)) {
853ed386507SSteven Whitehouse 		brelse(bh);
854ed386507SSteven Whitehouse 		bh = NULL;
855ed386507SSteven Whitehouse 	}
856c752666cSSteven Whitehouse 	*pbh = bh;
857c752666cSSteven Whitehouse 	return dent;
858b3b94faaSDavid Teigland }
859b3b94faaSDavid Teigland 
new_leaf(struct inode * inode,struct buffer_head ** pbh,u16 depth)860c752666cSSteven Whitehouse static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh, u16 depth)
861c752666cSSteven Whitehouse {
862feaa7bbaSSteven Whitehouse 	struct gfs2_inode *ip = GFS2_I(inode);
863b45e41d7SSteven Whitehouse 	unsigned int n = 1;
86409010978SSteven Whitehouse 	u64 bn;
86509010978SSteven Whitehouse 	int error;
86609010978SSteven Whitehouse 	struct buffer_head *bh;
867c752666cSSteven Whitehouse 	struct gfs2_leaf *leaf;
868c752666cSSteven Whitehouse 	struct gfs2_dirent *dent;
86995582b00SDeepa Dinamani 	struct timespec64 tv = current_time(inode);
87009010978SSteven Whitehouse 
871*d92445b2SAndreas Gruenbacher 	error = gfs2_alloc_blocks(ip, &bn, &n, 0);
87209010978SSteven Whitehouse 	if (error)
87309010978SSteven Whitehouse 		return NULL;
87409010978SSteven Whitehouse 	bh = gfs2_meta_new(ip->i_gl, bn);
875c752666cSSteven Whitehouse 	if (!bh)
876c752666cSSteven Whitehouse 		return NULL;
87709010978SSteven Whitehouse 
878fbb27873SAndreas Gruenbacher 	gfs2_trans_remove_revoke(GFS2_SB(inode), bn, 1);
879350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(ip->i_gl, bh);
880c752666cSSteven Whitehouse 	gfs2_metatype_set(bh, GFS2_METATYPE_LF, GFS2_FORMAT_LF);
881c752666cSSteven Whitehouse 	leaf = (struct gfs2_leaf *)bh->b_data;
882c752666cSSteven Whitehouse 	leaf->lf_depth = cpu_to_be16(depth);
8832bdbc5d7SSteven Whitehouse 	leaf->lf_entries = 0;
884a2d7d021SAl Viro 	leaf->lf_dirent_format = cpu_to_be32(GFS2_FORMAT_DE);
8852bdbc5d7SSteven Whitehouse 	leaf->lf_next = 0;
88601bcb0deSSteven Whitehouse 	leaf->lf_inode = cpu_to_be64(ip->i_no_addr);
88701bcb0deSSteven Whitehouse 	leaf->lf_dist = cpu_to_be32(1);
88801bcb0deSSteven Whitehouse 	leaf->lf_nsec = cpu_to_be32(tv.tv_nsec);
88901bcb0deSSteven Whitehouse 	leaf->lf_sec = cpu_to_be64(tv.tv_sec);
89001bcb0deSSteven Whitehouse 	memset(leaf->lf_reserved2, 0, sizeof(leaf->lf_reserved2));
891c752666cSSteven Whitehouse 	dent = (struct gfs2_dirent *)(leaf+1);
892cdf01226SDavid Howells 	gfs2_qstr2dirent(&empty_name, bh->b_size - sizeof(struct gfs2_leaf), dent);
893c752666cSSteven Whitehouse 	*pbh = bh;
894c752666cSSteven Whitehouse 	return leaf;
895b3b94faaSDavid Teigland }
896b3b94faaSDavid Teigland 
897b3b94faaSDavid Teigland /**
898b3b94faaSDavid Teigland  * dir_make_exhash - Convert a stuffed directory into an ExHash directory
8993ae3a7d6SBob Peterson  * @inode: The directory inode to be converted to exhash
900b3b94faaSDavid Teigland  *
901b3b94faaSDavid Teigland  * Returns: 0 on success, error code otherwise
902b3b94faaSDavid Teigland  */
903b3b94faaSDavid Teigland 
dir_make_exhash(struct inode * inode)904c752666cSSteven Whitehouse static int dir_make_exhash(struct inode *inode)
905b3b94faaSDavid Teigland {
906feaa7bbaSSteven Whitehouse 	struct gfs2_inode *dip = GFS2_I(inode);
907feaa7bbaSSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(inode);
908b3b94faaSDavid Teigland 	struct gfs2_dirent *dent;
909c752666cSSteven Whitehouse 	struct qstr args;
910b3b94faaSDavid Teigland 	struct buffer_head *bh, *dibh;
911b3b94faaSDavid Teigland 	struct gfs2_leaf *leaf;
912b3b94faaSDavid Teigland 	int y;
913cd915493SSteven Whitehouse 	u32 x;
914b44b84d7SAl Viro 	__be64 *lp;
915b44b84d7SAl Viro 	u64 bn;
916b3b94faaSDavid Teigland 	int error;
917b3b94faaSDavid Teigland 
918b3b94faaSDavid Teigland 	error = gfs2_meta_inode_buffer(dip, &dibh);
919b3b94faaSDavid Teigland 	if (error)
920b3b94faaSDavid Teigland 		return error;
921b3b94faaSDavid Teigland 
922b3b94faaSDavid Teigland 	/*  Turn over a new leaf  */
923b3b94faaSDavid Teigland 
924c752666cSSteven Whitehouse 	leaf = new_leaf(inode, &bh, 0);
925c752666cSSteven Whitehouse 	if (!leaf)
926c752666cSSteven Whitehouse 		return -ENOSPC;
927c752666cSSteven Whitehouse 	bn = bh->b_blocknr;
928b3b94faaSDavid Teigland 
92947a9a527SFabian Frederick 	gfs2_assert(sdp, dip->i_entries < BIT(16));
930ad6203f2SSteven Whitehouse 	leaf->lf_entries = cpu_to_be16(dip->i_entries);
931b3b94faaSDavid Teigland 
932b3b94faaSDavid Teigland 	/*  Copy dirents  */
933b3b94faaSDavid Teigland 
934b3b94faaSDavid Teigland 	gfs2_buffer_copy_tail(bh, sizeof(struct gfs2_leaf), dibh,
935b3b94faaSDavid Teigland 			     sizeof(struct gfs2_dinode));
936b3b94faaSDavid Teigland 
937b3b94faaSDavid Teigland 	/*  Find last entry  */
938b3b94faaSDavid Teigland 
939b3b94faaSDavid Teigland 	x = 0;
940c752666cSSteven Whitehouse 	args.len = bh->b_size - sizeof(struct gfs2_dinode) +
941c752666cSSteven Whitehouse 		   sizeof(struct gfs2_leaf);
942c752666cSSteven Whitehouse 	args.name = bh->b_data;
943feaa7bbaSSteven Whitehouse 	dent = gfs2_dirent_scan(&dip->i_inode, bh->b_data, bh->b_size,
94471b86f56SSteven Whitehouse 				gfs2_dirent_last, &args, NULL);
945c752666cSSteven Whitehouse 	if (!dent) {
946c752666cSSteven Whitehouse 		brelse(bh);
947c752666cSSteven Whitehouse 		brelse(dibh);
948c752666cSSteven Whitehouse 		return -EIO;
949b3b94faaSDavid Teigland 	}
950c752666cSSteven Whitehouse 	if (IS_ERR(dent)) {
951c752666cSSteven Whitehouse 		brelse(bh);
952c752666cSSteven Whitehouse 		brelse(dibh);
953c752666cSSteven Whitehouse 		return PTR_ERR(dent);
954c752666cSSteven Whitehouse 	}
955b3b94faaSDavid Teigland 
956b3b94faaSDavid Teigland 	/*  Adjust the last dirent's record length
957b3b94faaSDavid Teigland 	   (Remember that dent still points to the last entry.)  */
958b3b94faaSDavid Teigland 
9594dd651adSSteven Whitehouse 	dent->de_rec_len = cpu_to_be16(be16_to_cpu(dent->de_rec_len) +
960b3b94faaSDavid Teigland 		sizeof(struct gfs2_dinode) -
9614dd651adSSteven Whitehouse 		sizeof(struct gfs2_leaf));
962b3b94faaSDavid Teigland 
963b3b94faaSDavid Teigland 	brelse(bh);
964b3b94faaSDavid Teigland 
965b3b94faaSDavid Teigland 	/*  We're done with the new leaf block, now setup the new
966b3b94faaSDavid Teigland 	    hash table.  */
967b3b94faaSDavid Teigland 
968350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(dip->i_gl, dibh);
969b3b94faaSDavid Teigland 	gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode));
970b3b94faaSDavid Teigland 
971b44b84d7SAl Viro 	lp = (__be64 *)(dibh->b_data + sizeof(struct gfs2_dinode));
972b3b94faaSDavid Teigland 
973b3b94faaSDavid Teigland 	for (x = sdp->sd_hash_ptrs; x--; lp++)
974b3b94faaSDavid Teigland 		*lp = cpu_to_be64(bn);
975b3b94faaSDavid Teigland 
976a2e0f799SSteven Whitehouse 	i_size_write(inode, sdp->sd_sb.sb_bsize / 2);
97777658aadSSteven Whitehouse 	gfs2_add_inode_blocks(&dip->i_inode, 1);
978383f01fbSSteven Whitehouse 	dip->i_diskflags |= GFS2_DIF_EXHASH;
979b3b94faaSDavid Teigland 
980b3b94faaSDavid Teigland 	for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ;
9819a004508SSteven Whitehouse 	dip->i_depth = y;
982b3b94faaSDavid Teigland 
983539e5d6bSSteven Whitehouse 	gfs2_dinode_out(dip, dibh->b_data);
984b3b94faaSDavid Teigland 
985b3b94faaSDavid Teigland 	brelse(dibh);
986b3b94faaSDavid Teigland 
987b3b94faaSDavid Teigland 	return 0;
988b3b94faaSDavid Teigland }
989b3b94faaSDavid Teigland 
990b3b94faaSDavid Teigland /**
991b3b94faaSDavid Teigland  * dir_split_leaf - Split a leaf block into two
9923ae3a7d6SBob Peterson  * @inode: The directory inode to be split
9933ae3a7d6SBob Peterson  * @name: name of the dirent we're trying to insert
994b3b94faaSDavid Teigland  *
995b3b94faaSDavid Teigland  * Returns: 0 on success, error code on failure
996b3b94faaSDavid Teigland  */
997b3b94faaSDavid Teigland 
dir_split_leaf(struct inode * inode,const struct qstr * name)998c752666cSSteven Whitehouse static int dir_split_leaf(struct inode *inode, const struct qstr *name)
999b3b94faaSDavid Teigland {
1000feaa7bbaSSteven Whitehouse 	struct gfs2_inode *dip = GFS2_I(inode);
1001b3b94faaSDavid Teigland 	struct buffer_head *nbh, *obh, *dibh;
1002b3b94faaSDavid Teigland 	struct gfs2_leaf *nleaf, *oleaf;
10034da3c646SSteven Whitehouse 	struct gfs2_dirent *dent = NULL, *prev = NULL, *next = NULL, *new;
1004cd915493SSteven Whitehouse 	u32 start, len, half_len, divider;
1005b44b84d7SAl Viro 	u64 bn, leaf_no;
1006b44b84d7SAl Viro 	__be64 *lp;
1007cd915493SSteven Whitehouse 	u32 index;
1008d1b0cb93SColin Ian King 	int x;
1009b3b94faaSDavid Teigland 	int error;
1010b3b94faaSDavid Teigland 
10119a004508SSteven Whitehouse 	index = name->hash >> (32 - dip->i_depth);
1012c752666cSSteven Whitehouse 	error = get_leaf_nr(dip, index, &leaf_no);
1013287980e4SArnd Bergmann 	if (error)
1014c752666cSSteven Whitehouse 		return error;
1015b3b94faaSDavid Teigland 
1016b3b94faaSDavid Teigland 	/*  Get the old leaf block  */
1017b3b94faaSDavid Teigland 	error = get_leaf(dip, leaf_no, &obh);
1018b3b94faaSDavid Teigland 	if (error)
1019e90deff5SSteven Whitehouse 		return error;
1020e90deff5SSteven Whitehouse 
1021e90deff5SSteven Whitehouse 	oleaf = (struct gfs2_leaf *)obh->b_data;
10229a004508SSteven Whitehouse 	if (dip->i_depth == be16_to_cpu(oleaf->lf_depth)) {
1023e90deff5SSteven Whitehouse 		brelse(obh);
1024e90deff5SSteven Whitehouse 		return 1; /* can't split */
1025e90deff5SSteven Whitehouse 	}
1026b3b94faaSDavid Teigland 
1027350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(dip->i_gl, obh);
1028b3b94faaSDavid Teigland 
1029c752666cSSteven Whitehouse 	nleaf = new_leaf(inode, &nbh, be16_to_cpu(oleaf->lf_depth) + 1);
1030c752666cSSteven Whitehouse 	if (!nleaf) {
1031c752666cSSteven Whitehouse 		brelse(obh);
1032c752666cSSteven Whitehouse 		return -ENOSPC;
1033c752666cSSteven Whitehouse 	}
1034c752666cSSteven Whitehouse 	bn = nbh->b_blocknr;
1035b3b94faaSDavid Teigland 
1036c752666cSSteven Whitehouse 	/*  Compute the start and len of leaf pointers in the hash table.  */
103747a9a527SFabian Frederick 	len = BIT(dip->i_depth - be16_to_cpu(oleaf->lf_depth));
1038b3b94faaSDavid Teigland 	half_len = len >> 1;
1039b3b94faaSDavid Teigland 	if (!half_len) {
1040e54c78a2SBob Peterson 		fs_warn(GFS2_SB(inode), "i_depth %u lf_depth %u index %u\n",
1041d77d1b58SJoe Perches 			dip->i_depth, be16_to_cpu(oleaf->lf_depth), index);
1042b3b94faaSDavid Teigland 		gfs2_consist_inode(dip);
1043b3b94faaSDavid Teigland 		error = -EIO;
1044b3b94faaSDavid Teigland 		goto fail_brelse;
1045b3b94faaSDavid Teigland 	}
1046b3b94faaSDavid Teigland 
1047b3b94faaSDavid Teigland 	start = (index & ~(len - 1));
1048b3b94faaSDavid Teigland 
1049b3b94faaSDavid Teigland 	/* Change the pointers.
1050b3b94faaSDavid Teigland 	   Don't bother distinguishing stuffed from non-stuffed.
1051b3b94faaSDavid Teigland 	   This code is complicated enough already. */
10526da2ec56SKees Cook 	lp = kmalloc_array(half_len, sizeof(__be64), GFP_NOFS);
10534244b52eSDavid Rientjes 	if (!lp) {
10544244b52eSDavid Rientjes 		error = -ENOMEM;
10554244b52eSDavid Rientjes 		goto fail_brelse;
10564244b52eSDavid Rientjes 	}
10574244b52eSDavid Rientjes 
1058b3b94faaSDavid Teigland 	/*  Change the pointers  */
1059b3b94faaSDavid Teigland 	for (x = 0; x < half_len; x++)
1060b3b94faaSDavid Teigland 		lp[x] = cpu_to_be64(bn);
1061b3b94faaSDavid Teigland 
106217d539f0SSteven Whitehouse 	gfs2_dir_hash_inval(dip);
106317d539f0SSteven Whitehouse 
1064cd915493SSteven Whitehouse 	error = gfs2_dir_write_data(dip, (char *)lp, start * sizeof(u64),
1065cd915493SSteven Whitehouse 				    half_len * sizeof(u64));
1066cd915493SSteven Whitehouse 	if (error != half_len * sizeof(u64)) {
1067b3b94faaSDavid Teigland 		if (error >= 0)
1068b3b94faaSDavid Teigland 			error = -EIO;
1069b3b94faaSDavid Teigland 		goto fail_lpfree;
1070b3b94faaSDavid Teigland 	}
1071b3b94faaSDavid Teigland 
1072b3b94faaSDavid Teigland 	kfree(lp);
1073b3b94faaSDavid Teigland 
1074b3b94faaSDavid Teigland 	/*  Compute the divider  */
10759a004508SSteven Whitehouse 	divider = (start + half_len) << (32 - dip->i_depth);
1076b3b94faaSDavid Teigland 
1077b3b94faaSDavid Teigland 	/*  Copy the entries  */
10781579343aSSteven Whitehouse 	dent = (struct gfs2_dirent *)(obh->b_data + sizeof(struct gfs2_leaf));
1079b3b94faaSDavid Teigland 
1080b3b94faaSDavid Teigland 	do {
1081b3b94faaSDavid Teigland 		next = dent;
1082b3b94faaSDavid Teigland 		if (dirent_next(dip, obh, &next))
1083b3b94faaSDavid Teigland 			next = NULL;
1084b3b94faaSDavid Teigland 
10855e7d65cdSSteven Whitehouse 		if (!gfs2_dirent_sentinel(dent) &&
1086b3b94faaSDavid Teigland 		    be32_to_cpu(dent->de_hash) < divider) {
1087c752666cSSteven Whitehouse 			struct qstr str;
108834017472SBenjamin Marzinski 			void *ptr = ((char *)dent - obh->b_data) + nbh->b_data;
1089c752666cSSteven Whitehouse 			str.name = (char*)(dent+1);
1090c752666cSSteven Whitehouse 			str.len = be16_to_cpu(dent->de_name_len);
1091c752666cSSteven Whitehouse 			str.hash = be32_to_cpu(dent->de_hash);
109234017472SBenjamin Marzinski 			new = gfs2_dirent_split_alloc(inode, nbh, &str, ptr);
1093c752666cSSteven Whitehouse 			if (IS_ERR(new)) {
1094c752666cSSteven Whitehouse 				error = PTR_ERR(new);
1095c752666cSSteven Whitehouse 				break;
1096c752666cSSteven Whitehouse 			}
1097b3b94faaSDavid Teigland 
1098b3b94faaSDavid Teigland 			new->de_inum = dent->de_inum; /* No endian worries */
1099b3b94faaSDavid Teigland 			new->de_type = dent->de_type; /* No endian worries */
1100bb16b342SMarcin Slusarz 			be16_add_cpu(&nleaf->lf_entries, 1);
1101b3b94faaSDavid Teigland 
1102b3b94faaSDavid Teigland 			dirent_del(dip, obh, prev, dent);
1103b3b94faaSDavid Teigland 
1104b3b94faaSDavid Teigland 			if (!oleaf->lf_entries)
1105b3b94faaSDavid Teigland 				gfs2_consist_inode(dip);
1106bb16b342SMarcin Slusarz 			be16_add_cpu(&oleaf->lf_entries, -1);
1107b3b94faaSDavid Teigland 
1108b3b94faaSDavid Teigland 			if (!prev)
1109b3b94faaSDavid Teigland 				prev = dent;
1110c752666cSSteven Whitehouse 		} else {
1111b3b94faaSDavid Teigland 			prev = dent;
1112c752666cSSteven Whitehouse 		}
1113b3b94faaSDavid Teigland 		dent = next;
1114c752666cSSteven Whitehouse 	} while (dent);
1115b3b94faaSDavid Teigland 
1116c752666cSSteven Whitehouse 	oleaf->lf_depth = nleaf->lf_depth;
1117b3b94faaSDavid Teigland 
1118b3b94faaSDavid Teigland 	error = gfs2_meta_inode_buffer(dip, &dibh);
1119feaa7bbaSSteven Whitehouse 	if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) {
1120350a9b0aSSteven Whitehouse 		gfs2_trans_add_meta(dip->i_gl, dibh);
112177658aadSSteven Whitehouse 		gfs2_add_inode_blocks(&dip->i_inode, 1);
1122539e5d6bSSteven Whitehouse 		gfs2_dinode_out(dip, dibh->b_data);
1123b3b94faaSDavid Teigland 		brelse(dibh);
1124b3b94faaSDavid Teigland 	}
1125b3b94faaSDavid Teigland 
1126b3b94faaSDavid Teigland 	brelse(obh);
1127b3b94faaSDavid Teigland 	brelse(nbh);
1128b3b94faaSDavid Teigland 
1129b3b94faaSDavid Teigland 	return error;
1130b3b94faaSDavid Teigland 
1131b3b94faaSDavid Teigland fail_lpfree:
1132b3b94faaSDavid Teigland 	kfree(lp);
1133b3b94faaSDavid Teigland 
1134b3b94faaSDavid Teigland fail_brelse:
1135b3b94faaSDavid Teigland 	brelse(obh);
1136b3b94faaSDavid Teigland 	brelse(nbh);
1137b3b94faaSDavid Teigland 	return error;
1138b3b94faaSDavid Teigland }
1139b3b94faaSDavid Teigland 
1140b3b94faaSDavid Teigland /**
1141b3b94faaSDavid Teigland  * dir_double_exhash - Double size of ExHash table
1142b3b94faaSDavid Teigland  * @dip: The GFS2 dinode
1143b3b94faaSDavid Teigland  *
1144b3b94faaSDavid Teigland  * Returns: 0 on success, error code on failure
1145b3b94faaSDavid Teigland  */
1146b3b94faaSDavid Teigland 
dir_double_exhash(struct gfs2_inode * dip)1147b3b94faaSDavid Teigland static int dir_double_exhash(struct gfs2_inode *dip)
1148b3b94faaSDavid Teigland {
1149b3b94faaSDavid Teigland 	struct buffer_head *dibh;
1150cd915493SSteven Whitehouse 	u32 hsize;
115117d539f0SSteven Whitehouse 	u32 hsize_bytes;
115217d539f0SSteven Whitehouse 	__be64 *hc;
115317d539f0SSteven Whitehouse 	__be64 *hc2, *h;
1154b3b94faaSDavid Teigland 	int x;
1155b3b94faaSDavid Teigland 	int error = 0;
1156b3b94faaSDavid Teigland 
115747a9a527SFabian Frederick 	hsize = BIT(dip->i_depth);
115817d539f0SSteven Whitehouse 	hsize_bytes = hsize * sizeof(__be64);
1159b3b94faaSDavid Teigland 
116017d539f0SSteven Whitehouse 	hc = gfs2_dir_get_hash_table(dip);
116117d539f0SSteven Whitehouse 	if (IS_ERR(hc))
116217d539f0SSteven Whitehouse 		return PTR_ERR(hc);
1163b3b94faaSDavid Teigland 
11646da2ec56SKees Cook 	hc2 = kmalloc_array(hsize_bytes, 2, GFP_NOFS | __GFP_NOWARN);
1165e8830d88SBob Peterson 	if (hc2 == NULL)
116688dca4caSChristoph Hellwig 		hc2 = __vmalloc(hsize_bytes * 2, GFP_NOFS);
1167e8830d88SBob Peterson 
116817d539f0SSteven Whitehouse 	if (!hc2)
11694244b52eSDavid Rientjes 		return -ENOMEM;
1170b3b94faaSDavid Teigland 
1171512cbf02SBob Peterson 	h = hc2;
1172b3b94faaSDavid Teigland 	error = gfs2_meta_inode_buffer(dip, &dibh);
117317d539f0SSteven Whitehouse 	if (error)
117417d539f0SSteven Whitehouse 		goto out_kfree;
117517d539f0SSteven Whitehouse 
117617d539f0SSteven Whitehouse 	for (x = 0; x < hsize; x++) {
117717d539f0SSteven Whitehouse 		*h++ = *hc;
117817d539f0SSteven Whitehouse 		*h++ = *hc;
117917d539f0SSteven Whitehouse 		hc++;
118017d539f0SSteven Whitehouse 	}
118117d539f0SSteven Whitehouse 
118217d539f0SSteven Whitehouse 	error = gfs2_dir_write_data(dip, (char *)hc2, 0, hsize_bytes * 2);
118317d539f0SSteven Whitehouse 	if (error != (hsize_bytes * 2))
118417d539f0SSteven Whitehouse 		goto fail;
118517d539f0SSteven Whitehouse 
118617d539f0SSteven Whitehouse 	gfs2_dir_hash_inval(dip);
118717d539f0SSteven Whitehouse 	dip->i_hash_cache = hc2;
11889a004508SSteven Whitehouse 	dip->i_depth++;
1189539e5d6bSSteven Whitehouse 	gfs2_dinode_out(dip, dibh->b_data);
1190b3b94faaSDavid Teigland 	brelse(dibh);
119117d539f0SSteven Whitehouse 	return 0;
1192b3b94faaSDavid Teigland 
1193b3b94faaSDavid Teigland fail:
119417d539f0SSteven Whitehouse 	/* Replace original hash table & size */
119517d539f0SSteven Whitehouse 	gfs2_dir_write_data(dip, (char *)hc, 0, hsize_bytes);
119617d539f0SSteven Whitehouse 	i_size_write(&dip->i_inode, hsize_bytes);
119717d539f0SSteven Whitehouse 	gfs2_dinode_out(dip, dibh->b_data);
119817d539f0SSteven Whitehouse 	brelse(dibh);
119917d539f0SSteven Whitehouse out_kfree:
12003cdcf63eSAl Viro 	kvfree(hc2);
1201b3b94faaSDavid Teigland 	return error;
1202b3b94faaSDavid Teigland }
1203b3b94faaSDavid Teigland 
1204b3b94faaSDavid Teigland /**
1205b3b94faaSDavid Teigland  * compare_dents - compare directory entries by hash value
1206b3b94faaSDavid Teigland  * @a: first dent
1207b3b94faaSDavid Teigland  * @b: second dent
1208b3b94faaSDavid Teigland  *
1209b3b94faaSDavid Teigland  * When comparing the hash entries of @a to @b:
1210b3b94faaSDavid Teigland  *   gt: returns 1
1211b3b94faaSDavid Teigland  *   lt: returns -1
1212b3b94faaSDavid Teigland  *   eq: returns 0
1213b3b94faaSDavid Teigland  */
1214b3b94faaSDavid Teigland 
compare_dents(const void * a,const void * b)1215b3b94faaSDavid Teigland static int compare_dents(const void *a, const void *b)
1216b3b94faaSDavid Teigland {
12172bdbc5d7SSteven Whitehouse 	const struct gfs2_dirent *dent_a, *dent_b;
1218cd915493SSteven Whitehouse 	u32 hash_a, hash_b;
1219b3b94faaSDavid Teigland 	int ret = 0;
1220b3b94faaSDavid Teigland 
12212bdbc5d7SSteven Whitehouse 	dent_a = *(const struct gfs2_dirent **)a;
1222471f3db2SBenjamin Marzinski 	hash_a = dent_a->de_cookie;
1223b3b94faaSDavid Teigland 
12242bdbc5d7SSteven Whitehouse 	dent_b = *(const struct gfs2_dirent **)b;
1225471f3db2SBenjamin Marzinski 	hash_b = dent_b->de_cookie;
1226b3b94faaSDavid Teigland 
1227b3b94faaSDavid Teigland 	if (hash_a > hash_b)
1228b3b94faaSDavid Teigland 		ret = 1;
1229b3b94faaSDavid Teigland 	else if (hash_a < hash_b)
1230b3b94faaSDavid Teigland 		ret = -1;
1231b3b94faaSDavid Teigland 	else {
12324dd651adSSteven Whitehouse 		unsigned int len_a = be16_to_cpu(dent_a->de_name_len);
12334dd651adSSteven Whitehouse 		unsigned int len_b = be16_to_cpu(dent_b->de_name_len);
1234b3b94faaSDavid Teigland 
1235b3b94faaSDavid Teigland 		if (len_a > len_b)
1236b3b94faaSDavid Teigland 			ret = 1;
1237b3b94faaSDavid Teigland 		else if (len_a < len_b)
1238b3b94faaSDavid Teigland 			ret = -1;
1239b3b94faaSDavid Teigland 		else
12402bdbc5d7SSteven Whitehouse 			ret = memcmp(dent_a + 1, dent_b + 1, len_a);
1241b3b94faaSDavid Teigland 	}
1242b3b94faaSDavid Teigland 
1243b3b94faaSDavid Teigland 	return ret;
1244b3b94faaSDavid Teigland }
1245b3b94faaSDavid Teigland 
1246b3b94faaSDavid Teigland /**
1247b3b94faaSDavid Teigland  * do_filldir_main - read out directory entries
1248b3b94faaSDavid Teigland  * @dip: The GFS2 inode
1249d81a8ef5SAl Viro  * @ctx: what to feed the entries to
1250b3b94faaSDavid Teigland  * @darr: an array of struct gfs2_dirent pointers to read
1251b3b94faaSDavid Teigland  * @entries: the number of entries in darr
12523ae3a7d6SBob Peterson  * @sort_start: index of the directory array to start our sort
1253b3b94faaSDavid Teigland  * @copied: pointer to int that's non-zero if a entry has been copied out
1254b3b94faaSDavid Teigland  *
1255b3b94faaSDavid Teigland  * Jump through some hoops to make sure that if there are hash collsions,
1256b3b94faaSDavid Teigland  * they are read out at the beginning of a buffer.  We want to minimize
1257b3b94faaSDavid Teigland  * the possibility that they will fall into different readdir buffers or
1258b3b94faaSDavid Teigland  * that someone will want to seek to that location.
1259b3b94faaSDavid Teigland  *
1260d81a8ef5SAl Viro  * Returns: errno, >0 if the actor tells you to stop
1261b3b94faaSDavid Teigland  */
1262b3b94faaSDavid Teigland 
do_filldir_main(struct gfs2_inode * dip,struct dir_context * ctx,struct gfs2_dirent ** darr,u32 entries,u32 sort_start,int * copied)1263d81a8ef5SAl Viro static int do_filldir_main(struct gfs2_inode *dip, struct dir_context *ctx,
1264471f3db2SBenjamin Marzinski 			   struct gfs2_dirent **darr, u32 entries,
1265471f3db2SBenjamin Marzinski 			   u32 sort_start, int *copied)
1266b3b94faaSDavid Teigland {
126771b86f56SSteven Whitehouse 	const struct gfs2_dirent *dent, *dent_next;
1268cd915493SSteven Whitehouse 	u64 off, off_next;
1269b3b94faaSDavid Teigland 	unsigned int x, y;
1270b3b94faaSDavid Teigland 	int run = 0;
1271b3b94faaSDavid Teigland 
1272471f3db2SBenjamin Marzinski 	if (sort_start < entries)
1273471f3db2SBenjamin Marzinski 		sort(&darr[sort_start], entries - sort_start,
1274471f3db2SBenjamin Marzinski 		     sizeof(struct gfs2_dirent *), compare_dents, NULL);
1275b3b94faaSDavid Teigland 
1276b3b94faaSDavid Teigland 	dent_next = darr[0];
1277471f3db2SBenjamin Marzinski 	off_next = dent_next->de_cookie;
1278b3b94faaSDavid Teigland 
1279b3b94faaSDavid Teigland 	for (x = 0, y = 1; x < entries; x++, y++) {
1280b3b94faaSDavid Teigland 		dent = dent_next;
1281b3b94faaSDavid Teigland 		off = off_next;
1282b3b94faaSDavid Teigland 
1283b3b94faaSDavid Teigland 		if (y < entries) {
1284b3b94faaSDavid Teigland 			dent_next = darr[y];
1285471f3db2SBenjamin Marzinski 			off_next = dent_next->de_cookie;
1286b3b94faaSDavid Teigland 
1287d81a8ef5SAl Viro 			if (off < ctx->pos)
1288b3b94faaSDavid Teigland 				continue;
1289d81a8ef5SAl Viro 			ctx->pos = off;
1290b3b94faaSDavid Teigland 
1291b3b94faaSDavid Teigland 			if (off_next == off) {
1292b3b94faaSDavid Teigland 				if (*copied && !run)
1293b3b94faaSDavid Teigland 					return 1;
1294b3b94faaSDavid Teigland 				run = 1;
1295b3b94faaSDavid Teigland 			} else
1296b3b94faaSDavid Teigland 				run = 0;
1297b3b94faaSDavid Teigland 		} else {
1298d81a8ef5SAl Viro 			if (off < ctx->pos)
1299b3b94faaSDavid Teigland 				continue;
1300d81a8ef5SAl Viro 			ctx->pos = off;
1301b3b94faaSDavid Teigland 		}
1302b3b94faaSDavid Teigland 
1303d81a8ef5SAl Viro 		if (!dir_emit(ctx, (const char *)(dent + 1),
13044dd651adSSteven Whitehouse 				be16_to_cpu(dent->de_name_len),
1305d81a8ef5SAl Viro 				be64_to_cpu(dent->de_inum.no_addr),
1306d81a8ef5SAl Viro 				be16_to_cpu(dent->de_type)))
1307b3b94faaSDavid Teigland 			return 1;
1308b3b94faaSDavid Teigland 
1309b3b94faaSDavid Teigland 		*copied = 1;
1310b3b94faaSDavid Teigland 	}
1311b3b94faaSDavid Teigland 
1312d81a8ef5SAl Viro 	/* Increment the ctx->pos by one, so the next time we come into the
1313b3b94faaSDavid Teigland 	   do_filldir fxn, we get the next entry instead of the last one in the
1314b3b94faaSDavid Teigland 	   current leaf */
1315b3b94faaSDavid Teigland 
1316d81a8ef5SAl Viro 	ctx->pos++;
1317b3b94faaSDavid Teigland 
1318b3b94faaSDavid Teigland 	return 0;
1319b3b94faaSDavid Teigland }
1320b3b94faaSDavid Teigland 
gfs2_alloc_sort_buffer(unsigned size)1321d2a97a4eSSteven Whitehouse static void *gfs2_alloc_sort_buffer(unsigned size)
1322d2a97a4eSSteven Whitehouse {
1323d2a97a4eSSteven Whitehouse 	void *ptr = NULL;
1324d2a97a4eSSteven Whitehouse 
1325d2a97a4eSSteven Whitehouse 	if (size < KMALLOC_MAX_SIZE)
1326d2a97a4eSSteven Whitehouse 		ptr = kmalloc(size, GFP_NOFS | __GFP_NOWARN);
1327d2a97a4eSSteven Whitehouse 	if (!ptr)
132888dca4caSChristoph Hellwig 		ptr = __vmalloc(size, GFP_NOFS);
1329d2a97a4eSSteven Whitehouse 	return ptr;
1330d2a97a4eSSteven Whitehouse }
1331d2a97a4eSSteven Whitehouse 
1332471f3db2SBenjamin Marzinski 
gfs2_set_cookies(struct gfs2_sbd * sdp,struct buffer_head * bh,unsigned leaf_nr,struct gfs2_dirent ** darr,unsigned entries)1333471f3db2SBenjamin Marzinski static int gfs2_set_cookies(struct gfs2_sbd *sdp, struct buffer_head *bh,
1334471f3db2SBenjamin Marzinski 			    unsigned leaf_nr, struct gfs2_dirent **darr,
1335471f3db2SBenjamin Marzinski 			    unsigned entries)
1336471f3db2SBenjamin Marzinski {
1337471f3db2SBenjamin Marzinski 	int sort_id = -1;
1338471f3db2SBenjamin Marzinski 	int i;
1339471f3db2SBenjamin Marzinski 
1340471f3db2SBenjamin Marzinski 	for (i = 0; i < entries; i++) {
1341471f3db2SBenjamin Marzinski 		unsigned offset;
1342471f3db2SBenjamin Marzinski 
1343471f3db2SBenjamin Marzinski 		darr[i]->de_cookie = be32_to_cpu(darr[i]->de_hash);
1344471f3db2SBenjamin Marzinski 		darr[i]->de_cookie = gfs2_disk_hash2offset(darr[i]->de_cookie);
1345471f3db2SBenjamin Marzinski 
1346471f3db2SBenjamin Marzinski 		if (!sdp->sd_args.ar_loccookie)
1347471f3db2SBenjamin Marzinski 			continue;
1348471f3db2SBenjamin Marzinski 		offset = (char *)(darr[i]) -
1349e54c78a2SBob Peterson 			(bh->b_data + gfs2_dirent_offset(sdp, bh->b_data));
1350471f3db2SBenjamin Marzinski 		offset /= GFS2_MIN_DIRENT_SIZE;
1351471f3db2SBenjamin Marzinski 		offset += leaf_nr * sdp->sd_max_dents_per_leaf;
1352471f3db2SBenjamin Marzinski 		if (offset >= GFS2_USE_HASH_FLAG ||
1353471f3db2SBenjamin Marzinski 		    leaf_nr >= GFS2_USE_HASH_FLAG) {
1354471f3db2SBenjamin Marzinski 			darr[i]->de_cookie |= GFS2_USE_HASH_FLAG;
1355471f3db2SBenjamin Marzinski 			if (sort_id < 0)
1356471f3db2SBenjamin Marzinski 				sort_id = i;
1357471f3db2SBenjamin Marzinski 			continue;
1358471f3db2SBenjamin Marzinski 		}
1359471f3db2SBenjamin Marzinski 		darr[i]->de_cookie &= GFS2_HASH_INDEX_MASK;
1360471f3db2SBenjamin Marzinski 		darr[i]->de_cookie |= offset;
1361471f3db2SBenjamin Marzinski 	}
1362471f3db2SBenjamin Marzinski 	return sort_id;
1363471f3db2SBenjamin Marzinski }
1364471f3db2SBenjamin Marzinski 
1365471f3db2SBenjamin Marzinski 
gfs2_dir_read_leaf(struct inode * inode,struct dir_context * ctx,int * copied,unsigned * depth,u64 leaf_no)1366d81a8ef5SAl Viro static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx,
1367d81a8ef5SAl Viro 			      int *copied, unsigned *depth,
13683699e3a4SSteven Whitehouse 			      u64 leaf_no)
1369b3b94faaSDavid Teigland {
1370feaa7bbaSSteven Whitehouse 	struct gfs2_inode *ip = GFS2_I(inode);
1371bdd19a22SSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(inode);
137271b86f56SSteven Whitehouse 	struct buffer_head *bh;
137371b86f56SSteven Whitehouse 	struct gfs2_leaf *lf;
1374bdd19a22SSteven Whitehouse 	unsigned entries = 0, entries2 = 0;
1375471f3db2SBenjamin Marzinski 	unsigned leaves = 0, leaf = 0, offset, sort_offset;
1376471f3db2SBenjamin Marzinski 	struct gfs2_dirent **darr, *dent;
137771b86f56SSteven Whitehouse 	struct dirent_gather g;
137871b86f56SSteven Whitehouse 	struct buffer_head **larr;
1379471f3db2SBenjamin Marzinski 	int error, i, need_sort = 0, sort_id;
138071b86f56SSteven Whitehouse 	u64 lfn = leaf_no;
1381b3b94faaSDavid Teigland 
1382b3b94faaSDavid Teigland 	do {
138371b86f56SSteven Whitehouse 		error = get_leaf(ip, lfn, &bh);
1384b3b94faaSDavid Teigland 		if (error)
138571b86f56SSteven Whitehouse 			goto out;
138671b86f56SSteven Whitehouse 		lf = (struct gfs2_leaf *)bh->b_data;
138771b86f56SSteven Whitehouse 		if (leaves == 0)
138871b86f56SSteven Whitehouse 			*depth = be16_to_cpu(lf->lf_depth);
138971b86f56SSteven Whitehouse 		entries += be16_to_cpu(lf->lf_entries);
1390b3b94faaSDavid Teigland 		leaves++;
139171b86f56SSteven Whitehouse 		lfn = be64_to_cpu(lf->lf_next);
139271b86f56SSteven Whitehouse 		brelse(bh);
139371b86f56SSteven Whitehouse 	} while(lfn);
1394b3b94faaSDavid Teigland 
1395471f3db2SBenjamin Marzinski 	if (*depth < GFS2_DIR_MAX_DEPTH || !sdp->sd_args.ar_loccookie) {
1396471f3db2SBenjamin Marzinski 		need_sort = 1;
1397471f3db2SBenjamin Marzinski 		sort_offset = 0;
1398471f3db2SBenjamin Marzinski 	}
1399471f3db2SBenjamin Marzinski 
1400b3b94faaSDavid Teigland 	if (!entries)
1401b3b94faaSDavid Teigland 		return 0;
1402b3b94faaSDavid Teigland 
140371b86f56SSteven Whitehouse 	error = -ENOMEM;
1404bdd19a22SSteven Whitehouse 	/*
1405bdd19a22SSteven Whitehouse 	 * The extra 99 entries are not normally used, but are a buffer
1406bdd19a22SSteven Whitehouse 	 * zone in case the number of entries in the leaf is corrupt.
1407bdd19a22SSteven Whitehouse 	 * 99 is the maximum number of entries that can fit in a single
1408bdd19a22SSteven Whitehouse 	 * leaf block.
1409bdd19a22SSteven Whitehouse 	 */
1410d2a97a4eSSteven Whitehouse 	larr = gfs2_alloc_sort_buffer((leaves + entries + 99) * sizeof(void *));
1411b3b94faaSDavid Teigland 	if (!larr)
1412b3b94faaSDavid Teigland 		goto out;
1413471f3db2SBenjamin Marzinski 	darr = (struct gfs2_dirent **)(larr + leaves);
1414471f3db2SBenjamin Marzinski 	g.pdent = (const struct gfs2_dirent **)darr;
141571b86f56SSteven Whitehouse 	g.offset = 0;
141671b86f56SSteven Whitehouse 	lfn = leaf_no;
1417b3b94faaSDavid Teigland 
141871b86f56SSteven Whitehouse 	do {
141971b86f56SSteven Whitehouse 		error = get_leaf(ip, lfn, &bh);
1420b3b94faaSDavid Teigland 		if (error)
1421d2a97a4eSSteven Whitehouse 			goto out_free;
142271b86f56SSteven Whitehouse 		lf = (struct gfs2_leaf *)bh->b_data;
142371b86f56SSteven Whitehouse 		lfn = be64_to_cpu(lf->lf_next);
142471b86f56SSteven Whitehouse 		if (lf->lf_entries) {
1425471f3db2SBenjamin Marzinski 			offset = g.offset;
1426bdd19a22SSteven Whitehouse 			entries2 += be16_to_cpu(lf->lf_entries);
142771b86f56SSteven Whitehouse 			dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size,
142871b86f56SSteven Whitehouse 						gfs2_dirent_gather, NULL, &g);
142971b86f56SSteven Whitehouse 			error = PTR_ERR(dent);
1430bdd19a22SSteven Whitehouse 			if (IS_ERR(dent))
1431d2a97a4eSSteven Whitehouse 				goto out_free;
1432bdd19a22SSteven Whitehouse 			if (entries2 != g.offset) {
1433f391a4eaSakpm@linux-foundation.org 				fs_warn(sdp, "Number of entries corrupt in dir "
1434f391a4eaSakpm@linux-foundation.org 						"leaf %llu, entries2 (%u) != "
1435f391a4eaSakpm@linux-foundation.org 						"g.offset (%u)\n",
1436f391a4eaSakpm@linux-foundation.org 					(unsigned long long)bh->b_blocknr,
1437f391a4eaSakpm@linux-foundation.org 					entries2, g.offset);
1438d87d62b7SBob Peterson 				gfs2_consist_inode(ip);
1439bdd19a22SSteven Whitehouse 				error = -EIO;
1440d2a97a4eSSteven Whitehouse 				goto out_free;
1441b3b94faaSDavid Teigland 			}
144271b86f56SSteven Whitehouse 			error = 0;
1443471f3db2SBenjamin Marzinski 			sort_id = gfs2_set_cookies(sdp, bh, leaf, &darr[offset],
1444471f3db2SBenjamin Marzinski 						   be16_to_cpu(lf->lf_entries));
1445471f3db2SBenjamin Marzinski 			if (!need_sort && sort_id >= 0) {
1446471f3db2SBenjamin Marzinski 				need_sort = 1;
1447471f3db2SBenjamin Marzinski 				sort_offset = offset + sort_id;
1448471f3db2SBenjamin Marzinski 			}
144971b86f56SSteven Whitehouse 			larr[leaf++] = bh;
1450b3b94faaSDavid Teigland 		} else {
1451471f3db2SBenjamin Marzinski 			larr[leaf++] = NULL;
145271b86f56SSteven Whitehouse 			brelse(bh);
1453b3b94faaSDavid Teigland 		}
145471b86f56SSteven Whitehouse 	} while(lfn);
1455b3b94faaSDavid Teigland 
1456bdd19a22SSteven Whitehouse 	BUG_ON(entries2 != entries);
1457471f3db2SBenjamin Marzinski 	error = do_filldir_main(ip, ctx, darr, entries, need_sort ?
1458471f3db2SBenjamin Marzinski 				sort_offset : entries, copied);
1459d2a97a4eSSteven Whitehouse out_free:
146071b86f56SSteven Whitehouse 	for(i = 0; i < leaf; i++)
146171b86f56SSteven Whitehouse 		brelse(larr[i]);
14623cdcf63eSAl Viro 	kvfree(larr);
146371b86f56SSteven Whitehouse out:
1464b3b94faaSDavid Teigland 	return error;
1465b3b94faaSDavid Teigland }
1466b3b94faaSDavid Teigland 
146779c4c379SSteven Whitehouse /**
146879c4c379SSteven Whitehouse  * gfs2_dir_readahead - Issue read-ahead requests for leaf blocks.
14693ae3a7d6SBob Peterson  * @inode: the directory inode
14703ae3a7d6SBob Peterson  * @hsize: hash table size
14713ae3a7d6SBob Peterson  * @index: index into the hash table
14723ae3a7d6SBob Peterson  * @f_ra: read-ahead parameters
1473dfe4d34bSBob Peterson  *
1474dfe4d34bSBob Peterson  * Note: we can't calculate each index like dir_e_read can because we don't
1475dfe4d34bSBob Peterson  * have the leaf, and therefore we don't have the depth, and therefore we
1476dfe4d34bSBob Peterson  * don't have the length. So we have to just read enough ahead to make up
147779c4c379SSteven Whitehouse  * for the loss of information.
147879c4c379SSteven Whitehouse  */
gfs2_dir_readahead(struct inode * inode,unsigned hsize,u32 index,struct file_ra_state * f_ra)1479dfe4d34bSBob Peterson static void gfs2_dir_readahead(struct inode *inode, unsigned hsize, u32 index,
1480dfe4d34bSBob Peterson 			       struct file_ra_state *f_ra)
1481dfe4d34bSBob Peterson {
1482dfe4d34bSBob Peterson 	struct gfs2_inode *ip = GFS2_I(inode);
1483dfe4d34bSBob Peterson 	struct gfs2_glock *gl = ip->i_gl;
1484dfe4d34bSBob Peterson 	struct buffer_head *bh;
1485dfe4d34bSBob Peterson 	u64 blocknr = 0, last;
1486dfe4d34bSBob Peterson 	unsigned count;
1487dfe4d34bSBob Peterson 
1488dfe4d34bSBob Peterson 	/* First check if we've already read-ahead for the whole range. */
148979c4c379SSteven Whitehouse 	if (index + MAX_RA_BLOCKS < f_ra->start)
1490dfe4d34bSBob Peterson 		return;
1491dfe4d34bSBob Peterson 
1492dfe4d34bSBob Peterson 	f_ra->start = max((pgoff_t)index, f_ra->start);
1493dfe4d34bSBob Peterson 	for (count = 0; count < MAX_RA_BLOCKS; count++) {
1494dfe4d34bSBob Peterson 		if (f_ra->start >= hsize) /* if exceeded the hash table */
1495dfe4d34bSBob Peterson 			break;
1496dfe4d34bSBob Peterson 
1497dfe4d34bSBob Peterson 		last = blocknr;
1498dfe4d34bSBob Peterson 		blocknr = be64_to_cpu(ip->i_hash_cache[f_ra->start]);
1499dfe4d34bSBob Peterson 		f_ra->start++;
1500dfe4d34bSBob Peterson 		if (blocknr == last)
1501dfe4d34bSBob Peterson 			continue;
1502dfe4d34bSBob Peterson 
1503dfe4d34bSBob Peterson 		bh = gfs2_getbuf(gl, blocknr, 1);
1504dfe4d34bSBob Peterson 		if (trylock_buffer(bh)) {
1505dfe4d34bSBob Peterson 			if (buffer_uptodate(bh)) {
1506dfe4d34bSBob Peterson 				unlock_buffer(bh);
1507dfe4d34bSBob Peterson 				brelse(bh);
1508dfe4d34bSBob Peterson 				continue;
1509dfe4d34bSBob Peterson 			}
1510dfe4d34bSBob Peterson 			bh->b_end_io = end_buffer_read_sync;
15111420c4a5SBart Van Assche 			submit_bh(REQ_OP_READ | REQ_RAHEAD | REQ_META |
15121420c4a5SBart Van Assche 				  REQ_PRIO, bh);
1513dfe4d34bSBob Peterson 			continue;
1514dfe4d34bSBob Peterson 		}
1515dfe4d34bSBob Peterson 		brelse(bh);
1516dfe4d34bSBob Peterson 	}
1517dfe4d34bSBob Peterson }
151817d539f0SSteven Whitehouse 
1519b3b94faaSDavid Teigland /**
1520b3b94faaSDavid Teigland  * dir_e_read - Reads the entries from a directory into a filldir buffer
15213ae3a7d6SBob Peterson  * @inode: the directory inode
1522d81a8ef5SAl Viro  * @ctx: actor to feed the entries to
15233ae3a7d6SBob Peterson  * @f_ra: read-ahead parameters
1524b3b94faaSDavid Teigland  *
1525b3b94faaSDavid Teigland  * Returns: errno
1526b3b94faaSDavid Teigland  */
1527b3b94faaSDavid Teigland 
dir_e_read(struct inode * inode,struct dir_context * ctx,struct file_ra_state * f_ra)1528d81a8ef5SAl Viro static int dir_e_read(struct inode *inode, struct dir_context *ctx,
1529d81a8ef5SAl Viro 		      struct file_ra_state *f_ra)
1530b3b94faaSDavid Teigland {
1531feaa7bbaSSteven Whitehouse 	struct gfs2_inode *dip = GFS2_I(inode);
1532cd915493SSteven Whitehouse 	u32 hsize, len = 0;
1533cd915493SSteven Whitehouse 	u32 hash, index;
1534b44b84d7SAl Viro 	__be64 *lp;
1535b3b94faaSDavid Teigland 	int copied = 0;
1536b3b94faaSDavid Teigland 	int error = 0;
15374da3c646SSteven Whitehouse 	unsigned depth = 0;
1538b3b94faaSDavid Teigland 
153947a9a527SFabian Frederick 	hsize = BIT(dip->i_depth);
1540d81a8ef5SAl Viro 	hash = gfs2_dir_offset2hash(ctx->pos);
15419a004508SSteven Whitehouse 	index = hash >> (32 - dip->i_depth);
1542b3b94faaSDavid Teigland 
154379c4c379SSteven Whitehouse 	if (dip->i_hash_cache == NULL)
1544dfe4d34bSBob Peterson 		f_ra->start = 0;
154517d539f0SSteven Whitehouse 	lp = gfs2_dir_get_hash_table(dip);
154617d539f0SSteven Whitehouse 	if (IS_ERR(lp))
154717d539f0SSteven Whitehouse 		return PTR_ERR(lp);
1548b3b94faaSDavid Teigland 
1549dfe4d34bSBob Peterson 	gfs2_dir_readahead(inode, hsize, index, f_ra);
1550dfe4d34bSBob Peterson 
1551b3b94faaSDavid Teigland 	while (index < hsize) {
1552d81a8ef5SAl Viro 		error = gfs2_dir_read_leaf(inode, ctx,
155371b86f56SSteven Whitehouse 					   &copied, &depth,
155417d539f0SSteven Whitehouse 					   be64_to_cpu(lp[index]));
1555b3b94faaSDavid Teigland 		if (error)
155671b86f56SSteven Whitehouse 			break;
1557b3b94faaSDavid Teigland 
155847a9a527SFabian Frederick 		len = BIT(dip->i_depth - depth);
1559b3b94faaSDavid Teigland 		index = (index & ~(len - 1)) + len;
1560b3b94faaSDavid Teigland 	}
1561b3b94faaSDavid Teigland 
156271b86f56SSteven Whitehouse 	if (error > 0)
156371b86f56SSteven Whitehouse 		error = 0;
1564b3b94faaSDavid Teigland 	return error;
1565b3b94faaSDavid Teigland }
1566b3b94faaSDavid Teigland 
gfs2_dir_read(struct inode * inode,struct dir_context * ctx,struct file_ra_state * f_ra)1567d81a8ef5SAl Viro int gfs2_dir_read(struct inode *inode, struct dir_context *ctx,
1568d81a8ef5SAl Viro 		  struct file_ra_state *f_ra)
1569b3b94faaSDavid Teigland {
1570feaa7bbaSSteven Whitehouse 	struct gfs2_inode *dip = GFS2_I(inode);
1571bdd19a22SSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(inode);
157271b86f56SSteven Whitehouse 	struct dirent_gather g;
1573471f3db2SBenjamin Marzinski 	struct gfs2_dirent **darr, *dent;
1574b3b94faaSDavid Teigland 	struct buffer_head *dibh;
1575b3b94faaSDavid Teigland 	int copied = 0;
1576b3b94faaSDavid Teigland 	int error;
1577b3b94faaSDavid Teigland 
1578ad6203f2SSteven Whitehouse 	if (!dip->i_entries)
157971b86f56SSteven Whitehouse 		return 0;
158071b86f56SSteven Whitehouse 
1581383f01fbSSteven Whitehouse 	if (dip->i_diskflags & GFS2_DIF_EXHASH)
1582d81a8ef5SAl Viro 		return dir_e_read(inode, ctx, f_ra);
158371b86f56SSteven Whitehouse 
1584b3b94faaSDavid Teigland 	if (!gfs2_is_stuffed(dip)) {
1585b3b94faaSDavid Teigland 		gfs2_consist_inode(dip);
1586b3b94faaSDavid Teigland 		return -EIO;
1587b3b94faaSDavid Teigland 	}
1588b3b94faaSDavid Teigland 
1589b3b94faaSDavid Teigland 	error = gfs2_meta_inode_buffer(dip, &dibh);
1590b3b94faaSDavid Teigland 	if (error)
1591b3b94faaSDavid Teigland 		return error;
1592b3b94faaSDavid Teigland 
159371b86f56SSteven Whitehouse 	error = -ENOMEM;
1594bdd19a22SSteven Whitehouse 	/* 96 is max number of dirents which can be stuffed into an inode */
15956da2ec56SKees Cook 	darr = kmalloc_array(96, sizeof(struct gfs2_dirent *), GFP_NOFS);
159671b86f56SSteven Whitehouse 	if (darr) {
1597471f3db2SBenjamin Marzinski 		g.pdent = (const struct gfs2_dirent **)darr;
159871b86f56SSteven Whitehouse 		g.offset = 0;
159971b86f56SSteven Whitehouse 		dent = gfs2_dirent_scan(inode, dibh->b_data, dibh->b_size,
160071b86f56SSteven Whitehouse 					gfs2_dirent_gather, NULL, &g);
160171b86f56SSteven Whitehouse 		if (IS_ERR(dent)) {
160271b86f56SSteven Whitehouse 			error = PTR_ERR(dent);
160371b86f56SSteven Whitehouse 			goto out;
160471b86f56SSteven Whitehouse 		}
1605ad6203f2SSteven Whitehouse 		if (dip->i_entries != g.offset) {
1606bdd19a22SSteven Whitehouse 			fs_warn(sdp, "Number of entries corrupt in dir %llu, "
1607ad6203f2SSteven Whitehouse 				"ip->i_entries (%u) != g.offset (%u)\n",
1608dbb7cae2SSteven Whitehouse 				(unsigned long long)dip->i_no_addr,
1609ad6203f2SSteven Whitehouse 				dip->i_entries,
1610bdd19a22SSteven Whitehouse 				g.offset);
1611d87d62b7SBob Peterson 			gfs2_consist_inode(dip);
1612bdd19a22SSteven Whitehouse 			error = -EIO;
1613bdd19a22SSteven Whitehouse 			goto out;
1614bdd19a22SSteven Whitehouse 		}
1615471f3db2SBenjamin Marzinski 		gfs2_set_cookies(sdp, dibh, 0, darr, dip->i_entries);
1616d81a8ef5SAl Viro 		error = do_filldir_main(dip, ctx, darr,
1617471f3db2SBenjamin Marzinski 					dip->i_entries, 0, &copied);
161871b86f56SSteven Whitehouse out:
161971b86f56SSteven Whitehouse 		kfree(darr);
162071b86f56SSteven Whitehouse 	}
162171b86f56SSteven Whitehouse 
1622b3b94faaSDavid Teigland 	if (error > 0)
1623b3b94faaSDavid Teigland 		error = 0;
1624b3b94faaSDavid Teigland 
1625b3b94faaSDavid Teigland 	brelse(dibh);
1626b3b94faaSDavid Teigland 
1627b3b94faaSDavid Teigland 	return error;
1628b3b94faaSDavid Teigland }
1629b3b94faaSDavid Teigland 
1630b3b94faaSDavid Teigland /**
1631b3b94faaSDavid Teigland  * gfs2_dir_search - Search a directory
16323ae3a7d6SBob Peterson  * @dir: The GFS2 directory inode
16335a00f3ccSSteven Whitehouse  * @name: The name we are looking up
16345a00f3ccSSteven Whitehouse  * @fail_on_exist: Fail if the name exists rather than looking it up
1635b3b94faaSDavid Teigland  *
1636b3b94faaSDavid Teigland  * This routine searches a directory for a file or another directory.
1637b3b94faaSDavid Teigland  * Assumes a glock is held on dip.
1638b3b94faaSDavid Teigland  *
1639b3b94faaSDavid Teigland  * Returns: errno
1640b3b94faaSDavid Teigland  */
1641b3b94faaSDavid Teigland 
gfs2_dir_search(struct inode * dir,const struct qstr * name,bool fail_on_exist)16425a00f3ccSSteven Whitehouse struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name,
16435a00f3ccSSteven Whitehouse 			      bool fail_on_exist)
1644b3b94faaSDavid Teigland {
1645c752666cSSteven Whitehouse 	struct buffer_head *bh;
1646c752666cSSteven Whitehouse 	struct gfs2_dirent *dent;
16475a00f3ccSSteven Whitehouse 	u64 addr, formal_ino;
16485a00f3ccSSteven Whitehouse 	u16 dtype;
1649dbb7cae2SSteven Whitehouse 
1650dbb7cae2SSteven Whitehouse 	dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
1651dbb7cae2SSteven Whitehouse 	if (dent) {
1652c8d57703SAndreas Gruenbacher 		struct inode *inode;
1653c8d57703SAndreas Gruenbacher 		u16 rahead;
1654c8d57703SAndreas Gruenbacher 
1655dbb7cae2SSteven Whitehouse 		if (IS_ERR(dent))
1656e231c2eeSDavid Howells 			return ERR_CAST(dent);
16575a00f3ccSSteven Whitehouse 		dtype = be16_to_cpu(dent->de_type);
1658c8d57703SAndreas Gruenbacher 		rahead = be16_to_cpu(dent->de_rahead);
16595a00f3ccSSteven Whitehouse 		addr = be64_to_cpu(dent->de_inum.no_addr);
16605a00f3ccSSteven Whitehouse 		formal_ino = be64_to_cpu(dent->de_inum.no_formal_ino);
1661dbb7cae2SSteven Whitehouse 		brelse(bh);
16625a00f3ccSSteven Whitehouse 		if (fail_on_exist)
16635a00f3ccSSteven Whitehouse 			return ERR_PTR(-EEXIST);
16643ce37b2cSAndreas Gruenbacher 		inode = gfs2_inode_lookup(dir->i_sb, dtype, addr, formal_ino,
16653ce37b2cSAndreas Gruenbacher 					  GFS2_BLKST_FREE /* ignore */);
1666c8d57703SAndreas Gruenbacher 		if (!IS_ERR(inode))
1667c8d57703SAndreas Gruenbacher 			GFS2_I(inode)->i_rahead = rahead;
1668c8d57703SAndreas Gruenbacher 		return inode;
1669dbb7cae2SSteven Whitehouse 	}
1670dbb7cae2SSteven Whitehouse 	return ERR_PTR(-ENOENT);
1671dbb7cae2SSteven Whitehouse }
1672dbb7cae2SSteven Whitehouse 
gfs2_dir_check(struct inode * dir,const struct qstr * name,const struct gfs2_inode * ip)1673dbb7cae2SSteven Whitehouse int gfs2_dir_check(struct inode *dir, const struct qstr *name,
1674dbb7cae2SSteven Whitehouse 		   const struct gfs2_inode *ip)
1675dbb7cae2SSteven Whitehouse {
1676dbb7cae2SSteven Whitehouse 	struct buffer_head *bh;
1677dbb7cae2SSteven Whitehouse 	struct gfs2_dirent *dent;
1678dbb7cae2SSteven Whitehouse 	int ret = -ENOENT;
1679c752666cSSteven Whitehouse 
1680c752666cSSteven Whitehouse 	dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
1681c752666cSSteven Whitehouse 	if (dent) {
1682c752666cSSteven Whitehouse 		if (IS_ERR(dent))
1683c752666cSSteven Whitehouse 			return PTR_ERR(dent);
1684dbb7cae2SSteven Whitehouse 		if (ip) {
1685dbb7cae2SSteven Whitehouse 			if (be64_to_cpu(dent->de_inum.no_addr) != ip->i_no_addr)
1686dbb7cae2SSteven Whitehouse 				goto out;
1687dbb7cae2SSteven Whitehouse 			if (be64_to_cpu(dent->de_inum.no_formal_ino) !=
1688dbb7cae2SSteven Whitehouse 			    ip->i_no_formal_ino)
1689dbb7cae2SSteven Whitehouse 				goto out;
1690dbb7cae2SSteven Whitehouse 			if (unlikely(IF2DT(ip->i_inode.i_mode) !=
1691dbb7cae2SSteven Whitehouse 			    be16_to_cpu(dent->de_type))) {
1692dbb7cae2SSteven Whitehouse 				gfs2_consist_inode(GFS2_I(dir));
1693dbb7cae2SSteven Whitehouse 				ret = -EIO;
1694dbb7cae2SSteven Whitehouse 				goto out;
1695c752666cSSteven Whitehouse 			}
1696dbb7cae2SSteven Whitehouse 		}
1697dbb7cae2SSteven Whitehouse 		ret = 0;
1698dbb7cae2SSteven Whitehouse out:
1699dbb7cae2SSteven Whitehouse 		brelse(bh);
1700dbb7cae2SSteven Whitehouse 	}
1701dbb7cae2SSteven Whitehouse 	return ret;
1702c752666cSSteven Whitehouse }
1703c752666cSSteven Whitehouse 
170401bcb0deSSteven Whitehouse /**
170501bcb0deSSteven Whitehouse  * dir_new_leaf - Add a new leaf onto hash chain
170601bcb0deSSteven Whitehouse  * @inode: The directory
170701bcb0deSSteven Whitehouse  * @name: The name we are adding
170801bcb0deSSteven Whitehouse  *
170901bcb0deSSteven Whitehouse  * This adds a new dir leaf onto an existing leaf when there is not
171001bcb0deSSteven Whitehouse  * enough space to add a new dir entry. This is a last resort after
171101bcb0deSSteven Whitehouse  * we've expanded the hash table to max size and also split existing
171201bcb0deSSteven Whitehouse  * leaf blocks, so it will only occur for very large directories.
171301bcb0deSSteven Whitehouse  *
171401bcb0deSSteven Whitehouse  * The dist parameter is set to 1 for leaf blocks directly attached
171501bcb0deSSteven Whitehouse  * to the hash table, 2 for one layer of indirection, 3 for two layers
171601bcb0deSSteven Whitehouse  * etc. We are thus able to tell the difference between an old leaf
171701bcb0deSSteven Whitehouse  * with dist set to zero (i.e. "don't know") and a new one where we
171801bcb0deSSteven Whitehouse  * set this information for debug/fsck purposes.
171901bcb0deSSteven Whitehouse  *
172001bcb0deSSteven Whitehouse  * Returns: 0 on success, or -ve on error
172101bcb0deSSteven Whitehouse  */
172201bcb0deSSteven Whitehouse 
dir_new_leaf(struct inode * inode,const struct qstr * name)1723c752666cSSteven Whitehouse static int dir_new_leaf(struct inode *inode, const struct qstr *name)
1724c752666cSSteven Whitehouse {
1725c752666cSSteven Whitehouse 	struct buffer_head *bh, *obh;
1726feaa7bbaSSteven Whitehouse 	struct gfs2_inode *ip = GFS2_I(inode);
1727c752666cSSteven Whitehouse 	struct gfs2_leaf *leaf, *oleaf;
172801bcb0deSSteven Whitehouse 	u32 dist = 1;
1729b3b94faaSDavid Teigland 	int error;
1730c752666cSSteven Whitehouse 	u32 index;
1731c752666cSSteven Whitehouse 	u64 bn;
1732b3b94faaSDavid Teigland 
17339a004508SSteven Whitehouse 	index = name->hash >> (32 - ip->i_depth);
1734c752666cSSteven Whitehouse 	error = get_first_leaf(ip, index, &obh);
1735c752666cSSteven Whitehouse 	if (error)
1736b3b94faaSDavid Teigland 		return error;
1737c752666cSSteven Whitehouse 	do {
173801bcb0deSSteven Whitehouse 		dist++;
1739c752666cSSteven Whitehouse 		oleaf = (struct gfs2_leaf *)obh->b_data;
1740c752666cSSteven Whitehouse 		bn = be64_to_cpu(oleaf->lf_next);
1741c752666cSSteven Whitehouse 		if (!bn)
1742c752666cSSteven Whitehouse 			break;
1743c752666cSSteven Whitehouse 		brelse(obh);
1744c752666cSSteven Whitehouse 		error = get_leaf(ip, bn, &obh);
1745c752666cSSteven Whitehouse 		if (error)
1746c752666cSSteven Whitehouse 			return error;
1747c752666cSSteven Whitehouse 	} while(1);
1748c752666cSSteven Whitehouse 
1749350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(ip->i_gl, obh);
1750c752666cSSteven Whitehouse 
1751c752666cSSteven Whitehouse 	leaf = new_leaf(inode, &bh, be16_to_cpu(oleaf->lf_depth));
1752c752666cSSteven Whitehouse 	if (!leaf) {
1753c752666cSSteven Whitehouse 		brelse(obh);
1754c752666cSSteven Whitehouse 		return -ENOSPC;
1755c752666cSSteven Whitehouse 	}
175601bcb0deSSteven Whitehouse 	leaf->lf_dist = cpu_to_be32(dist);
17574d8012b6SSteven Whitehouse 	oleaf->lf_next = cpu_to_be64(bh->b_blocknr);
1758c752666cSSteven Whitehouse 	brelse(bh);
1759c752666cSSteven Whitehouse 	brelse(obh);
1760c752666cSSteven Whitehouse 
1761c752666cSSteven Whitehouse 	error = gfs2_meta_inode_buffer(ip, &bh);
1762c752666cSSteven Whitehouse 	if (error)
1763c752666cSSteven Whitehouse 		return error;
1764350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(ip->i_gl, bh);
176577658aadSSteven Whitehouse 	gfs2_add_inode_blocks(&ip->i_inode, 1);
1766539e5d6bSSteven Whitehouse 	gfs2_dinode_out(ip, bh->b_data);
1767c752666cSSteven Whitehouse 	brelse(bh);
1768c752666cSSteven Whitehouse 	return 0;
1769b3b94faaSDavid Teigland }
1770b3b94faaSDavid Teigland 
gfs2_inode_ra_len(const struct gfs2_inode * ip)177144aaada9SSteven Whitehouse static u16 gfs2_inode_ra_len(const struct gfs2_inode *ip)
177244aaada9SSteven Whitehouse {
177344aaada9SSteven Whitehouse 	u64 where = ip->i_no_addr + 1;
177444aaada9SSteven Whitehouse 	if (ip->i_eattr == where)
177544aaada9SSteven Whitehouse 		return 1;
177644aaada9SSteven Whitehouse 	return 0;
177744aaada9SSteven Whitehouse }
177844aaada9SSteven Whitehouse 
1779b3b94faaSDavid Teigland /**
1780b3b94faaSDavid Teigland  * gfs2_dir_add - Add new filename into directory
17812b47dad8SSteven Whitehouse  * @inode: The directory inode
17822b47dad8SSteven Whitehouse  * @name: The new name
17832b47dad8SSteven Whitehouse  * @nip: The GFS2 inode to be linked in to the directory
17842b47dad8SSteven Whitehouse  * @da: The directory addition info
17852b47dad8SSteven Whitehouse  *
17862b47dad8SSteven Whitehouse  * If the call to gfs2_diradd_alloc_required resulted in there being
17872b47dad8SSteven Whitehouse  * no need to allocate any new directory blocks, then it will contain
17882b47dad8SSteven Whitehouse  * a pointer to the directory entry and the bh in which it resides. We
17892b47dad8SSteven Whitehouse  * can use that without having to repeat the search. If there was no
17902b47dad8SSteven Whitehouse  * free space, then we must now create more space.
1791b3b94faaSDavid Teigland  *
1792b3b94faaSDavid Teigland  * Returns: 0 on success, error code on failure
1793b3b94faaSDavid Teigland  */
1794b3b94faaSDavid Teigland 
gfs2_dir_add(struct inode * inode,const struct qstr * name,const struct gfs2_inode * nip,struct gfs2_diradd * da)1795c752666cSSteven Whitehouse int gfs2_dir_add(struct inode *inode, const struct qstr *name,
17962b47dad8SSteven Whitehouse 		 const struct gfs2_inode *nip, struct gfs2_diradd *da)
1797b3b94faaSDavid Teigland {
1798feaa7bbaSSteven Whitehouse 	struct gfs2_inode *ip = GFS2_I(inode);
17992b47dad8SSteven Whitehouse 	struct buffer_head *bh = da->bh;
18002b47dad8SSteven Whitehouse 	struct gfs2_dirent *dent = da->dent;
180195582b00SDeepa Dinamani 	struct timespec64 tv;
1802c752666cSSteven Whitehouse 	struct gfs2_leaf *leaf;
1803b3b94faaSDavid Teigland 	int error;
1804b3b94faaSDavid Teigland 
1805c752666cSSteven Whitehouse 	while(1) {
18062b47dad8SSteven Whitehouse 		if (da->bh == NULL) {
18072b47dad8SSteven Whitehouse 			dent = gfs2_dirent_search(inode, name,
18082b47dad8SSteven Whitehouse 						  gfs2_dirent_find_space, &bh);
18092b47dad8SSteven Whitehouse 		}
1810c752666cSSteven Whitehouse 		if (dent) {
1811c752666cSSteven Whitehouse 			if (IS_ERR(dent))
1812c752666cSSteven Whitehouse 				return PTR_ERR(dent);
1813c752666cSSteven Whitehouse 			dent = gfs2_init_dirent(inode, dent, name, bh);
1814dbb7cae2SSteven Whitehouse 			gfs2_inum_out(nip, dent);
18153d6ecb7dSSteven Whitehouse 			dent->de_type = cpu_to_be16(IF2DT(nip->i_inode.i_mode));
181644aaada9SSteven Whitehouse 			dent->de_rahead = cpu_to_be16(gfs2_inode_ra_len(nip));
18178a8b8d91SJeff Layton 			tv = inode_set_ctime_current(&ip->i_inode);
1818383f01fbSSteven Whitehouse 			if (ip->i_diskflags & GFS2_DIF_EXHASH) {
1819c752666cSSteven Whitehouse 				leaf = (struct gfs2_leaf *)bh->b_data;
1820bb16b342SMarcin Slusarz 				be16_add_cpu(&leaf->lf_entries, 1);
182101bcb0deSSteven Whitehouse 				leaf->lf_nsec = cpu_to_be32(tv.tv_nsec);
182201bcb0deSSteven Whitehouse 				leaf->lf_sec = cpu_to_be64(tv.tv_sec);
1823c752666cSSteven Whitehouse 			}
18242b47dad8SSteven Whitehouse 			da->dent = NULL;
18252b47dad8SSteven Whitehouse 			da->bh = NULL;
1826c752666cSSteven Whitehouse 			brelse(bh);
1827ad6203f2SSteven Whitehouse 			ip->i_entries++;
18288a8b8d91SJeff Layton 			ip->i_inode.i_mtime = tv;
18293d6ecb7dSSteven Whitehouse 			if (S_ISDIR(nip->i_inode.i_mode))
18303d6ecb7dSSteven Whitehouse 				inc_nlink(&ip->i_inode);
1831343cd8f0SBob Peterson 			mark_inode_dirty(inode);
1832c752666cSSteven Whitehouse 			error = 0;
1833c752666cSSteven Whitehouse 			break;
1834c752666cSSteven Whitehouse 		}
1835383f01fbSSteven Whitehouse 		if (!(ip->i_diskflags & GFS2_DIF_EXHASH)) {
1836c752666cSSteven Whitehouse 			error = dir_make_exhash(inode);
1837c752666cSSteven Whitehouse 			if (error)
1838c752666cSSteven Whitehouse 				break;
1839c752666cSSteven Whitehouse 			continue;
1840c752666cSSteven Whitehouse 		}
1841c752666cSSteven Whitehouse 		error = dir_split_leaf(inode, name);
1842c752666cSSteven Whitehouse 		if (error == 0)
1843c752666cSSteven Whitehouse 			continue;
1844e90deff5SSteven Whitehouse 		if (error < 0)
1845c752666cSSteven Whitehouse 			break;
18469a004508SSteven Whitehouse 		if (ip->i_depth < GFS2_DIR_MAX_DEPTH) {
1847c752666cSSteven Whitehouse 			error = dir_double_exhash(ip);
1848c752666cSSteven Whitehouse 			if (error)
1849c752666cSSteven Whitehouse 				break;
1850c752666cSSteven Whitehouse 			error = dir_split_leaf(inode, name);
1851e90deff5SSteven Whitehouse 			if (error < 0)
1852c752666cSSteven Whitehouse 				break;
1853e90deff5SSteven Whitehouse 			if (error == 0)
1854c752666cSSteven Whitehouse 				continue;
1855c752666cSSteven Whitehouse 		}
1856c752666cSSteven Whitehouse 		error = dir_new_leaf(inode, name);
1857c752666cSSteven Whitehouse 		if (!error)
1858c752666cSSteven Whitehouse 			continue;
1859c752666cSSteven Whitehouse 		error = -ENOSPC;
1860c752666cSSteven Whitehouse 		break;
1861c752666cSSteven Whitehouse 	}
1862b3b94faaSDavid Teigland 	return error;
1863b3b94faaSDavid Teigland }
1864b3b94faaSDavid Teigland 
1865c752666cSSteven Whitehouse 
1866b3b94faaSDavid Teigland /**
1867b3b94faaSDavid Teigland  * gfs2_dir_del - Delete a directory entry
1868b3b94faaSDavid Teigland  * @dip: The GFS2 inode
18693ae3a7d6SBob Peterson  * @dentry: The directory entry we want to delete
1870b3b94faaSDavid Teigland  *
1871b3b94faaSDavid Teigland  * Returns: 0 on success, error code on failure
1872b3b94faaSDavid Teigland  */
1873b3b94faaSDavid Teigland 
gfs2_dir_del(struct gfs2_inode * dip,const struct dentry * dentry)1874855d23ceSSteven Whitehouse int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry)
1875b3b94faaSDavid Teigland {
1876855d23ceSSteven Whitehouse 	const struct qstr *name = &dentry->d_name;
1877c752666cSSteven Whitehouse 	struct gfs2_dirent *dent, *prev = NULL;
1878c752666cSSteven Whitehouse 	struct buffer_head *bh;
18798a8b8d91SJeff Layton 	struct timespec64 tv;
1880b3b94faaSDavid Teigland 
1881c752666cSSteven Whitehouse 	/* Returns _either_ the entry (if its first in block) or the
1882c752666cSSteven Whitehouse 	   previous entry otherwise */
1883feaa7bbaSSteven Whitehouse 	dent = gfs2_dirent_search(&dip->i_inode, name, gfs2_dirent_prev, &bh);
1884c752666cSSteven Whitehouse 	if (!dent) {
1885c752666cSSteven Whitehouse 		gfs2_consist_inode(dip);
1886c752666cSSteven Whitehouse 		return -EIO;
1887c752666cSSteven Whitehouse 	}
1888c752666cSSteven Whitehouse 	if (IS_ERR(dent)) {
1889c752666cSSteven Whitehouse 		gfs2_consist_inode(dip);
1890c752666cSSteven Whitehouse 		return PTR_ERR(dent);
1891c752666cSSteven Whitehouse 	}
1892c752666cSSteven Whitehouse 	/* If not first in block, adjust pointers accordingly */
189371b86f56SSteven Whitehouse 	if (gfs2_dirent_find(dent, name, NULL) == 0) {
1894c752666cSSteven Whitehouse 		prev = dent;
1895c752666cSSteven Whitehouse 		dent = (struct gfs2_dirent *)((char *)dent + be16_to_cpu(prev->de_rec_len));
1896c752666cSSteven Whitehouse 	}
1897c752666cSSteven Whitehouse 
1898c752666cSSteven Whitehouse 	dirent_del(dip, bh, prev, dent);
18998a8b8d91SJeff Layton 	tv = inode_set_ctime_current(&dip->i_inode);
1900383f01fbSSteven Whitehouse 	if (dip->i_diskflags & GFS2_DIF_EXHASH) {
1901c752666cSSteven Whitehouse 		struct gfs2_leaf *leaf = (struct gfs2_leaf *)bh->b_data;
1902c752666cSSteven Whitehouse 		u16 entries = be16_to_cpu(leaf->lf_entries);
1903c752666cSSteven Whitehouse 		if (!entries)
1904c752666cSSteven Whitehouse 			gfs2_consist_inode(dip);
1905c752666cSSteven Whitehouse 		leaf->lf_entries = cpu_to_be16(--entries);
190601bcb0deSSteven Whitehouse 		leaf->lf_nsec = cpu_to_be32(tv.tv_nsec);
190701bcb0deSSteven Whitehouse 		leaf->lf_sec = cpu_to_be64(tv.tv_sec);
1908c752666cSSteven Whitehouse 	}
1909ed386507SSteven Whitehouse 	brelse(bh);
1910c752666cSSteven Whitehouse 
1911ad6203f2SSteven Whitehouse 	if (!dip->i_entries)
1912c752666cSSteven Whitehouse 		gfs2_consist_inode(dip);
1913ad6203f2SSteven Whitehouse 	dip->i_entries--;
19148a8b8d91SJeff Layton 	dip->i_inode.i_mtime =  tv;
1915e36cb0b8SDavid Howells 	if (d_is_dir(dentry))
1916855d23ceSSteven Whitehouse 		drop_nlink(&dip->i_inode);
1917feaa7bbaSSteven Whitehouse 	mark_inode_dirty(&dip->i_inode);
1918b3b94faaSDavid Teigland 
1919ab9bbda0SSteven Whitehouse 	return 0;
1920b3b94faaSDavid Teigland }
1921b3b94faaSDavid Teigland 
1922b3b94faaSDavid Teigland /**
1923b3b94faaSDavid Teigland  * gfs2_dir_mvino - Change inode number of directory entry
19243ae3a7d6SBob Peterson  * @dip: The GFS2 directory inode
19253ae3a7d6SBob Peterson  * @filename: the filename to be moved
19263ae3a7d6SBob Peterson  * @nip: the new GFS2 inode
19273ae3a7d6SBob Peterson  * @new_type: the de_type of the new dirent
1928b3b94faaSDavid Teigland  *
1929b3b94faaSDavid Teigland  * This routine changes the inode number of a directory entry.  It's used
1930b3b94faaSDavid Teigland  * by rename to change ".." when a directory is moved.
1931b3b94faaSDavid Teigland  * Assumes a glock is held on dvp.
1932b3b94faaSDavid Teigland  *
1933b3b94faaSDavid Teigland  * Returns: errno
1934b3b94faaSDavid Teigland  */
1935b3b94faaSDavid Teigland 
gfs2_dir_mvino(struct gfs2_inode * dip,const struct qstr * filename,const struct gfs2_inode * nip,unsigned int new_type)1936c752666cSSteven Whitehouse int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1937dbb7cae2SSteven Whitehouse 		   const struct gfs2_inode *nip, unsigned int new_type)
1938b3b94faaSDavid Teigland {
1939c752666cSSteven Whitehouse 	struct buffer_head *bh;
1940c752666cSSteven Whitehouse 	struct gfs2_dirent *dent;
1941b3b94faaSDavid Teigland 
1942feaa7bbaSSteven Whitehouse 	dent = gfs2_dirent_search(&dip->i_inode, filename, gfs2_dirent_find, &bh);
1943c752666cSSteven Whitehouse 	if (!dent) {
1944c752666cSSteven Whitehouse 		gfs2_consist_inode(dip);
1945c752666cSSteven Whitehouse 		return -EIO;
1946c752666cSSteven Whitehouse 	}
1947c752666cSSteven Whitehouse 	if (IS_ERR(dent))
1948c752666cSSteven Whitehouse 		return PTR_ERR(dent);
1949b3b94faaSDavid Teigland 
1950350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(dip->i_gl, bh);
1951dbb7cae2SSteven Whitehouse 	gfs2_inum_out(nip, dent);
1952c752666cSSteven Whitehouse 	dent->de_type = cpu_to_be16(new_type);
1953c752666cSSteven Whitehouse 	brelse(bh);
1954c752666cSSteven Whitehouse 
19558a8b8d91SJeff Layton 	dip->i_inode.i_mtime = inode_set_ctime_current(&dip->i_inode);
195683998ccdSAndreas Gruenbacher 	mark_inode_dirty_sync(&dip->i_inode);
1957c752666cSSteven Whitehouse 	return 0;
1958b3b94faaSDavid Teigland }
1959b3b94faaSDavid Teigland 
1960b3b94faaSDavid Teigland /**
1961b3b94faaSDavid Teigland  * leaf_dealloc - Deallocate a directory leaf
1962b3b94faaSDavid Teigland  * @dip: the directory
1963b3b94faaSDavid Teigland  * @index: the hash table offset in the directory
1964b3b94faaSDavid Teigland  * @len: the number of pointers to this leaf
1965b3b94faaSDavid Teigland  * @leaf_no: the leaf number
1966ec038c82SBob Peterson  * @leaf_bh: buffer_head for the starting leaf
19673ae3a7d6SBob Peterson  * @last_dealloc: 1 if this is the final dealloc for the leaf, else 0
1968b3b94faaSDavid Teigland  *
1969b3b94faaSDavid Teigland  * Returns: errno
1970b3b94faaSDavid Teigland  */
1971b3b94faaSDavid Teigland 
leaf_dealloc(struct gfs2_inode * dip,u32 index,u32 len,u64 leaf_no,struct buffer_head * leaf_bh,int last_dealloc)1972cd915493SSteven Whitehouse static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
1973ec038c82SBob Peterson 			u64 leaf_no, struct buffer_head *leaf_bh,
1974ec038c82SBob Peterson 			int last_dealloc)
1975b3b94faaSDavid Teigland {
1976feaa7bbaSSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
1977c752666cSSteven Whitehouse 	struct gfs2_leaf *tmp_leaf;
1978b3b94faaSDavid Teigland 	struct gfs2_rgrp_list rlist;
1979b3b94faaSDavid Teigland 	struct buffer_head *bh, *dibh;
1980cd915493SSteven Whitehouse 	u64 blk, nblk;
1981b3b94faaSDavid Teigland 	unsigned int rg_blocks = 0, l_blocks = 0;
1982b3b94faaSDavid Teigland 	char *ht;
1983cd915493SSteven Whitehouse 	unsigned int x, size = len * sizeof(u64);
1984b3b94faaSDavid Teigland 	int error;
1985b3b94faaSDavid Teigland 
19865e2f7d61SBob Peterson 	error = gfs2_rindex_update(sdp);
19875e2f7d61SBob Peterson 	if (error)
19885e2f7d61SBob Peterson 		return error;
19895e2f7d61SBob Peterson 
1990b3b94faaSDavid Teigland 	memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
1991b3b94faaSDavid Teigland 
19928be04b93SJoe Perches 	ht = kzalloc(size, GFP_NOFS | __GFP_NOWARN);
1993e8830d88SBob Peterson 	if (ht == NULL)
199488dca4caSChristoph Hellwig 		ht = __vmalloc(size, GFP_NOFS | __GFP_NOWARN | __GFP_ZERO);
1995b3b94faaSDavid Teigland 	if (!ht)
1996b3b94faaSDavid Teigland 		return -ENOMEM;
1997b3b94faaSDavid Teigland 
1998f4108a60SEric W. Biederman 	error = gfs2_quota_hold(dip, NO_UID_QUOTA_CHANGE, NO_GID_QUOTA_CHANGE);
1999b3b94faaSDavid Teigland 	if (error)
20005407e242SBob Peterson 		goto out;
2001b3b94faaSDavid Teigland 
2002b3b94faaSDavid Teigland 	/*  Count the number of leaves  */
2003ec038c82SBob Peterson 	bh = leaf_bh;
2004b3b94faaSDavid Teigland 
2005c752666cSSteven Whitehouse 	for (blk = leaf_no; blk; blk = nblk) {
2006ec038c82SBob Peterson 		if (blk != leaf_no) {
2007b3b94faaSDavid Teigland 			error = get_leaf(dip, blk, &bh);
2008b3b94faaSDavid Teigland 			if (error)
2009b3b94faaSDavid Teigland 				goto out_rlist;
2010ec038c82SBob Peterson 		}
2011c752666cSSteven Whitehouse 		tmp_leaf = (struct gfs2_leaf *)bh->b_data;
2012c752666cSSteven Whitehouse 		nblk = be64_to_cpu(tmp_leaf->lf_next);
2013ec038c82SBob Peterson 		if (blk != leaf_no)
2014b3b94faaSDavid Teigland 			brelse(bh);
2015b3b94faaSDavid Teigland 
201670b0c365SSteven Whitehouse 		gfs2_rlist_add(dip, &rlist, blk);
2017b3b94faaSDavid Teigland 		l_blocks++;
2018b3b94faaSDavid Teigland 	}
2019b3b94faaSDavid Teigland 
202044dab005SAndreas Gruenbacher 	gfs2_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, LM_FLAG_NODE_SCOPE);
2021b3b94faaSDavid Teigland 
2022b3b94faaSDavid Teigland 	for (x = 0; x < rlist.rl_rgrps; x++) {
20236f6597baSAndreas Gruenbacher 		struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(rlist.rl_ghs[x].gh_gl);
20246f6597baSAndreas Gruenbacher 
2025bb8d8a6fSSteven Whitehouse 		rg_blocks += rgd->rd_length;
2026b3b94faaSDavid Teigland 	}
2027b3b94faaSDavid Teigland 
2028b3b94faaSDavid Teigland 	error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);
2029b3b94faaSDavid Teigland 	if (error)
2030b3b94faaSDavid Teigland 		goto out_rlist;
2031b3b94faaSDavid Teigland 
2032b3b94faaSDavid Teigland 	error = gfs2_trans_begin(sdp,
20335c676f6dSSteven Whitehouse 			rg_blocks + (DIV_ROUND_UP(size, sdp->sd_jbsize) + 1) +
2034cc44457fSBob Peterson 			RES_DINODE + RES_STATFS + RES_QUOTA, RES_DINODE +
2035cc44457fSBob Peterson 				 l_blocks);
2036b3b94faaSDavid Teigland 	if (error)
2037b3b94faaSDavid Teigland 		goto out_rg_gunlock;
2038b3b94faaSDavid Teigland 
2039ec038c82SBob Peterson 	bh = leaf_bh;
2040ec038c82SBob Peterson 
2041c752666cSSteven Whitehouse 	for (blk = leaf_no; blk; blk = nblk) {
20420ddeded4SAndreas Gruenbacher 		struct gfs2_rgrpd *rgd;
20430ddeded4SAndreas Gruenbacher 
2044ec038c82SBob Peterson 		if (blk != leaf_no) {
2045b3b94faaSDavid Teigland 			error = get_leaf(dip, blk, &bh);
2046b3b94faaSDavid Teigland 			if (error)
2047b3b94faaSDavid Teigland 				goto out_end_trans;
2048ec038c82SBob Peterson 		}
2049c752666cSSteven Whitehouse 		tmp_leaf = (struct gfs2_leaf *)bh->b_data;
2050c752666cSSteven Whitehouse 		nblk = be64_to_cpu(tmp_leaf->lf_next);
2051ec038c82SBob Peterson 		if (blk != leaf_no)
2052b3b94faaSDavid Teigland 			brelse(bh);
2053b3b94faaSDavid Teigland 
20540ddeded4SAndreas Gruenbacher 		rgd = gfs2_blk2rgrpd(sdp, blk, true);
20550ddeded4SAndreas Gruenbacher 		gfs2_free_meta(dip, rgd, blk, 1);
205677658aadSSteven Whitehouse 		gfs2_add_inode_blocks(&dip->i_inode, -1);
2057b3b94faaSDavid Teigland 	}
2058b3b94faaSDavid Teigland 
2059cd915493SSteven Whitehouse 	error = gfs2_dir_write_data(dip, ht, index * sizeof(u64), size);
2060b3b94faaSDavid Teigland 	if (error != size) {
2061b3b94faaSDavid Teigland 		if (error >= 0)
2062b3b94faaSDavid Teigland 			error = -EIO;
2063b3b94faaSDavid Teigland 		goto out_end_trans;
2064b3b94faaSDavid Teigland 	}
2065b3b94faaSDavid Teigland 
2066b3b94faaSDavid Teigland 	error = gfs2_meta_inode_buffer(dip, &dibh);
2067b3b94faaSDavid Teigland 	if (error)
2068b3b94faaSDavid Teigland 		goto out_end_trans;
2069b3b94faaSDavid Teigland 
2070350a9b0aSSteven Whitehouse 	gfs2_trans_add_meta(dip->i_gl, dibh);
2071d24a7a43SBob Peterson 	/* On the last dealloc, make this a regular file in case we crash.
2072d24a7a43SBob Peterson 	   (We don't want to free these blocks a second time.)  */
2073d24a7a43SBob Peterson 	if (last_dealloc)
2074d24a7a43SBob Peterson 		dip->i_inode.i_mode = S_IFREG;
2075539e5d6bSSteven Whitehouse 	gfs2_dinode_out(dip, dibh->b_data);
2076b3b94faaSDavid Teigland 	brelse(dibh);
2077b3b94faaSDavid Teigland 
2078b3b94faaSDavid Teigland out_end_trans:
2079b3b94faaSDavid Teigland 	gfs2_trans_end(sdp);
2080b3b94faaSDavid Teigland out_rg_gunlock:
2081b3b94faaSDavid Teigland 	gfs2_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs);
2082b3b94faaSDavid Teigland out_rlist:
2083b3b94faaSDavid Teigland 	gfs2_rlist_free(&rlist);
2084b3b94faaSDavid Teigland 	gfs2_quota_unhold(dip);
2085182fe5abSCyrill Gorcunov out:
20863cdcf63eSAl Viro 	kvfree(ht);
2087b3b94faaSDavid Teigland 	return error;
2088b3b94faaSDavid Teigland }
2089b3b94faaSDavid Teigland 
2090b3b94faaSDavid Teigland /**
2091b3b94faaSDavid Teigland  * gfs2_dir_exhash_dealloc - free all the leaf blocks in a directory
2092b3b94faaSDavid Teigland  * @dip: the directory
2093b3b94faaSDavid Teigland  *
2094b3b94faaSDavid Teigland  * Dealloc all on-disk directory leaves to FREEMETA state
2095b3b94faaSDavid Teigland  * Change on-disk inode type to "regular file"
2096b3b94faaSDavid Teigland  *
2097b3b94faaSDavid Teigland  * Returns: errno
2098b3b94faaSDavid Teigland  */
2099b3b94faaSDavid Teigland 
gfs2_dir_exhash_dealloc(struct gfs2_inode * dip)2100b3b94faaSDavid Teigland int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip)
2101b3b94faaSDavid Teigland {
2102556bb179SBob Peterson 	struct buffer_head *bh;
2103556bb179SBob Peterson 	struct gfs2_leaf *leaf;
2104556bb179SBob Peterson 	u32 hsize, len;
2105556bb179SBob Peterson 	u32 index = 0, next_index;
2106556bb179SBob Peterson 	__be64 *lp;
2107556bb179SBob Peterson 	u64 leaf_no;
2108556bb179SBob Peterson 	int error = 0, last;
2109556bb179SBob Peterson 
211047a9a527SFabian Frederick 	hsize = BIT(dip->i_depth);
2111556bb179SBob Peterson 
211217d539f0SSteven Whitehouse 	lp = gfs2_dir_get_hash_table(dip);
211317d539f0SSteven Whitehouse 	if (IS_ERR(lp))
211417d539f0SSteven Whitehouse 		return PTR_ERR(lp);
2115556bb179SBob Peterson 
2116556bb179SBob Peterson 	while (index < hsize) {
211717d539f0SSteven Whitehouse 		leaf_no = be64_to_cpu(lp[index]);
2118556bb179SBob Peterson 		if (leaf_no) {
2119556bb179SBob Peterson 			error = get_leaf(dip, leaf_no, &bh);
2120556bb179SBob Peterson 			if (error)
2121556bb179SBob Peterson 				goto out;
2122556bb179SBob Peterson 			leaf = (struct gfs2_leaf *)bh->b_data;
212347a9a527SFabian Frederick 			len = BIT(dip->i_depth - be16_to_cpu(leaf->lf_depth));
2124556bb179SBob Peterson 
2125556bb179SBob Peterson 			next_index = (index & ~(len - 1)) + len;
2126556bb179SBob Peterson 			last = ((next_index >= hsize) ? 1 : 0);
2127556bb179SBob Peterson 			error = leaf_dealloc(dip, index, len, leaf_no, bh,
2128556bb179SBob Peterson 					     last);
2129556bb179SBob Peterson 			brelse(bh);
2130556bb179SBob Peterson 			if (error)
2131556bb179SBob Peterson 				goto out;
2132556bb179SBob Peterson 			index = next_index;
2133556bb179SBob Peterson 		} else
2134556bb179SBob Peterson 			index++;
2135556bb179SBob Peterson 	}
2136556bb179SBob Peterson 
2137556bb179SBob Peterson 	if (index != hsize) {
2138556bb179SBob Peterson 		gfs2_consist_inode(dip);
2139556bb179SBob Peterson 		error = -EIO;
2140556bb179SBob Peterson 	}
2141556bb179SBob Peterson 
2142556bb179SBob Peterson out:
2143556bb179SBob Peterson 
2144556bb179SBob Peterson 	return error;
2145b3b94faaSDavid Teigland }
2146b3b94faaSDavid Teigland 
2147b3b94faaSDavid Teigland /**
2148b3b94faaSDavid Teigland  * gfs2_diradd_alloc_required - find if adding entry will require an allocation
21493ae3a7d6SBob Peterson  * @inode: the directory inode being written to
21503ae3a7d6SBob Peterson  * @name: the filename that's going to be added
21513c1c0ae1SSteven Whitehouse  * @da: The structure to return dir alloc info
2152b3b94faaSDavid Teigland  *
21533c1c0ae1SSteven Whitehouse  * Returns: 0 if ok, -ve on error
2154b3b94faaSDavid Teigland  */
2155b3b94faaSDavid Teigland 
gfs2_diradd_alloc_required(struct inode * inode,const struct qstr * name,struct gfs2_diradd * da)21563c1c0ae1SSteven Whitehouse int gfs2_diradd_alloc_required(struct inode *inode, const struct qstr *name,
21573c1c0ae1SSteven Whitehouse 			       struct gfs2_diradd *da)
2158b3b94faaSDavid Teigland {
215922b5a6c0SSteven Whitehouse 	struct gfs2_inode *ip = GFS2_I(inode);
21603c1c0ae1SSteven Whitehouse 	struct gfs2_sbd *sdp = GFS2_SB(inode);
216122b5a6c0SSteven Whitehouse 	const unsigned int extra = sizeof(struct gfs2_dinode) - sizeof(struct gfs2_leaf);
2162c752666cSSteven Whitehouse 	struct gfs2_dirent *dent;
2163c752666cSSteven Whitehouse 	struct buffer_head *bh;
2164b3b94faaSDavid Teigland 
21653c1c0ae1SSteven Whitehouse 	da->nr_blocks = 0;
21662b47dad8SSteven Whitehouse 	da->bh = NULL;
21672b47dad8SSteven Whitehouse 	da->dent = NULL;
21683c1c0ae1SSteven Whitehouse 
2169c752666cSSteven Whitehouse 	dent = gfs2_dirent_search(inode, name, gfs2_dirent_find_space, &bh);
2170ed386507SSteven Whitehouse 	if (!dent) {
21713c1c0ae1SSteven Whitehouse 		da->nr_blocks = sdp->sd_max_dirres;
217222b5a6c0SSteven Whitehouse 		if (!(ip->i_diskflags & GFS2_DIF_EXHASH) &&
217322b5a6c0SSteven Whitehouse 		    (GFS2_DIRENT_SIZE(name->len) < extra))
217422b5a6c0SSteven Whitehouse 			da->nr_blocks = 1;
21753c1c0ae1SSteven Whitehouse 		return 0;
2176ed386507SSteven Whitehouse 	}
2177c752666cSSteven Whitehouse 	if (IS_ERR(dent))
2178c752666cSSteven Whitehouse 		return PTR_ERR(dent);
217919aeb5a6SBob Peterson 
218019aeb5a6SBob Peterson 	if (da->save_loc) {
21812b47dad8SSteven Whitehouse 		da->bh = bh;
21822b47dad8SSteven Whitehouse 		da->dent = dent;
218319aeb5a6SBob Peterson 	} else {
218419aeb5a6SBob Peterson 		brelse(bh);
218519aeb5a6SBob Peterson 	}
2186c752666cSSteven Whitehouse 	return 0;
2187b3b94faaSDavid Teigland }
2188b3b94faaSDavid Teigland 
2189