xfs_dir2_leaf.c 50.0 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2
 * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
3
 * Copyright (c) 2013 Red Hat, Inc.
4
 * All Rights Reserved.
L
Linus Torvalds 已提交
5
 *
6 7
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
L
Linus Torvalds 已提交
8 9
 * published by the Free Software Foundation.
 *
10 11 12 13
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
L
Linus Torvalds 已提交
14
 *
15 16 17
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software Foundation,
 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
L
Linus Torvalds 已提交
18 19
 */
#include "xfs.h"
20
#include "xfs_fs.h"
21
#include "xfs_format.h"
22 23
#include "xfs_log_format.h"
#include "xfs_trans_resv.h"
L
Linus Torvalds 已提交
24 25 26
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_mount.h"
27
#include "xfs_da_format.h"
28
#include "xfs_da_btree.h"
L
Linus Torvalds 已提交
29 30
#include "xfs_inode.h"
#include "xfs_bmap.h"
31
#include "xfs_dir2.h"
C
Christoph Hellwig 已提交
32
#include "xfs_dir2_priv.h"
L
Linus Torvalds 已提交
33
#include "xfs_error.h"
C
Christoph Hellwig 已提交
34
#include "xfs_trace.h"
35
#include "xfs_trans.h"
36 37
#include "xfs_buf_item.h"
#include "xfs_cksum.h"
L
Linus Torvalds 已提交
38 39 40 41

/*
 * Local function declarations.
 */
42 43
static int xfs_dir2_leaf_lookup_int(xfs_da_args_t *args, struct xfs_buf **lbpp,
				    int *indexp, struct xfs_buf **dbpp);
44 45 46 47
static void xfs_dir3_leaf_log_bests(struct xfs_da_args *args,
				    struct xfs_buf *bp, int first, int last);
static void xfs_dir3_leaf_log_tail(struct xfs_da_args *args,
				   struct xfs_buf *bp);
48

49 50 51 52 53
/*
 * Check the internal consistency of a leaf1 block.
 * Pop an assert if something is wrong.
 */
#ifdef DEBUG
54
#define	xfs_dir3_leaf_check(dp, bp) \
55
do { \
56
	if (!xfs_dir3_leaf1_check((dp), (bp))) \
57 58 59 60 61
		ASSERT(0); \
} while (0);

STATIC bool
xfs_dir3_leaf1_check(
62
	struct xfs_inode	*dp,
63 64 65 66 67
	struct xfs_buf		*bp)
{
	struct xfs_dir2_leaf	*leaf = bp->b_addr;
	struct xfs_dir3_icleaf_hdr leafhdr;

68
	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
69 70 71 72 73 74 75 76

	if (leafhdr.magic == XFS_DIR3_LEAF1_MAGIC) {
		struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
		if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn)
			return false;
	} else if (leafhdr.magic != XFS_DIR2_LEAF1_MAGIC)
		return false;

77
	return xfs_dir3_leaf_check_int(dp->i_mount, dp, &leafhdr, leaf);
78 79
}
#else
80
#define	xfs_dir3_leaf_check(dp, bp)
81 82 83 84 85
#endif

bool
xfs_dir3_leaf_check_int(
	struct xfs_mount	*mp,
86
	struct xfs_inode	*dp,
87 88 89 90 91 92 93
	struct xfs_dir3_icleaf_hdr *hdr,
	struct xfs_dir2_leaf	*leaf)
{
	struct xfs_dir2_leaf_entry *ents;
	xfs_dir2_leaf_tail_t	*ltp;
	int			stale;
	int			i;
94
	const struct xfs_dir_ops *ops;
95
	struct xfs_dir3_icleaf_hdr leafhdr;
96
	struct xfs_da_geometry	*geo = mp->m_dir_geo;
97

98 99 100 101 102 103
	/*
	 * we can be passed a null dp here from a verifier, so we need to go the
	 * hard way to get them.
	 */
	ops = xfs_dir_get_ops(mp, dp);

104 105 106 107 108
	if (!hdr) {
		ops->leaf_hdr_from_disk(&leafhdr, leaf);
		hdr = &leafhdr;
	}

109
	ents = ops->leaf_ents_p(leaf);
110
	ltp = xfs_dir2_leaf_tail_p(geo, leaf);
111 112 113 114 115 116

	/*
	 * XXX (dgc): This value is not restrictive enough.
	 * Should factor in the size of the bests table as well.
	 * We can deduce a value for that from di_size.
	 */
117
	if (hdr->count > ops->leaf_max_ents(geo))
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
		return false;

	/* Leaves and bests don't overlap in leaf format. */
	if ((hdr->magic == XFS_DIR2_LEAF1_MAGIC ||
	     hdr->magic == XFS_DIR3_LEAF1_MAGIC) &&
	    (char *)&ents[hdr->count] > (char *)xfs_dir2_leaf_bests_p(ltp))
		return false;

	/* Check hash value order, count stale entries.  */
	for (i = stale = 0; i < hdr->count; i++) {
		if (i + 1 < hdr->count) {
			if (be32_to_cpu(ents[i].hashval) >
					be32_to_cpu(ents[i + 1].hashval))
				return false;
		}
		if (ents[i].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
			stale++;
	}
	if (hdr->stale != stale)
		return false;
	return true;
}

141 142 143 144 145
/*
 * We verify the magic numbers before decoding the leaf header so that on debug
 * kernels we don't get assertion failures in xfs_dir3_leaf_hdr_from_disk() due
 * to incorrect magic numbers.
 */
146 147
static bool
xfs_dir3_leaf_verify(
D
Dave Chinner 已提交
148
	struct xfs_buf		*bp,
149 150 151 152 153 154 155 156 157
	__uint16_t		magic)
{
	struct xfs_mount	*mp = bp->b_target->bt_mount;
	struct xfs_dir2_leaf	*leaf = bp->b_addr;

	ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC);

	if (xfs_sb_version_hascrc(&mp->m_sb)) {
		struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;
158
		__uint16_t		magic3;
159

160 161
		magic3 = (magic == XFS_DIR2_LEAF1_MAGIC) ? XFS_DIR3_LEAF1_MAGIC
							 : XFS_DIR3_LEAFN_MAGIC;
162

163 164
		if (leaf3->info.hdr.magic != cpu_to_be16(magic3))
			return false;
165 166 167 168 169
		if (!uuid_equal(&leaf3->info.uuid, &mp->m_sb.sb_uuid))
			return false;
		if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn)
			return false;
	} else {
170
		if (leaf->hdr.info.magic != cpu_to_be16(magic))
171 172
			return false;
	}
173

174
	return xfs_dir3_leaf_check_int(mp, NULL, NULL, leaf);
175 176 177 178 179 180 181 182 183
}

static void
__read_verify(
	struct xfs_buf  *bp,
	__uint16_t	magic)
{
	struct xfs_mount	*mp = bp->b_target->bt_mount;

184 185 186 187
	if (xfs_sb_version_hascrc(&mp->m_sb) &&
	     !xfs_buf_verify_cksum(bp, XFS_DIR3_LEAF_CRC_OFF))
		xfs_buf_ioerror(bp, EFSBADCRC);
	else if (!xfs_dir3_leaf_verify(bp, magic))
188
		xfs_buf_ioerror(bp, EFSCORRUPTED);
189 190 191

	if (bp->b_error)
		xfs_verifier_error(bp);
192 193 194 195 196 197
}

static void
__write_verify(
	struct xfs_buf  *bp,
	__uint16_t	magic)
D
Dave Chinner 已提交
198 199
{
	struct xfs_mount	*mp = bp->b_target->bt_mount;
200 201
	struct xfs_buf_log_item	*bip = bp->b_fspriv;
	struct xfs_dir3_leaf_hdr *hdr3 = bp->b_addr;
D
Dave Chinner 已提交
202

203
	if (!xfs_dir3_leaf_verify(bp, magic)) {
D
Dave Chinner 已提交
204
		xfs_buf_ioerror(bp, EFSCORRUPTED);
205
		xfs_verifier_error(bp);
206
		return;
D
Dave Chinner 已提交
207
	}
208 209 210 211 212 213 214

	if (!xfs_sb_version_hascrc(&mp->m_sb))
		return;

	if (bip)
		hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);

215
	xfs_buf_update_cksum(bp, XFS_DIR3_LEAF_CRC_OFF);
216
}
D
Dave Chinner 已提交
217

218
static void
219
xfs_dir3_leaf1_read_verify(
220 221
	struct xfs_buf	*bp)
{
222
	__read_verify(bp, XFS_DIR2_LEAF1_MAGIC);
223 224 225
}

static void
226
xfs_dir3_leaf1_write_verify(
227 228
	struct xfs_buf	*bp)
{
229
	__write_verify(bp, XFS_DIR2_LEAF1_MAGIC);
D
Dave Chinner 已提交
230 231
}

232 233
static void
xfs_dir3_leafn_read_verify(
234
	struct xfs_buf	*bp)
D
Dave Chinner 已提交
235
{
236
	__read_verify(bp, XFS_DIR2_LEAFN_MAGIC);
D
Dave Chinner 已提交
237 238
}

239 240
static void
xfs_dir3_leafn_write_verify(
241
	struct xfs_buf	*bp)
D
Dave Chinner 已提交
242
{
243
	__write_verify(bp, XFS_DIR2_LEAFN_MAGIC);
D
Dave Chinner 已提交
244 245
}

246
const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = {
247 248
	.verify_read = xfs_dir3_leaf1_read_verify,
	.verify_write = xfs_dir3_leaf1_write_verify,
249 250
};

251 252 253
const struct xfs_buf_ops xfs_dir3_leafn_buf_ops = {
	.verify_read = xfs_dir3_leafn_read_verify,
	.verify_write = xfs_dir3_leafn_write_verify,
254 255
};

D
Dave Chinner 已提交
256
static int
257
xfs_dir3_leaf_read(
D
Dave Chinner 已提交
258 259 260 261 262 263
	struct xfs_trans	*tp,
	struct xfs_inode	*dp,
	xfs_dablk_t		fbno,
	xfs_daddr_t		mappedbno,
	struct xfs_buf		**bpp)
{
264 265 266
	int			err;

	err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
267
				XFS_DATA_FORK, &xfs_dir3_leaf1_buf_ops);
268
	if (!err && tp)
269
		xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_LEAF1_BUF);
270
	return err;
D
Dave Chinner 已提交
271 272 273
}

int
274
xfs_dir3_leafn_read(
D
Dave Chinner 已提交
275 276 277 278 279 280
	struct xfs_trans	*tp,
	struct xfs_inode	*dp,
	xfs_dablk_t		fbno,
	xfs_daddr_t		mappedbno,
	struct xfs_buf		**bpp)
{
281 282 283
	int			err;

	err = xfs_da_read_buf(tp, dp, fbno, mappedbno, bpp,
284
				XFS_DATA_FORK, &xfs_dir3_leafn_buf_ops);
285
	if (!err && tp)
286
		xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_LEAFN_BUF);
287
	return err;
288 289 290 291 292 293 294 295
}

/*
 * Initialize a new leaf block, leaf1 or leafn magic accepted.
 */
static void
xfs_dir3_leaf_init(
	struct xfs_mount	*mp,
296
	struct xfs_trans	*tp,
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
	struct xfs_buf		*bp,
	xfs_ino_t		owner,
	__uint16_t		type)
{
	struct xfs_dir2_leaf	*leaf = bp->b_addr;

	ASSERT(type == XFS_DIR2_LEAF1_MAGIC || type == XFS_DIR2_LEAFN_MAGIC);

	if (xfs_sb_version_hascrc(&mp->m_sb)) {
		struct xfs_dir3_leaf_hdr *leaf3 = bp->b_addr;

		memset(leaf3, 0, sizeof(*leaf3));

		leaf3->info.hdr.magic = (type == XFS_DIR2_LEAF1_MAGIC)
					 ? cpu_to_be16(XFS_DIR3_LEAF1_MAGIC)
					 : cpu_to_be16(XFS_DIR3_LEAFN_MAGIC);
		leaf3->info.blkno = cpu_to_be64(bp->b_bn);
		leaf3->info.owner = cpu_to_be64(owner);
		uuid_copy(&leaf3->info.uuid, &mp->m_sb.sb_uuid);
	} else {
		memset(leaf, 0, sizeof(*leaf));
		leaf->hdr.info.magic = cpu_to_be16(type);
	}

	/*
	 * If it's a leaf-format directory initialize the tail.
	 * Caller is responsible for initialising the bests table.
	 */
	if (type == XFS_DIR2_LEAF1_MAGIC) {
		struct xfs_dir2_leaf_tail *ltp;

328
		ltp = xfs_dir2_leaf_tail_p(mp->m_dir_geo, leaf);
329 330
		ltp->bestcount = 0;
		bp->b_ops = &xfs_dir3_leaf1_buf_ops;
331
		xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAF1_BUF);
332
	} else {
333
		bp->b_ops = &xfs_dir3_leafn_buf_ops;
334
		xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DIR_LEAFN_BUF);
335
	}
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
}

int
xfs_dir3_leaf_get_buf(
	xfs_da_args_t		*args,
	xfs_dir2_db_t		bno,
	struct xfs_buf		**bpp,
	__uint16_t		magic)
{
	struct xfs_inode	*dp = args->dp;
	struct xfs_trans	*tp = args->trans;
	struct xfs_mount	*mp = dp->i_mount;
	struct xfs_buf		*bp;
	int			error;

	ASSERT(magic == XFS_DIR2_LEAF1_MAGIC || magic == XFS_DIR2_LEAFN_MAGIC);
352 353
	ASSERT(bno >= xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET) &&
	       bno < xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET));
354

355 356
	error = xfs_da_get_buf(tp, dp, xfs_dir2_db_to_da(args->geo, bno),
			       -1, &bp, XFS_DATA_FORK);
357 358 359
	if (error)
		return error;

360
	xfs_dir3_leaf_init(mp, tp, bp, dp->i_ino, magic);
361
	xfs_dir3_leaf_log_header(args, bp);
362
	if (magic == XFS_DIR2_LEAF1_MAGIC)
363
		xfs_dir3_leaf_log_tail(args, bp);
364 365
	*bpp = bp;
	return 0;
D
Dave Chinner 已提交
366
}
L
Linus Torvalds 已提交
367 368 369 370 371 372 373

/*
 * Convert a block form directory to a leaf form directory.
 */
int						/* error */
xfs_dir2_block_to_leaf(
	xfs_da_args_t		*args,		/* operation arguments */
374
	struct xfs_buf		*dbp)		/* input block's buffer */
L
Linus Torvalds 已提交
375
{
376
	__be16			*bestsp;	/* leaf's bestsp entries */
L
Linus Torvalds 已提交
377
	xfs_dablk_t		blkno;		/* leaf block's bno */
378
	xfs_dir2_data_hdr_t	*hdr;		/* block header */
L
Linus Torvalds 已提交
379 380 381 382
	xfs_dir2_leaf_entry_t	*blp;		/* block's leaf entries */
	xfs_dir2_block_tail_t	*btp;		/* block's tail */
	xfs_inode_t		*dp;		/* incore directory inode */
	int			error;		/* error return code */
383
	struct xfs_buf		*lbp;		/* leaf block's buffer */
L
Linus Torvalds 已提交
384 385 386 387 388 389 390
	xfs_dir2_db_t		ldb;		/* leaf block's bno */
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
	xfs_dir2_leaf_tail_t	*ltp;		/* leaf's tail */
	xfs_mount_t		*mp;		/* filesystem mount point */
	int			needlog;	/* need to log block header */
	int			needscan;	/* need to rescan bestfree */
	xfs_trans_t		*tp;		/* transaction pointer */
391
	struct xfs_dir2_data_free *bf;
392 393
	struct xfs_dir2_leaf_entry *ents;
	struct xfs_dir3_icleaf_hdr leafhdr;
L
Linus Torvalds 已提交
394

C
Christoph Hellwig 已提交
395 396
	trace_xfs_dir2_block_to_leaf(args);

L
Linus Torvalds 已提交
397 398 399 400 401 402 403 404 405 406 407
	dp = args->dp;
	mp = dp->i_mount;
	tp = args->trans;
	/*
	 * Add the leaf block to the inode.
	 * This interface will only put blocks in the leaf/node range.
	 * Since that's empty now, we'll get the root (block 0 in range).
	 */
	if ((error = xfs_da_grow_inode(args, &blkno))) {
		return error;
	}
408
	ldb = xfs_dir2_da_to_db(args->geo, blkno);
409
	ASSERT(ldb == xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET));
L
Linus Torvalds 已提交
410 411 412
	/*
	 * Initialize the leaf block, get a buffer for it.
	 */
413 414
	error = xfs_dir3_leaf_get_buf(args, ldb, &lbp, XFS_DIR2_LEAF1_MAGIC);
	if (error)
L
Linus Torvalds 已提交
415
		return error;
416

417 418
	leaf = lbp->b_addr;
	hdr = dbp->b_addr;
419
	xfs_dir3_data_check(dp, dbp);
420
	btp = xfs_dir2_block_tail_p(args->geo, hdr);
421
	blp = xfs_dir2_block_leaf_p(btp);
422
	bf = dp->d_ops->data_bestfree_p(hdr);
423
	ents = dp->d_ops->leaf_ents_p(leaf);
424

L
Linus Torvalds 已提交
425 426 427
	/*
	 * Set the counts in the leaf header.
	 */
428
	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
429 430
	leafhdr.count = be32_to_cpu(btp->count);
	leafhdr.stale = be32_to_cpu(btp->stale);
431
	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
432
	xfs_dir3_leaf_log_header(args, lbp);
433

L
Linus Torvalds 已提交
434 435 436 437
	/*
	 * Could compact these but I think we always do the conversion
	 * after squeezing out stale entries.
	 */
438
	memcpy(ents, blp, be32_to_cpu(btp->count) * sizeof(xfs_dir2_leaf_entry_t));
439
	xfs_dir3_leaf_log_ents(args, lbp, 0, leafhdr.count - 1);
L
Linus Torvalds 已提交
440 441 442 443 444 445
	needscan = 0;
	needlog = 1;
	/*
	 * Make the space formerly occupied by the leaf entries and block
	 * tail be free.
	 */
446
	xfs_dir2_data_make_free(args, dbp,
447
		(xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr),
448
		(xfs_dir2_data_aoff_t)((char *)hdr + args->geo->blksize -
L
Linus Torvalds 已提交
449 450 451 452 453
				       (char *)blp),
		&needlog, &needscan);
	/*
	 * Fix up the block header, make it a data block.
	 */
454
	dbp->b_ops = &xfs_dir3_data_buf_ops;
455
	xfs_trans_buf_set_type(tp, dbp, XFS_BLFT_DIR_DATA_BUF);
456 457 458 459 460
	if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC))
		hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC);
	else
		hdr->magic = cpu_to_be32(XFS_DIR3_DATA_MAGIC);

L
Linus Torvalds 已提交
461
	if (needscan)
462
		xfs_dir2_data_freescan(dp, hdr, &needlog);
L
Linus Torvalds 已提交
463 464 465
	/*
	 * Set up leaf tail and bests table.
	 */
466
	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
467
	ltp->bestcount = cpu_to_be32(1);
468
	bestsp = xfs_dir2_leaf_bests_p(ltp);
469
	bestsp[0] =  bf[0].length;
L
Linus Torvalds 已提交
470 471 472 473
	/*
	 * Log the data header and leaf bests table.
	 */
	if (needlog)
474
		xfs_dir2_data_log_header(args, dbp);
475
	xfs_dir3_leaf_check(dp, lbp);
476
	xfs_dir3_data_check(dp, dbp);
477
	xfs_dir3_leaf_log_bests(args, lbp, 0, 0);
L
Linus Torvalds 已提交
478 479 480
	return 0;
}

481
STATIC void
482 483 484
xfs_dir3_leaf_find_stale(
	struct xfs_dir3_icleaf_hdr *leafhdr,
	struct xfs_dir2_leaf_entry *ents,
485 486 487 488 489 490 491 492
	int			index,
	int			*lowstale,
	int			*highstale)
{
	/*
	 * Find the first stale entry before our index, if any.
	 */
	for (*lowstale = index - 1; *lowstale >= 0; --*lowstale) {
493
		if (ents[*lowstale].address ==
494 495 496 497 498 499 500 501 502
		    cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
			break;
	}

	/*
	 * Find the first stale entry at or after our index, if any.
	 * Stop if the result would require moving more entries than using
	 * lowstale.
	 */
503 504
	for (*highstale = index; *highstale < leafhdr->count; ++*highstale) {
		if (ents[*highstale].address ==
505 506 507 508 509 510 511
		    cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
			break;
		if (*lowstale >= 0 && index - *lowstale <= *highstale - index)
			break;
	}
}

512
struct xfs_dir2_leaf_entry *
513 514 515
xfs_dir3_leaf_find_entry(
	struct xfs_dir3_icleaf_hdr *leafhdr,
	struct xfs_dir2_leaf_entry *ents,
516 517 518 519 520 521 522
	int			index,		/* leaf table position */
	int			compact,	/* need to compact leaves */
	int			lowstale,	/* index of prev stale leaf */
	int			highstale,	/* index of next stale leaf */
	int			*lfloglow,	/* low leaf logging index */
	int			*lfloghigh)	/* high leaf logging index */
{
523
	if (!leafhdr->stale) {
524 525 526 527 528 529 530
		xfs_dir2_leaf_entry_t	*lep;	/* leaf entry table pointer */

		/*
		 * Now we need to make room to insert the leaf entry.
		 *
		 * If there are no stale entries, just insert a hole at index.
		 */
531 532
		lep = &ents[index];
		if (index < leafhdr->count)
533
			memmove(lep + 1, lep,
534
				(leafhdr->count - index) * sizeof(*lep));
535 536 537 538 539

		/*
		 * Record low and high logging indices for the leaf.
		 */
		*lfloglow = index;
540
		*lfloghigh = leafhdr->count++;
541 542 543 544 545 546 547 548 549 550 551 552
		return lep;
	}

	/*
	 * There are stale entries.
	 *
	 * We will use one of them for the new entry.  It's probably not at
	 * the right location, so we'll have to shift some up or down first.
	 *
	 * If we didn't compact before, we need to find the nearest stale
	 * entries before and after our insertion point.
	 */
553
	if (compact == 0)
554 555
		xfs_dir3_leaf_find_stale(leafhdr, ents, index,
					 &lowstale, &highstale);
556 557 558 559 560

	/*
	 * If the low one is better, use it.
	 */
	if (lowstale >= 0 &&
561
	    (highstale == leafhdr->count ||
562 563
	     index - lowstale - 1 < highstale - index)) {
		ASSERT(index - lowstale - 1 >= 0);
564
		ASSERT(ents[lowstale].address ==
565
		       cpu_to_be32(XFS_DIR2_NULL_DATAPTR));
566 567 568 569 570 571

		/*
		 * Copy entries up to cover the stale entry and make room
		 * for the new entry.
		 */
		if (index - lowstale - 1 > 0) {
572
			memmove(&ents[lowstale], &ents[lowstale + 1],
573
				(index - lowstale - 1) *
574
					sizeof(xfs_dir2_leaf_entry_t));
575 576 577
		}
		*lfloglow = MIN(lowstale, *lfloglow);
		*lfloghigh = MAX(index - 1, *lfloghigh);
578 579
		leafhdr->stale--;
		return &ents[index - 1];
580 581 582 583 584 585
	}

	/*
	 * The high one is better, so use that one.
	 */
	ASSERT(highstale - index >= 0);
586
	ASSERT(ents[highstale].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR));
587 588 589 590 591 592

	/*
	 * Copy entries down to cover the stale entry and make room for the
	 * new entry.
	 */
	if (highstale - index > 0) {
593
		memmove(&ents[index + 1], &ents[index],
594 595 596 597
			(highstale - index) * sizeof(xfs_dir2_leaf_entry_t));
	}
	*lfloglow = MIN(index, *lfloglow);
	*lfloghigh = MAX(highstale, *lfloghigh);
598 599
	leafhdr->stale--;
	return &ents[index];
600 601
}

L
Linus Torvalds 已提交
602 603 604 605 606 607 608
/*
 * Add an entry to a leaf form directory.
 */
int						/* error */
xfs_dir2_leaf_addname(
	xfs_da_args_t		*args)		/* operation arguments */
{
609
	__be16			*bestsp;	/* freespace table in leaf */
L
Linus Torvalds 已提交
610
	int			compact;	/* need to compact leaves */
611
	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
612
	struct xfs_buf		*dbp;		/* data block buffer */
L
Linus Torvalds 已提交
613 614 615 616 617 618 619 620
	xfs_dir2_data_entry_t	*dep;		/* data block entry */
	xfs_inode_t		*dp;		/* incore directory inode */
	xfs_dir2_data_unused_t	*dup;		/* data unused entry */
	int			error;		/* error return value */
	int			grown;		/* allocated new data block */
	int			highstale;	/* index of next stale leaf */
	int			i;		/* temporary, index */
	int			index;		/* leaf table position */
621
	struct xfs_buf		*lbp;		/* leaf's buffer */
L
Linus Torvalds 已提交
622 623 624 625 626 627 628 629 630 631 632
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
	int			length;		/* length of new entry */
	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry table pointer */
	int			lfloglow;	/* low leaf logging index */
	int			lfloghigh;	/* high leaf logging index */
	int			lowstale;	/* index of prev stale leaf */
	xfs_dir2_leaf_tail_t	*ltp;		/* leaf tail pointer */
	xfs_mount_t		*mp;		/* filesystem mount point */
	int			needbytes;	/* leaf block bytes needed */
	int			needlog;	/* need to log data header */
	int			needscan;	/* need to rescan data free */
633
	__be16			*tagp;		/* end of data entry */
L
Linus Torvalds 已提交
634 635
	xfs_trans_t		*tp;		/* transaction pointer */
	xfs_dir2_db_t		use_block;	/* data block number */
636
	struct xfs_dir2_data_free *bf;		/* bestfree table */
637 638
	struct xfs_dir2_leaf_entry *ents;
	struct xfs_dir3_icleaf_hdr leafhdr;
L
Linus Torvalds 已提交
639

C
Christoph Hellwig 已提交
640 641
	trace_xfs_dir2_leaf_addname(args);

L
Linus Torvalds 已提交
642 643 644
	dp = args->dp;
	tp = args->trans;
	mp = dp->i_mount;
D
Dave Chinner 已提交
645

646
	error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp);
647
	if (error)
L
Linus Torvalds 已提交
648
		return error;
D
Dave Chinner 已提交
649

L
Linus Torvalds 已提交
650 651 652 653 654 655 656
	/*
	 * Look up the entry by hash value and name.
	 * We know it's not there, our caller has already done a lookup.
	 * So the index is of the entry to insert in front of.
	 * But if there are dup hash values the index is of the first of those.
	 */
	index = xfs_dir2_leaf_search_hash(args, lbp);
657
	leaf = lbp->b_addr;
658
	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
659
	ents = dp->d_ops->leaf_ents_p(leaf);
660
	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
661
	bestsp = xfs_dir2_leaf_bests_p(ltp);
662
	length = dp->d_ops->data_entsize(args->namelen);
663

L
Linus Torvalds 已提交
664 665 666 667 668 669
	/*
	 * See if there are any entries with the same hash value
	 * and space in their block for the new entry.
	 * This is good because it puts multiple same-hash value entries
	 * in a data block, improving the lookup of those entries.
	 */
670 671
	for (use_block = -1, lep = &ents[index];
	     index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
L
Linus Torvalds 已提交
672
	     index++, lep++) {
673
		if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
L
Linus Torvalds 已提交
674
			continue;
675
		i = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
676
		ASSERT(i < be32_to_cpu(ltp->bestcount));
677
		ASSERT(bestsp[i] != cpu_to_be16(NULLDATAOFF));
678
		if (be16_to_cpu(bestsp[i]) >= length) {
L
Linus Torvalds 已提交
679 680 681 682 683 684 685 686
			use_block = i;
			break;
		}
	}
	/*
	 * Didn't find a block yet, linear search all the data blocks.
	 */
	if (use_block == -1) {
687
		for (i = 0; i < be32_to_cpu(ltp->bestcount); i++) {
L
Linus Torvalds 已提交
688 689 690
			/*
			 * Remember a block we see that's missing.
			 */
691 692
			if (bestsp[i] == cpu_to_be16(NULLDATAOFF) &&
			    use_block == -1)
L
Linus Torvalds 已提交
693
				use_block = i;
694
			else if (be16_to_cpu(bestsp[i]) >= length) {
L
Linus Torvalds 已提交
695 696 697 698 699 700 701 702
				use_block = i;
				break;
			}
		}
	}
	/*
	 * How many bytes do we need in the leaf block?
	 */
703
	needbytes = 0;
704
	if (!leafhdr.stale)
705 706 707 708
		needbytes += sizeof(xfs_dir2_leaf_entry_t);
	if (use_block == -1)
		needbytes += sizeof(xfs_dir2_data_off_t);

L
Linus Torvalds 已提交
709 710 711 712
	/*
	 * Now kill use_block if it refers to a missing block, so we
	 * can use it as an indication of allocation needed.
	 */
713
	if (use_block != -1 && bestsp[use_block] == cpu_to_be16(NULLDATAOFF))
L
Linus Torvalds 已提交
714 715 716 717 718
		use_block = -1;
	/*
	 * If we don't have enough free bytes but we can make enough
	 * by compacting out stale entries, we'll do that.
	 */
719 720
	if ((char *)bestsp - (char *)&ents[leafhdr.count] < needbytes &&
	    leafhdr.stale > 1)
L
Linus Torvalds 已提交
721
		compact = 1;
722

L
Linus Torvalds 已提交
723 724 725 726
	/*
	 * Otherwise if we don't have enough free bytes we need to
	 * convert to node form.
	 */
727
	else if ((char *)bestsp - (char *)&ents[leafhdr.count] < needbytes) {
L
Linus Torvalds 已提交
728 729 730
		/*
		 * Just checking or no space reservation, give up.
		 */
731 732
		if ((args->op_flags & XFS_DA_OP_JUSTCHECK) ||
							args->total == 0) {
733
			xfs_trans_brelse(tp, lbp);
E
Eric Sandeen 已提交
734
			return ENOSPC;
L
Linus Torvalds 已提交
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
		}
		/*
		 * Convert to node form.
		 */
		error = xfs_dir2_leaf_to_node(args, lbp);
		if (error)
			return error;
		/*
		 * Then add the new entry.
		 */
		return xfs_dir2_node_addname(args);
	}
	/*
	 * Otherwise it will fit without compaction.
	 */
	else
		compact = 0;
	/*
	 * If just checking, then it will fit unless we needed to allocate
	 * a new data block.
	 */
756
	if (args->op_flags & XFS_DA_OP_JUSTCHECK) {
757
		xfs_trans_brelse(tp, lbp);
E
Eric Sandeen 已提交
758
		return use_block == -1 ? ENOSPC : 0;
L
Linus Torvalds 已提交
759 760 761 762 763 764
	}
	/*
	 * If no allocations are allowed, return now before we've
	 * changed anything.
	 */
	if (args->total == 0 && use_block == -1) {
765
		xfs_trans_brelse(tp, lbp);
E
Eric Sandeen 已提交
766
		return ENOSPC;
L
Linus Torvalds 已提交
767 768 769 770 771 772 773 774
	}
	/*
	 * Need to compact the leaf entries, removing stale ones.
	 * Leave one stale entry behind - the one closest to our
	 * insertion index - and we'll shift that one to our insertion
	 * point later.
	 */
	if (compact) {
775 776
		xfs_dir3_leaf_compact_x1(&leafhdr, ents, &index, &lowstale,
			&highstale, &lfloglow, &lfloghigh);
L
Linus Torvalds 已提交
777 778 779 780 781
	}
	/*
	 * There are stale entries, so we'll need log-low and log-high
	 * impossibly bad values later.
	 */
782 783
	else if (leafhdr.stale) {
		lfloglow = leafhdr.count;
L
Linus Torvalds 已提交
784 785 786 787 788 789 790 791 792 793 794 795
		lfloghigh = -1;
	}
	/*
	 * If there was no data block space found, we need to allocate
	 * a new one.
	 */
	if (use_block == -1) {
		/*
		 * Add the new data block.
		 */
		if ((error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE,
				&use_block))) {
796
			xfs_trans_brelse(tp, lbp);
L
Linus Torvalds 已提交
797 798 799 800 801
			return error;
		}
		/*
		 * Initialize the block.
		 */
802
		if ((error = xfs_dir3_data_init(args, use_block, &dbp))) {
803
			xfs_trans_brelse(tp, lbp);
L
Linus Torvalds 已提交
804 805 806 807 808 809
			return error;
		}
		/*
		 * If we're adding a new data block on the end we need to
		 * extend the bests table.  Copy it up one entry.
		 */
810
		if (use_block >= be32_to_cpu(ltp->bestcount)) {
L
Linus Torvalds 已提交
811 812
			bestsp--;
			memmove(&bestsp[0], &bestsp[1],
813
				be32_to_cpu(ltp->bestcount) * sizeof(bestsp[0]));
814
			be32_add_cpu(&ltp->bestcount, 1);
815 816 817
			xfs_dir3_leaf_log_tail(args, lbp);
			xfs_dir3_leaf_log_bests(args, lbp, 0,
						be32_to_cpu(ltp->bestcount) - 1);
L
Linus Torvalds 已提交
818 819 820 821 822
		}
		/*
		 * If we're filling in a previously empty block just log it.
		 */
		else
823
			xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
824
		hdr = dbp->b_addr;
825
		bf = dp->d_ops->data_bestfree_p(hdr);
826
		bestsp[use_block] = bf[0].length;
L
Linus Torvalds 已提交
827
		grown = 1;
828 829 830 831 832
	} else {
		/*
		 * Already had space in some data block.
		 * Just read that one in.
		 */
833
		error = xfs_dir3_data_read(tp, dp,
834 835
				   xfs_dir2_db_to_da(args->geo, use_block),
				   -1, &dbp);
836
		if (error) {
837
			xfs_trans_brelse(tp, lbp);
L
Linus Torvalds 已提交
838 839
			return error;
		}
840
		hdr = dbp->b_addr;
841
		bf = dp->d_ops->data_bestfree_p(hdr);
L
Linus Torvalds 已提交
842 843 844 845 846 847
		grown = 0;
	}
	/*
	 * Point to the biggest freespace in our data block.
	 */
	dup = (xfs_dir2_data_unused_t *)
848
	      ((char *)hdr + be16_to_cpu(bf[0].offset));
849
	ASSERT(be16_to_cpu(dup->length) >= length);
L
Linus Torvalds 已提交
850 851 852 853
	needscan = needlog = 0;
	/*
	 * Mark the initial part of our freespace in use for the new entry.
	 */
854
	xfs_dir2_data_use_free(args, dbp, dup,
855
		(xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length,
L
Linus Torvalds 已提交
856 857 858 859 860
		&needlog, &needscan);
	/*
	 * Initialize our new entry (at last).
	 */
	dep = (xfs_dir2_data_entry_t *)dup;
861
	dep->inumber = cpu_to_be64(args->inumber);
L
Linus Torvalds 已提交
862 863
	dep->namelen = args->namelen;
	memcpy(dep->name, args->name, dep->namelen);
864 865
	dp->d_ops->data_put_ftype(dep, args->filetype);
	tagp = dp->d_ops->data_entry_tag_p(dep);
866
	*tagp = cpu_to_be16((char *)dep - (char *)hdr);
L
Linus Torvalds 已提交
867 868 869 870
	/*
	 * Need to scan fix up the bestfree table.
	 */
	if (needscan)
871
		xfs_dir2_data_freescan(dp, hdr, &needlog);
L
Linus Torvalds 已提交
872 873 874 875
	/*
	 * Need to log the data block's header.
	 */
	if (needlog)
876 877
		xfs_dir2_data_log_header(args, dbp);
	xfs_dir2_data_log_entry(args, dbp, dep);
L
Linus Torvalds 已提交
878 879 880 881
	/*
	 * If the bests table needs to be changed, do it.
	 * Log the change unless we've already done that.
	 */
882 883
	if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(bf[0].length)) {
		bestsp[use_block] = bf[0].length;
L
Linus Torvalds 已提交
884
		if (!grown)
885
			xfs_dir3_leaf_log_bests(args, lbp, use_block, use_block);
L
Linus Torvalds 已提交
886
	}
887

888
	lep = xfs_dir3_leaf_find_entry(&leafhdr, ents, index, compact, lowstale,
889 890
				       highstale, &lfloglow, &lfloghigh);

L
Linus Torvalds 已提交
891 892 893
	/*
	 * Fill in the new leaf entry.
	 */
894
	lep->hashval = cpu_to_be32(args->hashval);
895 896
	lep->address = cpu_to_be32(
				xfs_dir2_db_off_to_dataptr(args->geo, use_block,
897
				be16_to_cpu(*tagp)));
L
Linus Torvalds 已提交
898 899 900
	/*
	 * Log the leaf fields and give up the buffers.
	 */
901
	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
902 903
	xfs_dir3_leaf_log_header(args, lbp);
	xfs_dir3_leaf_log_ents(args, lbp, lfloglow, lfloghigh);
904
	xfs_dir3_leaf_check(dp, lbp);
905
	xfs_dir3_data_check(dp, dbp);
L
Linus Torvalds 已提交
906 907 908 909 910 911 912 913
	return 0;
}

/*
 * Compact out any stale entries in the leaf.
 * Log the header and changed leaf entries, if any.
 */
void
914
xfs_dir3_leaf_compact(
L
Linus Torvalds 已提交
915
	xfs_da_args_t	*args,		/* operation arguments */
916
	struct xfs_dir3_icleaf_hdr *leafhdr,
917
	struct xfs_buf	*bp)		/* leaf buffer */
L
Linus Torvalds 已提交
918 919 920 921 922
{
	int		from;		/* source leaf index */
	xfs_dir2_leaf_t	*leaf;		/* leaf structure */
	int		loglow;		/* first leaf entry to log */
	int		to;		/* target leaf index */
923
	struct xfs_dir2_leaf_entry *ents;
924
	struct xfs_inode *dp = args->dp;
L
Linus Torvalds 已提交
925

926
	leaf = bp->b_addr;
927
	if (!leafhdr->stale)
L
Linus Torvalds 已提交
928
		return;
929

L
Linus Torvalds 已提交
930 931 932
	/*
	 * Compress out the stale entries in place.
	 */
933
	ents = dp->d_ops->leaf_ents_p(leaf);
934 935
	for (from = to = 0, loglow = -1; from < leafhdr->count; from++) {
		if (ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR))
L
Linus Torvalds 已提交
936 937 938 939 940 941 942
			continue;
		/*
		 * Only actually copy the entries that are different.
		 */
		if (from > to) {
			if (loglow == -1)
				loglow = to;
943
			ents[to] = ents[from];
L
Linus Torvalds 已提交
944 945 946 947 948 949
		}
		to++;
	}
	/*
	 * Update and log the header, log the leaf entries.
	 */
950 951 952 953
	ASSERT(leafhdr->stale == from - to);
	leafhdr->count -= leafhdr->stale;
	leafhdr->stale = 0;

954
	dp->d_ops->leaf_hdr_to_disk(leaf, leafhdr);
955
	xfs_dir3_leaf_log_header(args, bp);
L
Linus Torvalds 已提交
956
	if (loglow != -1)
957
		xfs_dir3_leaf_log_ents(args, bp, loglow, to - 1);
L
Linus Torvalds 已提交
958 959 960 961 962 963 964 965 966 967 968
}

/*
 * Compact the leaf entries, removing stale ones.
 * Leave one stale entry behind - the one closest to our
 * insertion index - and the caller will shift that one to our insertion
 * point later.
 * Return new insertion index, where the remaining stale entry is,
 * and leaf logging indices.
 */
void
969 970 971
xfs_dir3_leaf_compact_x1(
	struct xfs_dir3_icleaf_hdr *leafhdr,
	struct xfs_dir2_leaf_entry *ents,
L
Linus Torvalds 已提交
972 973 974 975 976 977 978 979 980 981 982 983 984 985
	int		*indexp,	/* insertion index */
	int		*lowstalep,	/* out: stale entry before us */
	int		*highstalep,	/* out: stale entry after us */
	int		*lowlogp,	/* out: low log index */
	int		*highlogp)	/* out: high log index */
{
	int		from;		/* source copy index */
	int		highstale;	/* stale entry at/after index */
	int		index;		/* insertion index */
	int		keepstale;	/* source index of kept stale */
	int		lowstale;	/* stale entry before index */
	int		newindex=0;	/* new insertion index */
	int		to;		/* destination copy index */

986
	ASSERT(leafhdr->stale > 1);
L
Linus Torvalds 已提交
987
	index = *indexp;
988

989
	xfs_dir3_leaf_find_stale(leafhdr, ents, index, &lowstale, &highstale);
990

L
Linus Torvalds 已提交
991 992 993 994
	/*
	 * Pick the better of lowstale and highstale.
	 */
	if (lowstale >= 0 &&
995
	    (highstale == leafhdr->count ||
L
Linus Torvalds 已提交
996 997 998 999 1000 1001 1002 1003
	     index - lowstale <= highstale - index))
		keepstale = lowstale;
	else
		keepstale = highstale;
	/*
	 * Copy the entries in place, removing all the stale entries
	 * except keepstale.
	 */
1004
	for (from = to = 0; from < leafhdr->count; from++) {
L
Linus Torvalds 已提交
1005 1006 1007 1008 1009 1010
		/*
		 * Notice the new value of index.
		 */
		if (index == from)
			newindex = to;
		if (from != keepstale &&
1011
		    ents[from].address == cpu_to_be32(XFS_DIR2_NULL_DATAPTR)) {
L
Linus Torvalds 已提交
1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024
			if (from == to)
				*lowlogp = to;
			continue;
		}
		/*
		 * Record the new keepstale value for the insertion.
		 */
		if (from == keepstale)
			lowstale = highstale = to;
		/*
		 * Copy only the entries that have moved.
		 */
		if (from > to)
1025
			ents[to] = ents[from];
L
Linus Torvalds 已提交
1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038
		to++;
	}
	ASSERT(from > to);
	/*
	 * If the insertion point was past the last entry,
	 * set the new insertion point accordingly.
	 */
	if (index == from)
		newindex = to;
	*indexp = newindex;
	/*
	 * Adjust the leaf header values.
	 */
1039 1040
	leafhdr->count -= from - to;
	leafhdr->stale = 1;
L
Linus Torvalds 已提交
1041 1042 1043 1044 1045 1046 1047
	/*
	 * Remember the low/high stale value only in the "right"
	 * direction.
	 */
	if (lowstale >= newindex)
		lowstale = -1;
	else
1048 1049
		highstale = leafhdr->count;
	*highlogp = leafhdr->count - 1;
L
Linus Torvalds 已提交
1050 1051 1052 1053 1054 1055 1056
	*lowstalep = lowstale;
	*highstalep = highstale;
}

/*
 * Log the bests entries indicated from a leaf1 block.
 */
1057
static void
1058
xfs_dir3_leaf_log_bests(
1059
	struct xfs_da_args	*args,
1060
	struct xfs_buf		*bp,		/* leaf buffer */
L
Linus Torvalds 已提交
1061 1062 1063
	int			first,		/* first entry to log */
	int			last)		/* last entry to log */
{
1064 1065
	__be16			*firstb;	/* pointer to first entry */
	__be16			*lastb;		/* pointer to last entry */
1066
	struct xfs_dir2_leaf	*leaf = bp->b_addr;
L
Linus Torvalds 已提交
1067 1068
	xfs_dir2_leaf_tail_t	*ltp;		/* leaf tail structure */

1069 1070 1071
	ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC));

1072
	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
1073 1074
	firstb = xfs_dir2_leaf_bests_p(ltp) + first;
	lastb = xfs_dir2_leaf_bests_p(ltp) + last;
1075 1076
	xfs_trans_log_buf(args->trans, bp,
		(uint)((char *)firstb - (char *)leaf),
L
Linus Torvalds 已提交
1077 1078 1079 1080 1081 1082 1083
		(uint)((char *)lastb - (char *)leaf + sizeof(*lastb) - 1));
}

/*
 * Log the leaf entries indicated from a leaf1 or leafn block.
 */
void
1084
xfs_dir3_leaf_log_ents(
1085
	struct xfs_da_args	*args,
1086 1087 1088
	struct xfs_buf		*bp,
	int			first,
	int			last)
L
Linus Torvalds 已提交
1089 1090 1091
{
	xfs_dir2_leaf_entry_t	*firstlep;	/* pointer to first entry */
	xfs_dir2_leaf_entry_t	*lastlep;	/* pointer to last entry */
1092 1093
	struct xfs_dir2_leaf	*leaf = bp->b_addr;
	struct xfs_dir2_leaf_entry *ents;
L
Linus Torvalds 已提交
1094

1095
	ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
1096 1097 1098 1099
	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));

1100
	ents = args->dp->d_ops->leaf_ents_p(leaf);
1101 1102
	firstlep = &ents[first];
	lastlep = &ents[last];
1103 1104
	xfs_trans_log_buf(args->trans, bp,
		(uint)((char *)firstlep - (char *)leaf),
L
Linus Torvalds 已提交
1105 1106 1107 1108 1109 1110 1111
		(uint)((char *)lastlep - (char *)leaf + sizeof(*lastlep) - 1));
}

/*
 * Log the header of the leaf1 or leafn block.
 */
void
1112
xfs_dir3_leaf_log_header(
1113
	struct xfs_da_args	*args,
1114
	struct xfs_buf		*bp)
L
Linus Torvalds 已提交
1115
{
1116
	struct xfs_dir2_leaf	*leaf = bp->b_addr;
L
Linus Torvalds 已提交
1117

1118
	ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
1119 1120 1121 1122
	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));

1123 1124 1125
	xfs_trans_log_buf(args->trans, bp,
			  (uint)((char *)&leaf->hdr - (char *)leaf),
			  args->dp->d_ops->leaf_hdr_size - 1);
L
Linus Torvalds 已提交
1126 1127 1128 1129 1130
}

/*
 * Log the tail of the leaf1 block.
 */
1131
STATIC void
1132
xfs_dir3_leaf_log_tail(
1133
	struct xfs_da_args	*args,
1134
	struct xfs_buf		*bp)
L
Linus Torvalds 已提交
1135
{
1136
	struct xfs_dir2_leaf	*leaf = bp->b_addr;
L
Linus Torvalds 已提交
1137
	xfs_dir2_leaf_tail_t	*ltp;		/* leaf tail structure */
1138 1139 1140 1141 1142

	ASSERT(leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAF1_MAGIC) ||
	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) ||
	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR2_LEAFN_MAGIC) ||
	       leaf->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC));
L
Linus Torvalds 已提交
1143

1144 1145 1146
	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
	xfs_trans_log_buf(args->trans, bp, (uint)((char *)ltp - (char *)leaf),
		(uint)(args->geo->blksize - 1));
L
Linus Torvalds 已提交
1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157
}

/*
 * Look up the entry referred to by args in the leaf format directory.
 * Most of the work is done by the xfs_dir2_leaf_lookup_int routine which
 * is also used by the node-format code.
 */
int
xfs_dir2_leaf_lookup(
	xfs_da_args_t		*args)		/* operation arguments */
{
1158
	struct xfs_buf		*dbp;		/* data block buffer */
L
Linus Torvalds 已提交
1159 1160 1161 1162
	xfs_dir2_data_entry_t	*dep;		/* data block entry */
	xfs_inode_t		*dp;		/* incore directory inode */
	int			error;		/* error return code */
	int			index;		/* found entry index */
1163
	struct xfs_buf		*lbp;		/* leaf buffer */
L
Linus Torvalds 已提交
1164 1165 1166
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry */
	xfs_trans_t		*tp;		/* transaction pointer */
1167
	struct xfs_dir2_leaf_entry *ents;
L
Linus Torvalds 已提交
1168

C
Christoph Hellwig 已提交
1169 1170
	trace_xfs_dir2_leaf_lookup(args);

L
Linus Torvalds 已提交
1171 1172 1173 1174 1175 1176 1177 1178
	/*
	 * Look up name in the leaf block, returning both buffers and index.
	 */
	if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
		return error;
	}
	tp = args->trans;
	dp = args->dp;
1179
	xfs_dir3_leaf_check(dp, lbp);
1180
	leaf = lbp->b_addr;
1181
	ents = dp->d_ops->leaf_ents_p(leaf);
L
Linus Torvalds 已提交
1182 1183 1184
	/*
	 * Get to the leaf entry and contained data entry address.
	 */
1185 1186
	lep = &ents[index];

L
Linus Torvalds 已提交
1187 1188 1189 1190
	/*
	 * Point to the data entry.
	 */
	dep = (xfs_dir2_data_entry_t *)
1191
	      ((char *)dbp->b_addr +
1192
	       xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
L
Linus Torvalds 已提交
1193
	/*
1194
	 * Return the found inode number & CI name if appropriate
L
Linus Torvalds 已提交
1195
	 */
1196
	args->inumber = be64_to_cpu(dep->inumber);
1197
	args->filetype = dp->d_ops->data_get_ftype(dep);
1198
	error = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
1199 1200
	xfs_trans_brelse(tp, dbp);
	xfs_trans_brelse(tp, lbp);
E
Eric Sandeen 已提交
1201
	return error;
L
Linus Torvalds 已提交
1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212
}

/*
 * Look up name/hash in the leaf block.
 * Fill in indexp with the found index, and dbpp with the data buffer.
 * If not found dbpp will be NULL, and ENOENT comes back.
 * lbpp will always be filled in with the leaf buffer unless there's an error.
 */
static int					/* error */
xfs_dir2_leaf_lookup_int(
	xfs_da_args_t		*args,		/* operation arguments */
1213
	struct xfs_buf		**lbpp,		/* out: leaf buffer */
L
Linus Torvalds 已提交
1214
	int			*indexp,	/* out: index in leaf block */
1215
	struct xfs_buf		**dbpp)		/* out: data buffer */
L
Linus Torvalds 已提交
1216
{
1217
	xfs_dir2_db_t		curdb = -1;	/* current data block number */
1218
	struct xfs_buf		*dbp = NULL;	/* data buffer */
L
Linus Torvalds 已提交
1219 1220 1221 1222
	xfs_dir2_data_entry_t	*dep;		/* data entry */
	xfs_inode_t		*dp;		/* incore directory inode */
	int			error;		/* error return code */
	int			index;		/* index in leaf block */
1223
	struct xfs_buf		*lbp;		/* leaf buffer */
L
Linus Torvalds 已提交
1224 1225 1226 1227 1228
	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry */
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
	xfs_mount_t		*mp;		/* filesystem mount point */
	xfs_dir2_db_t		newdb;		/* new data block number */
	xfs_trans_t		*tp;		/* transaction pointer */
1229
	xfs_dir2_db_t		cidb = -1;	/* case match data block no. */
1230
	enum xfs_dacmp		cmp;		/* name compare result */
1231 1232
	struct xfs_dir2_leaf_entry *ents;
	struct xfs_dir3_icleaf_hdr leafhdr;
L
Linus Torvalds 已提交
1233 1234 1235 1236

	dp = args->dp;
	tp = args->trans;
	mp = dp->i_mount;
D
Dave Chinner 已提交
1237

1238
	error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp);
1239
	if (error)
L
Linus Torvalds 已提交
1240
		return error;
D
Dave Chinner 已提交
1241

L
Linus Torvalds 已提交
1242
	*lbpp = lbp;
1243
	leaf = lbp->b_addr;
1244 1245
	xfs_dir3_leaf_check(dp, lbp);
	ents = dp->d_ops->leaf_ents_p(leaf);
1246
	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
1247

L
Linus Torvalds 已提交
1248 1249 1250 1251 1252 1253 1254 1255
	/*
	 * Look for the first leaf entry with our hash value.
	 */
	index = xfs_dir2_leaf_search_hash(args, lbp);
	/*
	 * Loop over all the entries with the right hash value
	 * looking to match the name.
	 */
1256 1257 1258
	for (lep = &ents[index];
	     index < leafhdr.count && be32_to_cpu(lep->hashval) == args->hashval;
	     lep++, index++) {
L
Linus Torvalds 已提交
1259 1260 1261
		/*
		 * Skip over stale leaf entries.
		 */
1262
		if (be32_to_cpu(lep->address) == XFS_DIR2_NULL_DATAPTR)
L
Linus Torvalds 已提交
1263 1264 1265 1266
			continue;
		/*
		 * Get the new data block number.
		 */
1267 1268
		newdb = xfs_dir2_dataptr_to_db(args->geo,
					       be32_to_cpu(lep->address));
L
Linus Torvalds 已提交
1269 1270 1271 1272 1273
		/*
		 * If it's not the same as the old data block number,
		 * need to pitch the old one and read the new one.
		 */
		if (newdb != curdb) {
1274
			if (dbp)
1275
				xfs_trans_brelse(tp, dbp);
1276
			error = xfs_dir3_data_read(tp, dp,
1277 1278
					   xfs_dir2_db_to_da(args->geo, newdb),
					   -1, &dbp);
1279
			if (error) {
1280
				xfs_trans_brelse(tp, lbp);
L
Linus Torvalds 已提交
1281 1282 1283 1284 1285 1286 1287
				return error;
			}
			curdb = newdb;
		}
		/*
		 * Point to the data entry.
		 */
1288
		dep = (xfs_dir2_data_entry_t *)((char *)dbp->b_addr +
1289 1290
			xfs_dir2_dataptr_to_off(args->geo,
						be32_to_cpu(lep->address)));
L
Linus Torvalds 已提交
1291
		/*
1292 1293 1294
		 * Compare name and if it's an exact match, return the index
		 * and buffer. If it's the first case-insensitive match, store
		 * the index and buffer and continue looking for an exact match.
L
Linus Torvalds 已提交
1295
		 */
1296 1297 1298
		cmp = mp->m_dirnameops->compname(args, dep->name, dep->namelen);
		if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) {
			args->cmpresult = cmp;
L
Linus Torvalds 已提交
1299
			*indexp = index;
1300
			/* case exact match: return the current buffer. */
1301 1302 1303 1304
			if (cmp == XFS_CMP_EXACT) {
				*dbpp = dbp;
				return 0;
			}
1305
			cidb = curdb;
L
Linus Torvalds 已提交
1306 1307
		}
	}
1308
	ASSERT(args->op_flags & XFS_DA_OP_OKNOENT);
1309
	/*
1310 1311 1312
	 * Here, we can only be doing a lookup (not a rename or remove).
	 * If a case-insensitive match was found earlier, re-read the
	 * appropriate data block if required and return it.
1313 1314
	 */
	if (args->cmpresult == XFS_CMP_CASE) {
1315 1316
		ASSERT(cidb != -1);
		if (cidb != curdb) {
1317
			xfs_trans_brelse(tp, dbp);
1318
			error = xfs_dir3_data_read(tp, dp,
1319 1320
					   xfs_dir2_db_to_da(args->geo, cidb),
					   -1, &dbp);
1321
			if (error) {
1322
				xfs_trans_brelse(tp, lbp);
1323 1324 1325 1326
				return error;
			}
		}
		*dbpp = dbp;
1327 1328
		return 0;
	}
L
Linus Torvalds 已提交
1329 1330 1331
	/*
	 * No match found, return ENOENT.
	 */
1332
	ASSERT(cidb == -1);
L
Linus Torvalds 已提交
1333
	if (dbp)
1334 1335
		xfs_trans_brelse(tp, dbp);
	xfs_trans_brelse(tp, lbp);
E
Eric Sandeen 已提交
1336
	return ENOENT;
L
Linus Torvalds 已提交
1337 1338 1339 1340 1341 1342 1343 1344 1345
}

/*
 * Remove an entry from a leaf format directory.
 */
int						/* error */
xfs_dir2_leaf_removename(
	xfs_da_args_t		*args)		/* operation arguments */
{
1346
	__be16			*bestsp;	/* leaf block best freespace */
1347
	xfs_dir2_data_hdr_t	*hdr;		/* data block header */
L
Linus Torvalds 已提交
1348
	xfs_dir2_db_t		db;		/* data block number */
1349
	struct xfs_buf		*dbp;		/* data block buffer */
L
Linus Torvalds 已提交
1350 1351 1352 1353 1354
	xfs_dir2_data_entry_t	*dep;		/* data entry structure */
	xfs_inode_t		*dp;		/* incore directory inode */
	int			error;		/* error return code */
	xfs_dir2_db_t		i;		/* temporary data block # */
	int			index;		/* index into leaf entries */
1355
	struct xfs_buf		*lbp;		/* leaf buffer */
L
Linus Torvalds 已提交
1356 1357 1358 1359 1360 1361 1362 1363
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry */
	xfs_dir2_leaf_tail_t	*ltp;		/* leaf tail structure */
	xfs_mount_t		*mp;		/* filesystem mount point */
	int			needlog;	/* need to log data header */
	int			needscan;	/* need to rescan data frees */
	xfs_dir2_data_off_t	oldbest;	/* old value of best free */
	xfs_trans_t		*tp;		/* transaction pointer */
1364
	struct xfs_dir2_data_free *bf;		/* bestfree table */
1365 1366
	struct xfs_dir2_leaf_entry *ents;
	struct xfs_dir3_icleaf_hdr leafhdr;
L
Linus Torvalds 已提交
1367

C
Christoph Hellwig 已提交
1368 1369
	trace_xfs_dir2_leaf_removename(args);

L
Linus Torvalds 已提交
1370 1371 1372 1373 1374 1375 1376 1377 1378
	/*
	 * Lookup the leaf entry, get the leaf and data blocks read in.
	 */
	if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
		return error;
	}
	dp = args->dp;
	tp = args->trans;
	mp = dp->i_mount;
1379 1380
	leaf = lbp->b_addr;
	hdr = dbp->b_addr;
1381
	xfs_dir3_data_check(dp, dbp);
1382
	bf = dp->d_ops->data_bestfree_p(hdr);
1383
	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
1384
	ents = dp->d_ops->leaf_ents_p(leaf);
L
Linus Torvalds 已提交
1385 1386 1387
	/*
	 * Point to the leaf entry, use that to point to the data entry.
	 */
1388
	lep = &ents[index];
1389 1390 1391
	db = xfs_dir2_dataptr_to_db(args->geo, be32_to_cpu(lep->address));
	dep = (xfs_dir2_data_entry_t *)((char *)hdr +
		xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
L
Linus Torvalds 已提交
1392
	needscan = needlog = 0;
1393
	oldbest = be16_to_cpu(bf[0].length);
1394
	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
1395
	bestsp = xfs_dir2_leaf_bests_p(ltp);
1396
	ASSERT(be16_to_cpu(bestsp[db]) == oldbest);
L
Linus Torvalds 已提交
1397 1398 1399
	/*
	 * Mark the former data entry unused.
	 */
1400
	xfs_dir2_data_make_free(args, dbp,
1401
		(xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr),
1402
		dp->d_ops->data_entsize(dep->namelen), &needlog, &needscan);
L
Linus Torvalds 已提交
1403 1404 1405
	/*
	 * We just mark the leaf entry stale by putting a null in it.
	 */
1406
	leafhdr.stale++;
1407
	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
1408
	xfs_dir3_leaf_log_header(args, lbp);
1409

1410
	lep->address = cpu_to_be32(XFS_DIR2_NULL_DATAPTR);
1411
	xfs_dir3_leaf_log_ents(args, lbp, index, index);
1412

L
Linus Torvalds 已提交
1413 1414 1415 1416 1417
	/*
	 * Scan the freespace in the data block again if necessary,
	 * log the data block header if necessary.
	 */
	if (needscan)
1418
		xfs_dir2_data_freescan(dp, hdr, &needlog);
L
Linus Torvalds 已提交
1419
	if (needlog)
1420
		xfs_dir2_data_log_header(args, dbp);
L
Linus Torvalds 已提交
1421 1422 1423 1424
	/*
	 * If the longest freespace in the data block has changed,
	 * put the new value in the bests table and log that.
	 */
1425 1426
	if (be16_to_cpu(bf[0].length) != oldbest) {
		bestsp[db] = bf[0].length;
1427
		xfs_dir3_leaf_log_bests(args, lbp, db, db);
L
Linus Torvalds 已提交
1428
	}
1429
	xfs_dir3_data_check(dp, dbp);
L
Linus Torvalds 已提交
1430 1431 1432
	/*
	 * If the data block is now empty then get rid of the data block.
	 */
1433
	if (be16_to_cpu(bf[0].length) ==
1434
			args->geo->blksize - dp->d_ops->data_entry_offset) {
1435
		ASSERT(db != args->geo->datablk);
L
Linus Torvalds 已提交
1436 1437 1438 1439 1440 1441 1442
		if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
			/*
			 * Nope, can't get rid of it because it caused
			 * allocation of a bmap btree block to do so.
			 * Just go on, returning success, leaving the
			 * empty block in place.
			 */
1443
			if (error == ENOSPC && args->total == 0)
L
Linus Torvalds 已提交
1444
				error = 0;
1445
			xfs_dir3_leaf_check(dp, lbp);
L
Linus Torvalds 已提交
1446 1447 1448 1449 1450 1451 1452
			return error;
		}
		dbp = NULL;
		/*
		 * If this is the last data block then compact the
		 * bests table by getting rid of entries.
		 */
1453
		if (db == be32_to_cpu(ltp->bestcount) - 1) {
L
Linus Torvalds 已提交
1454 1455 1456 1457
			/*
			 * Look for the last active entry (i).
			 */
			for (i = db - 1; i > 0; i--) {
1458
				if (bestsp[i] != cpu_to_be16(NULLDATAOFF))
L
Linus Torvalds 已提交
1459 1460 1461 1462 1463 1464 1465
					break;
			}
			/*
			 * Copy the table down so inactive entries at the
			 * end are removed.
			 */
			memmove(&bestsp[db - i], bestsp,
1466
				(be32_to_cpu(ltp->bestcount) - (db - i)) * sizeof(*bestsp));
1467
			be32_add_cpu(&ltp->bestcount, -(db - i));
1468 1469 1470
			xfs_dir3_leaf_log_tail(args, lbp);
			xfs_dir3_leaf_log_bests(args, lbp, 0,
						be32_to_cpu(ltp->bestcount) - 1);
L
Linus Torvalds 已提交
1471
		} else
1472
			bestsp[db] = cpu_to_be16(NULLDATAOFF);
L
Linus Torvalds 已提交
1473 1474 1475 1476
	}
	/*
	 * If the data block was not the first one, drop it.
	 */
1477
	else if (db != args->geo->datablk)
L
Linus Torvalds 已提交
1478
		dbp = NULL;
1479

1480
	xfs_dir3_leaf_check(dp, lbp);
L
Linus Torvalds 已提交
1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493
	/*
	 * See if we can convert to block form.
	 */
	return xfs_dir2_leaf_to_block(args, lbp, dbp);
}

/*
 * Replace the inode number in a leaf format directory entry.
 */
int						/* error */
xfs_dir2_leaf_replace(
	xfs_da_args_t		*args)		/* operation arguments */
{
1494
	struct xfs_buf		*dbp;		/* data block buffer */
L
Linus Torvalds 已提交
1495 1496 1497 1498
	xfs_dir2_data_entry_t	*dep;		/* data block entry */
	xfs_inode_t		*dp;		/* incore directory inode */
	int			error;		/* error return code */
	int			index;		/* index of leaf entry */
1499
	struct xfs_buf		*lbp;		/* leaf buffer */
L
Linus Torvalds 已提交
1500 1501 1502
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry */
	xfs_trans_t		*tp;		/* transaction pointer */
1503
	struct xfs_dir2_leaf_entry *ents;
L
Linus Torvalds 已提交
1504

C
Christoph Hellwig 已提交
1505 1506
	trace_xfs_dir2_leaf_replace(args);

L
Linus Torvalds 已提交
1507 1508 1509 1510 1511 1512 1513
	/*
	 * Look up the entry.
	 */
	if ((error = xfs_dir2_leaf_lookup_int(args, &lbp, &index, &dbp))) {
		return error;
	}
	dp = args->dp;
1514
	leaf = lbp->b_addr;
1515
	ents = dp->d_ops->leaf_ents_p(leaf);
L
Linus Torvalds 已提交
1516 1517 1518
	/*
	 * Point to the leaf entry, get data address from it.
	 */
1519
	lep = &ents[index];
L
Linus Torvalds 已提交
1520 1521 1522 1523
	/*
	 * Point to the data entry.
	 */
	dep = (xfs_dir2_data_entry_t *)
1524
	      ((char *)dbp->b_addr +
1525
	       xfs_dir2_dataptr_to_off(args->geo, be32_to_cpu(lep->address)));
1526
	ASSERT(args->inumber != be64_to_cpu(dep->inumber));
L
Linus Torvalds 已提交
1527 1528 1529
	/*
	 * Put the new inode number in, log it.
	 */
1530
	dep->inumber = cpu_to_be64(args->inumber);
1531
	dp->d_ops->data_put_ftype(dep, args->filetype);
L
Linus Torvalds 已提交
1532
	tp = args->trans;
1533
	xfs_dir2_data_log_entry(args, dbp, dep);
1534
	xfs_dir3_leaf_check(dp, lbp);
1535
	xfs_trans_brelse(tp, lbp);
L
Linus Torvalds 已提交
1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546
	return 0;
}

/*
 * Return index in the leaf block (lbp) which is either the first
 * one with this hash value, or if there are none, the insert point
 * for that hash value.
 */
int						/* index value */
xfs_dir2_leaf_search_hash(
	xfs_da_args_t		*args,		/* operation arguments */
1547
	struct xfs_buf		*lbp)		/* leaf buffer */
L
Linus Torvalds 已提交
1548 1549 1550 1551 1552 1553 1554 1555
{
	xfs_dahash_t		hash=0;		/* hash from this entry */
	xfs_dahash_t		hashwant;	/* hash value looking for */
	int			high;		/* high leaf index */
	int			low;		/* low leaf index */
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
	xfs_dir2_leaf_entry_t	*lep;		/* leaf entry */
	int			mid=0;		/* current leaf index */
1556 1557
	struct xfs_dir2_leaf_entry *ents;
	struct xfs_dir3_icleaf_hdr leafhdr;
L
Linus Torvalds 已提交
1558

1559
	leaf = lbp->b_addr;
1560
	ents = args->dp->d_ops->leaf_ents_p(leaf);
1561
	args->dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
1562

L
Linus Torvalds 已提交
1563 1564 1565 1566
	/*
	 * Note, the table cannot be empty, so we have to go through the loop.
	 * Binary search the leaf entries looking for our hash value.
	 */
1567
	for (lep = ents, low = 0, high = leafhdr.count - 1,
L
Linus Torvalds 已提交
1568 1569 1570
		hashwant = args->hashval;
	     low <= high; ) {
		mid = (low + high) >> 1;
1571
		if ((hash = be32_to_cpu(lep[mid].hashval)) == hashwant)
L
Linus Torvalds 已提交
1572 1573 1574 1575 1576 1577 1578 1579 1580 1581
			break;
		if (hash < hashwant)
			low = mid + 1;
		else
			high = mid - 1;
	}
	/*
	 * Found one, back up through all the equal hash values.
	 */
	if (hash == hashwant) {
1582
		while (mid > 0 && be32_to_cpu(lep[mid - 1].hashval) == hashwant) {
L
Linus Torvalds 已提交
1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600
			mid--;
		}
	}
	/*
	 * Need to point to an entry higher than ours.
	 */
	else if (hash < hashwant)
		mid++;
	return mid;
}

/*
 * Trim off a trailing data block.  We know it's empty since the leaf
 * freespace table says so.
 */
int						/* error */
xfs_dir2_leaf_trim_data(
	xfs_da_args_t		*args,		/* operation arguments */
1601
	struct xfs_buf		*lbp,		/* leaf buffer */
L
Linus Torvalds 已提交
1602 1603
	xfs_dir2_db_t		db)		/* data block number */
{
1604
	__be16			*bestsp;	/* leaf bests table */
1605
	struct xfs_buf		*dbp;		/* data block buffer */
L
Linus Torvalds 已提交
1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618
	xfs_inode_t		*dp;		/* incore directory inode */
	int			error;		/* error return value */
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
	xfs_dir2_leaf_tail_t	*ltp;		/* leaf tail structure */
	xfs_mount_t		*mp;		/* filesystem mount point */
	xfs_trans_t		*tp;		/* transaction pointer */

	dp = args->dp;
	mp = dp->i_mount;
	tp = args->trans;
	/*
	 * Read the offending data block.  We need its buffer.
	 */
1619 1620
	error = xfs_dir3_data_read(tp, dp, xfs_dir2_db_to_da(args->geo, db),
				   -1, &dbp);
1621
	if (error)
L
Linus Torvalds 已提交
1622 1623
		return error;

1624
	leaf = lbp->b_addr;
1625
	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
1626 1627 1628

#ifdef DEBUG
{
1629
	struct xfs_dir2_data_hdr *hdr = dbp->b_addr;
1630
	struct xfs_dir2_data_free *bf = dp->d_ops->data_bestfree_p(hdr);
1631

1632 1633 1634
	ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) ||
	       hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC));
	ASSERT(be16_to_cpu(bf[0].length) ==
1635
	       args->geo->blksize - dp->d_ops->data_entry_offset);
1636
	ASSERT(db == be32_to_cpu(ltp->bestcount) - 1);
1637 1638 1639
}
#endif

L
Linus Torvalds 已提交
1640 1641 1642 1643 1644
	/*
	 * Get rid of the data block.
	 */
	if ((error = xfs_dir2_shrink_inode(args, db, dbp))) {
		ASSERT(error != ENOSPC);
1645
		xfs_trans_brelse(tp, dbp);
L
Linus Torvalds 已提交
1646 1647 1648 1649 1650
		return error;
	}
	/*
	 * Eliminate the last bests entry from the table.
	 */
1651
	bestsp = xfs_dir2_leaf_bests_p(ltp);
1652
	be32_add_cpu(&ltp->bestcount, -1);
1653
	memmove(&bestsp[1], &bestsp[0], be32_to_cpu(ltp->bestcount) * sizeof(*bestsp));
1654 1655
	xfs_dir3_leaf_log_tail(args, lbp);
	xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
L
Linus Torvalds 已提交
1656 1657 1658
	return 0;
}

1659
static inline size_t
1660 1661
xfs_dir3_leaf_size(
	struct xfs_dir3_icleaf_hdr	*hdr,
1662 1663
	int				counts)
{
1664 1665 1666 1667 1668 1669 1670 1671 1672
	int	entries;
	int	hdrsize;

	entries = hdr->count - hdr->stale;
	if (hdr->magic == XFS_DIR2_LEAF1_MAGIC ||
	    hdr->magic == XFS_DIR2_LEAFN_MAGIC)
		hdrsize = sizeof(struct xfs_dir2_leaf_hdr);
	else
		hdrsize = sizeof(struct xfs_dir3_leaf_hdr);
1673

1674 1675 1676
	return hdrsize + entries * sizeof(xfs_dir2_leaf_entry_t)
	               + counts * sizeof(xfs_dir2_data_off_t)
		       + sizeof(xfs_dir2_leaf_tail_t);
1677 1678
}

L
Linus Torvalds 已提交
1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690
/*
 * Convert node form directory to leaf form directory.
 * The root of the node form dir needs to already be a LEAFN block.
 * Just return if we can't do anything.
 */
int						/* error */
xfs_dir2_node_to_leaf(
	xfs_da_state_t		*state)		/* directory operation state */
{
	xfs_da_args_t		*args;		/* operation arguments */
	xfs_inode_t		*dp;		/* incore directory inode */
	int			error;		/* error return code */
1691
	struct xfs_buf		*fbp;		/* buffer for freespace block */
L
Linus Torvalds 已提交
1692 1693
	xfs_fileoff_t		fo;		/* freespace file offset */
	xfs_dir2_free_t		*free;		/* freespace structure */
1694
	struct xfs_buf		*lbp;		/* buffer for leaf block */
L
Linus Torvalds 已提交
1695 1696 1697 1698 1699
	xfs_dir2_leaf_tail_t	*ltp;		/* tail of leaf structure */
	xfs_dir2_leaf_t		*leaf;		/* leaf structure */
	xfs_mount_t		*mp;		/* filesystem mount point */
	int			rval;		/* successful free trim? */
	xfs_trans_t		*tp;		/* transaction pointer */
1700
	struct xfs_dir3_icleaf_hdr leafhdr;
1701
	struct xfs_dir3_icfree_hdr freehdr;
L
Linus Torvalds 已提交
1702 1703 1704 1705 1706 1707 1708 1709

	/*
	 * There's more than a leaf level in the btree, so there must
	 * be multiple leafn blocks.  Give up.
	 */
	if (state->path.active > 1)
		return 0;
	args = state->args;
C
Christoph Hellwig 已提交
1710 1711 1712

	trace_xfs_dir2_node_to_leaf(args);

L
Linus Torvalds 已提交
1713 1714 1715 1716 1717 1718
	mp = state->mp;
	dp = args->dp;
	tp = args->trans;
	/*
	 * Get the last offset in the file.
	 */
1719
	if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK))) {
L
Linus Torvalds 已提交
1720 1721
		return error;
	}
1722
	fo -= args->geo->fsbcount;
L
Linus Torvalds 已提交
1723 1724 1725 1726 1727 1728
	/*
	 * If there are freespace blocks other than the first one,
	 * take this opportunity to remove trailing empty freespace blocks
	 * that may have been left behind during no-space-reservation
	 * operations.
	 */
1729
	while (fo > args->geo->freeblk) {
L
Linus Torvalds 已提交
1730 1731 1732 1733
		if ((error = xfs_dir2_node_trim_free(args, fo, &rval))) {
			return error;
		}
		if (rval)
1734
			fo -= args->geo->fsbcount;
L
Linus Torvalds 已提交
1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746
		else
			return 0;
	}
	/*
	 * Now find the block just before the freespace block.
	 */
	if ((error = xfs_bmap_last_before(tp, dp, &fo, XFS_DATA_FORK))) {
		return error;
	}
	/*
	 * If it's not the single leaf block, give up.
	 */
1747
	if (XFS_FSB_TO_B(mp, fo) > XFS_DIR2_LEAF_OFFSET + args->geo->blksize)
L
Linus Torvalds 已提交
1748 1749
		return 0;
	lbp = state->path.blk[0].bp;
1750
	leaf = lbp->b_addr;
1751
	dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
1752 1753 1754 1755

	ASSERT(leafhdr.magic == XFS_DIR2_LEAFN_MAGIC ||
	       leafhdr.magic == XFS_DIR3_LEAFN_MAGIC);

L
Linus Torvalds 已提交
1756 1757 1758
	/*
	 * Read the freespace block.
	 */
1759
	error = xfs_dir2_free_read(tp, dp,  args->geo->freeblk, &fbp);
1760
	if (error)
L
Linus Torvalds 已提交
1761
		return error;
1762
	free = fbp->b_addr;
1763
	dp->d_ops->free_hdr_from_disk(&freehdr, free);
1764 1765

	ASSERT(!freehdr.firstdb);
1766

L
Linus Torvalds 已提交
1767 1768 1769 1770
	/*
	 * Now see if the leafn and free data will fit in a leaf1.
	 * If not, release the buffer and give up.
	 */
1771
	if (xfs_dir3_leaf_size(&leafhdr, freehdr.nvalid) > args->geo->blksize) {
1772
		xfs_trans_brelse(tp, fbp);
L
Linus Torvalds 已提交
1773 1774
		return 0;
	}
1775

L
Linus Torvalds 已提交
1776 1777 1778
	/*
	 * If the leaf has any stale entries in it, compress them out.
	 */
1779 1780
	if (leafhdr.stale)
		xfs_dir3_leaf_compact(args, &leafhdr, lbp);
1781

1782
	lbp->b_ops = &xfs_dir3_leaf1_buf_ops;
1783
	xfs_trans_buf_set_type(tp, lbp, XFS_BLFT_DIR_LEAF1_BUF);
1784 1785 1786
	leafhdr.magic = (leafhdr.magic == XFS_DIR2_LEAFN_MAGIC)
					? XFS_DIR2_LEAF1_MAGIC
					: XFS_DIR3_LEAF1_MAGIC;
1787

L
Linus Torvalds 已提交
1788 1789 1790
	/*
	 * Set up the leaf tail from the freespace block.
	 */
1791
	ltp = xfs_dir2_leaf_tail_p(args->geo, leaf);
1792
	ltp->bestcount = cpu_to_be32(freehdr.nvalid);
1793

L
Linus Torvalds 已提交
1794 1795 1796
	/*
	 * Set up the leaf bests table.
	 */
1797
	memcpy(xfs_dir2_leaf_bests_p(ltp), dp->d_ops->free_bests_p(free),
1798
		freehdr.nvalid * sizeof(xfs_dir2_data_off_t));
1799

1800
	dp->d_ops->leaf_hdr_to_disk(leaf, &leafhdr);
1801 1802 1803
	xfs_dir3_leaf_log_header(args, lbp);
	xfs_dir3_leaf_log_bests(args, lbp, 0, be32_to_cpu(ltp->bestcount) - 1);
	xfs_dir3_leaf_log_tail(args, lbp);
1804
	xfs_dir3_leaf_check(dp, lbp);
1805

L
Linus Torvalds 已提交
1806 1807 1808
	/*
	 * Get rid of the freespace block.
	 */
1809
	error = xfs_dir2_shrink_inode(args,
1810 1811
			xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET),
			fbp);
L
Linus Torvalds 已提交
1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831
	if (error) {
		/*
		 * This can't fail here because it can only happen when
		 * punching out the middle of an extent, and this is an
		 * isolated block.
		 */
		ASSERT(error != ENOSPC);
		return error;
	}
	fbp = NULL;
	/*
	 * Now see if we can convert the single-leaf directory
	 * down to a block form directory.
	 * This routine always kills the dabuf for the leaf, so
	 * eliminate it from the path.
	 */
	error = xfs_dir2_leaf_to_block(args, lbp, NULL);
	state->path.blk[0].bp = NULL;
	return error;
}