Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
   4 * All Rights Reserved.
   5 */
   6#include "xfs.h"
   7#include "xfs_fs.h"
   8#include "xfs_shared.h"
   9#include "xfs_format.h"
  10#include "xfs_log_format.h"
  11#include "xfs_trans_resv.h"
  12#include "xfs_mount.h"
  13#include "xfs_defer.h"
  14#include "xfs_da_format.h"
  15#include "xfs_da_btree.h"
  16#include "xfs_attr_sf.h"
  17#include "xfs_inode.h"
  18#include "xfs_trans.h"
  19#include "xfs_bmap.h"
  20#include "xfs_bmap_btree.h"
  21#include "xfs_attr.h"
  22#include "xfs_attr_leaf.h"
  23#include "xfs_attr_remote.h"
  24#include "xfs_quota.h"
  25#include "xfs_trans_space.h"
  26#include "xfs_trace.h"
  27
  28/*
  29 * xfs_attr.c
  30 *
  31 * Provide the external interfaces to manage attribute lists.
  32 */
  33
  34/*========================================================================
  35 * Function prototypes for the kernel.
  36 *========================================================================*/
  37
  38/*
  39 * Internal routines when attribute list fits inside the inode.
  40 */
  41STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
  42
  43/*
  44 * Internal routines when attribute list is one block.
  45 */
  46STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
  47STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args);
  48STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
  49STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp);
  50
  51/*
  52 * Internal routines when attribute list is more than one block.
  53 */
  54STATIC int xfs_attr_node_get(xfs_da_args_t *args);
  55STATIC int xfs_attr_node_addname(xfs_da_args_t *args);
  56STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
  57STATIC int xfs_attr_node_hasname(xfs_da_args_t *args,
  58				 struct xfs_da_state **state);
  59STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
  60STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
  61
  62int
  63xfs_inode_hasattr(
  64	struct xfs_inode	*ip)
  65{
  66	if (!XFS_IFORK_Q(ip) ||
  67	    (ip->i_afp->if_format == XFS_DINODE_FMT_EXTENTS &&
  68	     ip->i_afp->if_nextents == 0))
  69		return 0;
  70	return 1;
  71}
  72
  73/*========================================================================
  74 * Overall external interface routines.
  75 *========================================================================*/
  76
  77/*
  78 * Retrieve an extended attribute and its value.  Must have ilock.
  79 * Returns 0 on successful retrieval, otherwise an error.
  80 */
  81int
  82xfs_attr_get_ilocked(
  83	struct xfs_da_args	*args)
  84{
  85	ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
  86
  87	if (!xfs_inode_hasattr(args->dp))
  88		return -ENOATTR;
  89
  90	if (args->dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL)
  91		return xfs_attr_shortform_getvalue(args);
  92	if (xfs_bmap_one_block(args->dp, XFS_ATTR_FORK))
  93		return xfs_attr_leaf_get(args);
  94	return xfs_attr_node_get(args);
  95}
  96
  97/*
  98 * Retrieve an extended attribute by name, and its value if requested.
  99 *
 100 * If args->valuelen is zero, then the caller does not want the value, just an
 101 * indication whether the attribute exists and the size of the value if it
 102 * exists. The size is returned in args.valuelen.
 103 *
 104 * If args->value is NULL but args->valuelen is non-zero, allocate the buffer
 105 * for the value after existence of the attribute has been determined. The
 106 * caller always has to free args->value if it is set, no matter if this
 107 * function was successful or not.
 108 *
 109 * If the attribute is found, but exceeds the size limit set by the caller in
 110 * args->valuelen, return -ERANGE with the size of the attribute that was found
 111 * in args->valuelen.
 112 */
 113int
 114xfs_attr_get(
 115	struct xfs_da_args	*args)
 116{
 117	uint			lock_mode;
 118	int			error;
 119
 120	XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
 121
 122	if (XFS_FORCED_SHUTDOWN(args->dp->i_mount))
 123		return -EIO;
 124
 125	args->geo = args->dp->i_mount->m_attr_geo;
 126	args->whichfork = XFS_ATTR_FORK;
 127	args->hashval = xfs_da_hashname(args->name, args->namelen);
 128
 129	/* Entirely possible to look up a name which doesn't exist */
 130	args->op_flags = XFS_DA_OP_OKNOENT;
 131
 132	lock_mode = xfs_ilock_attr_map_shared(args->dp);
 133	error = xfs_attr_get_ilocked(args);
 134	xfs_iunlock(args->dp, lock_mode);
 135
 136	return error;
 137}
 138
 139/*
 140 * Calculate how many blocks we need for the new attribute,
 141 */
 142STATIC int
 143xfs_attr_calc_size(
 144	struct xfs_da_args	*args,
 145	int			*local)
 146{
 147	struct xfs_mount	*mp = args->dp->i_mount;
 148	int			size;
 149	int			nblks;
 150
 151	/*
 152	 * Determine space new attribute will use, and if it would be
 153	 * "local" or "remote" (note: local != inline).
 154	 */
 155	size = xfs_attr_leaf_newentsize(args, local);
 156	nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
 157	if (*local) {
 158		if (size > (args->geo->blksize / 2)) {
 159			/* Double split possible */
 160			nblks *= 2;
 161		}
 162	} else {
 163		/*
 164		 * Out of line attribute, cannot double split, but
 165		 * make room for the attribute value itself.
 166		 */
 167		uint	dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
 168		nblks += dblocks;
 169		nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
 170	}
 171
 172	return nblks;
 173}
 174
 175STATIC int
 176xfs_attr_try_sf_addname(
 177	struct xfs_inode	*dp,
 178	struct xfs_da_args	*args)
 179{
 180
 181	int			error;
 182
 183	/*
 184	 * Build initial attribute list (if required).
 185	 */
 186	if (dp->i_afp->if_format == XFS_DINODE_FMT_EXTENTS)
 187		xfs_attr_shortform_create(args);
 188
 189	error = xfs_attr_shortform_addname(args);
 190	if (error == -ENOSPC)
 191		return error;
 192
 193	/*
 194	 * Commit the shortform mods, and we're done.
 195	 * NOTE: this is also the error path (EEXIST, etc).
 196	 */
 197	if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
 198		xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
 199
 200	if (dp->i_mount->m_flags & XFS_MOUNT_WSYNC)
 201		xfs_trans_set_sync(args->trans);
 202
 203	return error;
 204}
 205
 206/*
 207 * Check to see if the attr should be upgraded from non-existent or shortform to
 208 * single-leaf-block attribute list.
 209 */
 210static inline bool
 211xfs_attr_is_shortform(
 212	struct xfs_inode    *ip)
 213{
 214	return ip->i_afp->if_format == XFS_DINODE_FMT_LOCAL ||
 215	       (ip->i_afp->if_format == XFS_DINODE_FMT_EXTENTS &&
 216		ip->i_afp->if_nextents == 0);
 217}
 218
 219/*
 220 * Attempts to set an attr in shortform, or converts short form to leaf form if
 221 * there is not enough room.  If the attr is set, the transaction is committed
 222 * and set to NULL.
 223 */
 224STATIC int
 225xfs_attr_set_shortform(
 226	struct xfs_da_args	*args,
 227	struct xfs_buf		**leaf_bp)
 228{
 229	struct xfs_inode	*dp = args->dp;
 230	int			error, error2 = 0;
 231
 232	/*
 233	 * Try to add the attr to the attribute list in the inode.
 234	 */
 235	error = xfs_attr_try_sf_addname(dp, args);
 236	if (error != -ENOSPC) {
 237		error2 = xfs_trans_commit(args->trans);
 238		args->trans = NULL;
 239		return error ? error : error2;
 240	}
 241	/*
 242	 * It won't fit in the shortform, transform to a leaf block.  GROT:
 243	 * another possible req'mt for a double-split btree op.
 244	 */
 245	error = xfs_attr_shortform_to_leaf(args, leaf_bp);
 246	if (error)
 247		return error;
 248
 249	/*
 250	 * Prevent the leaf buffer from being unlocked so that a concurrent AIL
 251	 * push cannot grab the half-baked leaf buffer and run into problems
 252	 * with the write verifier. Once we're done rolling the transaction we
 253	 * can release the hold and add the attr to the leaf.
 254	 */
 255	xfs_trans_bhold(args->trans, *leaf_bp);
 256	error = xfs_defer_finish(&args->trans);
 257	xfs_trans_bhold_release(args->trans, *leaf_bp);
 258	if (error) {
 259		xfs_trans_brelse(args->trans, *leaf_bp);
 260		return error;
 261	}
 262
 263	return 0;
 264}
 265
 266/*
 267 * Set the attribute specified in @args.
 268 */
 269int
 270xfs_attr_set_args(
 271	struct xfs_da_args	*args)
 272{
 273	struct xfs_inode	*dp = args->dp;
 274	struct xfs_buf          *leaf_bp = NULL;
 275	int			error = 0;
 276
 277	/*
 278	 * If the attribute list is already in leaf format, jump straight to
 279	 * leaf handling.  Otherwise, try to add the attribute to the shortform
 280	 * list; if there's no room then convert the list to leaf format and try
 281	 * again.
 282	 */
 283	if (xfs_attr_is_shortform(dp)) {
 284
 285		/*
 286		 * If the attr was successfully set in shortform, the
 287		 * transaction is committed and set to NULL.  Otherwise, is it
 288		 * converted from shortform to leaf, and the transaction is
 289		 * retained.
 290		 */
 291		error = xfs_attr_set_shortform(args, &leaf_bp);
 292		if (error || !args->trans)
 293			return error;
 294	}
 295
 296	if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
 297		error = xfs_attr_leaf_addname(args);
 298		if (error != -ENOSPC)
 299			return error;
 300
 301		/*
 302		 * Promote the attribute list to the Btree format.
 303		 */
 304		error = xfs_attr3_leaf_to_node(args);
 305		if (error)
 306			return error;
 307
 308		/*
 309		 * Finish any deferred work items and roll the transaction once
 310		 * more.  The goal here is to call node_addname with the inode
 311		 * and transaction in the same state (inode locked and joined,
 312		 * transaction clean) no matter how we got to this step.
 313		 */
 314		error = xfs_defer_finish(&args->trans);
 315		if (error)
 316			return error;
 317
 318		/*
 319		 * Commit the current trans (including the inode) and
 320		 * start a new one.
 321		 */
 322		error = xfs_trans_roll_inode(&args->trans, dp);
 323		if (error)
 324			return error;
 325	}
 326
 327	error = xfs_attr_node_addname(args);
 328	return error;
 329}
 330
 331/*
 332 * Return EEXIST if attr is found, or ENOATTR if not
 333 */
 334int
 335xfs_has_attr(
 336	struct xfs_da_args	*args)
 337{
 338	struct xfs_inode	*dp = args->dp;
 339	struct xfs_buf		*bp = NULL;
 340	int			error;
 341
 342	if (!xfs_inode_hasattr(dp))
 343		return -ENOATTR;
 344
 345	if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) {
 346		ASSERT(dp->i_afp->if_flags & XFS_IFINLINE);
 347		return xfs_attr_sf_findname(args, NULL, NULL);
 348	}
 349
 350	if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
 351		error = xfs_attr_leaf_hasname(args, &bp);
 352
 353		if (bp)
 354			xfs_trans_brelse(args->trans, bp);
 355
 356		return error;
 357	}
 358
 359	return xfs_attr_node_hasname(args, NULL);
 360}
 361
 362/*
 363 * Remove the attribute specified in @args.
 364 */
 365int
 366xfs_attr_remove_args(
 367	struct xfs_da_args      *args)
 368{
 369	struct xfs_inode	*dp = args->dp;
 370	int			error;
 371
 372	if (!xfs_inode_hasattr(dp)) {
 373		error = -ENOATTR;
 374	} else if (dp->i_afp->if_format == XFS_DINODE_FMT_LOCAL) {
 375		ASSERT(dp->i_afp->if_flags & XFS_IFINLINE);
 376		error = xfs_attr_shortform_remove(args);
 377	} else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
 378		error = xfs_attr_leaf_removename(args);
 379	} else {
 380		error = xfs_attr_node_removename(args);
 381	}
 382
 383	return error;
 384}
 385
 386/*
 387 * Note: If args->value is NULL the attribute will be removed, just like the
 388 * Linux ->setattr API.
 389 */
 390int
 391xfs_attr_set(
 392	struct xfs_da_args	*args)
 393{
 394	struct xfs_inode	*dp = args->dp;
 395	struct xfs_mount	*mp = dp->i_mount;
 396	struct xfs_trans_res	tres;
 397	bool			rsvd = (args->attr_filter & XFS_ATTR_ROOT);
 398	int			error, local;
 399	unsigned int		total;
 400
 401	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
 402		return -EIO;
 403
 404	error = xfs_qm_dqattach(dp);
 405	if (error)
 406		return error;
 407
 408	args->geo = mp->m_attr_geo;
 409	args->whichfork = XFS_ATTR_FORK;
 410	args->hashval = xfs_da_hashname(args->name, args->namelen);
 411
 412	/*
 413	 * We have no control over the attribute names that userspace passes us
 414	 * to remove, so we have to allow the name lookup prior to attribute
 415	 * removal to fail as well.
 416	 */
 417	args->op_flags = XFS_DA_OP_OKNOENT;
 418
 419	if (args->value) {
 420		XFS_STATS_INC(mp, xs_attr_set);
 421
 422		args->op_flags |= XFS_DA_OP_ADDNAME;
 423		args->total = xfs_attr_calc_size(args, &local);
 424
 425		/*
 426		 * If the inode doesn't have an attribute fork, add one.
 427		 * (inode must not be locked when we call this routine)
 428		 */
 429		if (XFS_IFORK_Q(dp) == 0) {
 430			int sf_size = sizeof(struct xfs_attr_sf_hdr) +
 431				XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen,
 432						args->valuelen);
 433
 434			error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
 435			if (error)
 436				return error;
 437		}
 438
 439		tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
 440				 M_RES(mp)->tr_attrsetrt.tr_logres *
 441					args->total;
 442		tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
 443		tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
 444		total = args->total;
 445	} else {
 446		XFS_STATS_INC(mp, xs_attr_remove);
 447
 448		tres = M_RES(mp)->tr_attrrm;
 449		total = XFS_ATTRRM_SPACE_RES(mp);
 450	}
 451
 452	/*
 453	 * Root fork attributes can use reserved data blocks for this
 454	 * operation if necessary
 455	 */
 456	error = xfs_trans_alloc(mp, &tres, total, 0,
 457			rsvd ? XFS_TRANS_RESERVE : 0, &args->trans);
 458	if (error)
 459		return error;
 460
 461	xfs_ilock(dp, XFS_ILOCK_EXCL);
 462	xfs_trans_ijoin(args->trans, dp, 0);
 463	if (args->value) {
 464		unsigned int	quota_flags = XFS_QMOPT_RES_REGBLKS;
 465
 466		if (rsvd)
 467			quota_flags |= XFS_QMOPT_FORCE_RES;
 468		error = xfs_trans_reserve_quota_nblks(args->trans, dp,
 469				args->total, 0, quota_flags);
 470		if (error)
 471			goto out_trans_cancel;
 472
 473		error = xfs_has_attr(args);
 474		if (error == -EEXIST && (args->attr_flags & XATTR_CREATE))
 475			goto out_trans_cancel;
 476		if (error == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
 477			goto out_trans_cancel;
 478		if (error != -ENOATTR && error != -EEXIST)
 479			goto out_trans_cancel;
 480
 481		error = xfs_attr_set_args(args);
 482		if (error)
 483			goto out_trans_cancel;
 484		/* shortform attribute has already been committed */
 485		if (!args->trans)
 486			goto out_unlock;
 487	} else {
 488		error = xfs_has_attr(args);
 489		if (error != -EEXIST)
 490			goto out_trans_cancel;
 491
 492		error = xfs_attr_remove_args(args);
 493		if (error)
 494			goto out_trans_cancel;
 495	}
 496
 497	/*
 498	 * If this is a synchronous mount, make sure that the
 499	 * transaction goes to disk before returning to the user.
 500	 */
 501	if (mp->m_flags & XFS_MOUNT_WSYNC)
 502		xfs_trans_set_sync(args->trans);
 503
 504	if (!(args->op_flags & XFS_DA_OP_NOTIME))
 505		xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
 506
 507	/*
 508	 * Commit the last in the sequence of transactions.
 509	 */
 510	xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
 511	error = xfs_trans_commit(args->trans);
 512out_unlock:
 513	xfs_iunlock(dp, XFS_ILOCK_EXCL);
 514	return error;
 515
 516out_trans_cancel:
 517	if (args->trans)
 518		xfs_trans_cancel(args->trans);
 519	goto out_unlock;
 520}
 521
 522/*========================================================================
 523 * External routines when attribute list is inside the inode
 524 *========================================================================*/
 525
 526/*
 527 * Add a name to the shortform attribute list structure
 528 * This is the external routine.
 529 */
 530STATIC int
 531xfs_attr_shortform_addname(xfs_da_args_t *args)
 532{
 533	int newsize, forkoff, retval;
 534
 535	trace_xfs_attr_sf_addname(args);
 536
 537	retval = xfs_attr_shortform_lookup(args);
 538	if (retval == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
 539		return retval;
 540	if (retval == -EEXIST) {
 541		if (args->attr_flags & XATTR_CREATE)
 542			return retval;
 543		retval = xfs_attr_shortform_remove(args);
 544		if (retval)
 545			return retval;
 546		/*
 547		 * Since we have removed the old attr, clear ATTR_REPLACE so
 548		 * that the leaf format add routine won't trip over the attr
 549		 * not being around.
 550		 */
 551		args->attr_flags &= ~XATTR_REPLACE;
 552	}
 553
 554	if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
 555	    args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
 556		return -ENOSPC;
 557
 558	newsize = XFS_ATTR_SF_TOTSIZE(args->dp);
 559	newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen);
 560
 561	forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
 562	if (!forkoff)
 563		return -ENOSPC;
 564
 565	xfs_attr_shortform_add(args, forkoff);
 566	return 0;
 567}
 568
 569
 570/*========================================================================
 571 * External routines when attribute list is one block
 572 *========================================================================*/
 573
 574/* Store info about a remote block */
 575STATIC void
 576xfs_attr_save_rmt_blk(
 577	struct xfs_da_args	*args)
 578{
 579	args->blkno2 = args->blkno;
 580	args->index2 = args->index;
 581	args->rmtblkno2 = args->rmtblkno;
 582	args->rmtblkcnt2 = args->rmtblkcnt;
 583	args->rmtvaluelen2 = args->rmtvaluelen;
 584}
 585
 586/* Set stored info about a remote block */
 587STATIC void
 588xfs_attr_restore_rmt_blk(
 589	struct xfs_da_args	*args)
 590{
 591	args->blkno = args->blkno2;
 592	args->index = args->index2;
 593	args->rmtblkno = args->rmtblkno2;
 594	args->rmtblkcnt = args->rmtblkcnt2;
 595	args->rmtvaluelen = args->rmtvaluelen2;
 596}
 597
 598/*
 599 * Tries to add an attribute to an inode in leaf form
 600 *
 601 * This function is meant to execute as part of a delayed operation and leaves
 602 * the transaction handling to the caller.  On success the attribute is added
 603 * and the inode and transaction are left dirty.  If there is not enough space,
 604 * the attr data is converted to node format and -ENOSPC is returned. Caller is
 605 * responsible for handling the dirty inode and transaction or adding the attr
 606 * in node format.
 607 */
 608STATIC int
 609xfs_attr_leaf_try_add(
 610	struct xfs_da_args	*args,
 611	struct xfs_buf		*bp)
 612{
 613	int			retval;
 614
 615	/*
 616	 * Look up the given attribute in the leaf block.  Figure out if
 617	 * the given flags produce an error or call for an atomic rename.
 618	 */
 619	retval = xfs_attr_leaf_hasname(args, &bp);
 620	if (retval != -ENOATTR && retval != -EEXIST)
 621		return retval;
 622	if (retval == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
 623		goto out_brelse;
 624	if (retval == -EEXIST) {
 625		if (args->attr_flags & XATTR_CREATE)
 626			goto out_brelse;
 627
 628		trace_xfs_attr_leaf_replace(args);
 629
 630		/* save the attribute state for later removal*/
 631		args->op_flags |= XFS_DA_OP_RENAME;	/* an atomic rename */
 632		xfs_attr_save_rmt_blk(args);
 633
 634		/*
 635		 * clear the remote attr state now that it is saved so that the
 636		 * values reflect the state of the attribute we are about to
 637		 * add, not the attribute we just found and will remove later.
 638		 */
 639		args->rmtblkno = 0;
 640		args->rmtblkcnt = 0;
 641		args->rmtvaluelen = 0;
 642	}
 643
 644	/*
 645	 * Add the attribute to the leaf block
 646	 */
 647	return xfs_attr3_leaf_add(bp, args);
 648
 649out_brelse:
 650	xfs_trans_brelse(args->trans, bp);
 651	return retval;
 652}
 653
 654
 655/*
 656 * Add a name to the leaf attribute list structure
 657 *
 658 * This leaf block cannot have a "remote" value, we only call this routine
 659 * if bmap_one_block() says there is only one block (ie: no remote blks).
 660 */
 661STATIC int
 662xfs_attr_leaf_addname(
 663	struct xfs_da_args	*args)
 664{
 665	int			error, forkoff;
 666	struct xfs_buf		*bp = NULL;
 667	struct xfs_inode	*dp = args->dp;
 668
 669	trace_xfs_attr_leaf_addname(args);
 670
 671	error = xfs_attr_leaf_try_add(args, bp);
 672	if (error)
 673		return error;
 674
 675	/*
 676	 * Commit the transaction that added the attr name so that
 677	 * later routines can manage their own transactions.
 678	 */
 679	error = xfs_trans_roll_inode(&args->trans, dp);
 680	if (error)
 681		return error;
 682
 683	/*
 684	 * If there was an out-of-line value, allocate the blocks we
 685	 * identified for its storage and copy the value.  This is done
 686	 * after we create the attribute so that we don't overflow the
 687	 * maximum size of a transaction and/or hit a deadlock.
 688	 */
 689	if (args->rmtblkno > 0) {
 690		error = xfs_attr_rmtval_set(args);
 691		if (error)
 692			return error;
 693	}
 694
 695	if (!(args->op_flags & XFS_DA_OP_RENAME)) {
 696		/*
 697		 * Added a "remote" value, just clear the incomplete flag.
 698		 */
 699		if (args->rmtblkno > 0)
 700			error = xfs_attr3_leaf_clearflag(args);
 701
 702		return error;
 703	}
 704
 705	/*
 706	 * If this is an atomic rename operation, we must "flip" the incomplete
 707	 * flags on the "new" and "old" attribute/value pairs so that one
 708	 * disappears and one appears atomically.  Then we must remove the "old"
 709	 * attribute/value pair.
 710	 *
 711	 * In a separate transaction, set the incomplete flag on the "old" attr
 712	 * and clear the incomplete flag on the "new" attr.
 713	 */
 714
 715	error = xfs_attr3_leaf_flipflags(args);
 716	if (error)
 717		return error;
 718	/*
 719	 * Commit the flag value change and start the next trans in series.
 720	 */
 721	error = xfs_trans_roll_inode(&args->trans, args->dp);
 722	if (error)
 723		return error;
 724
 725	/*
 726	 * Dismantle the "old" attribute/value pair by removing a "remote" value
 727	 * (if it exists).
 728	 */
 729	xfs_attr_restore_rmt_blk(args);
 730
 731	if (args->rmtblkno) {
 732		error = xfs_attr_rmtval_invalidate(args);
 733		if (error)
 734			return error;
 735
 736		error = xfs_attr_rmtval_remove(args);
 737		if (error)
 738			return error;
 739	}
 740
 741	/*
 742	 * Read in the block containing the "old" attr, then remove the "old"
 743	 * attr from that block (neat, huh!)
 744	 */
 745	error = xfs_attr3_leaf_read(args->trans, args->dp, args->blkno,
 746				   &bp);
 747	if (error)
 748		return error;
 749
 750	xfs_attr3_leaf_remove(bp, args);
 751
 752	/*
 753	 * If the result is small enough, shrink it all into the inode.
 754	 */
 755	forkoff = xfs_attr_shortform_allfit(bp, dp);
 756	if (forkoff)
 757		error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
 758		/* bp is gone due to xfs_da_shrink_inode */
 759
 760	return error;
 761}
 762
 763/*
 764 * Return EEXIST if attr is found, or ENOATTR if not
 765 */
 766STATIC int
 767xfs_attr_leaf_hasname(
 768	struct xfs_da_args	*args,
 769	struct xfs_buf		**bp)
 770{
 771	int                     error = 0;
 772
 773	error = xfs_attr3_leaf_read(args->trans, args->dp, 0, bp);
 774	if (error)
 775		return error;
 776
 777	error = xfs_attr3_leaf_lookup_int(*bp, args);
 778	if (error != -ENOATTR && error != -EEXIST)
 779		xfs_trans_brelse(args->trans, *bp);
 780
 781	return error;
 782}
 783
 784/*
 785 * Remove a name from the leaf attribute list structure
 786 *
 787 * This leaf block cannot have a "remote" value, we only call this routine
 788 * if bmap_one_block() says there is only one block (ie: no remote blks).
 789 */
 790STATIC int
 791xfs_attr_leaf_removename(
 792	struct xfs_da_args	*args)
 793{
 794	struct xfs_inode	*dp;
 795	struct xfs_buf		*bp;
 796	int			error, forkoff;
 797
 798	trace_xfs_attr_leaf_removename(args);
 799
 800	/*
 801	 * Remove the attribute.
 802	 */
 803	dp = args->dp;
 804
 805	error = xfs_attr_leaf_hasname(args, &bp);
 806
 807	if (error == -ENOATTR) {
 808		xfs_trans_brelse(args->trans, bp);
 809		return error;
 810	} else if (error != -EEXIST)
 811		return error;
 812
 813	xfs_attr3_leaf_remove(bp, args);
 814
 815	/*
 816	 * If the result is small enough, shrink it all into the inode.
 817	 */
 818	forkoff = xfs_attr_shortform_allfit(bp, dp);
 819	if (forkoff)
 820		return xfs_attr3_leaf_to_shortform(bp, args, forkoff);
 821		/* bp is gone due to xfs_da_shrink_inode */
 822
 823	return 0;
 824}
 825
 826/*
 827 * Look up a name in a leaf attribute list structure.
 828 *
 829 * This leaf block cannot have a "remote" value, we only call this routine
 830 * if bmap_one_block() says there is only one block (ie: no remote blks).
 831 *
 832 * Returns 0 on successful retrieval, otherwise an error.
 833 */
 834STATIC int
 835xfs_attr_leaf_get(xfs_da_args_t *args)
 836{
 837	struct xfs_buf *bp;
 838	int error;
 839
 840	trace_xfs_attr_leaf_get(args);
 841
 842	error = xfs_attr_leaf_hasname(args, &bp);
 843
 844	if (error == -ENOATTR)  {
 845		xfs_trans_brelse(args->trans, bp);
 846		return error;
 847	} else if (error != -EEXIST)
 848		return error;
 849
 850
 851	error = xfs_attr3_leaf_getvalue(bp, args);
 852	xfs_trans_brelse(args->trans, bp);
 853	return error;
 854}
 855
 856/*
 857 * Return EEXIST if attr is found, or ENOATTR if not
 858 * statep: If not null is set to point at the found state.  Caller will
 859 *         be responsible for freeing the state in this case.
 860 */
 861STATIC int
 862xfs_attr_node_hasname(
 863	struct xfs_da_args	*args,
 864	struct xfs_da_state	**statep)
 865{
 866	struct xfs_da_state	*state;
 867	int			retval, error;
 868
 869	state = xfs_da_state_alloc(args);
 870	if (statep != NULL)
 871		*statep = NULL;
 872
 873	/*
 874	 * Search to see if name exists, and get back a pointer to it.
 875	 */
 876	error = xfs_da3_node_lookup_int(state, &retval);
 877	if (error) {
 878		xfs_da_state_free(state);
 879		return error;
 880	}
 881
 882	if (statep != NULL)
 883		*statep = state;
 884	else
 885		xfs_da_state_free(state);
 886	return retval;
 887}
 888
 889/*========================================================================
 890 * External routines when attribute list size > geo->blksize
 891 *========================================================================*/
 892
 893/*
 894 * Add a name to a Btree-format attribute list.
 895 *
 896 * This will involve walking down the Btree, and may involve splitting
 897 * leaf nodes and even splitting intermediate nodes up to and including
 898 * the root node (a special case of an intermediate node).
 899 *
 900 * "Remote" attribute values confuse the issue and atomic rename operations
 901 * add a whole extra layer of confusion on top of that.
 902 */
 903STATIC int
 904xfs_attr_node_addname(
 905	struct xfs_da_args	*args)
 906{
 907	struct xfs_da_state	*state;
 908	struct xfs_da_state_blk	*blk;
 909	struct xfs_inode	*dp;
 910	int			retval, error;
 911
 912	trace_xfs_attr_node_addname(args);
 913
 914	/*
 915	 * Fill in bucket of arguments/results/context to carry around.
 916	 */
 917	dp = args->dp;
 918restart:
 919	/*
 920	 * Search to see if name already exists, and get back a pointer
 921	 * to where it should go.
 922	 */
 923	retval = xfs_attr_node_hasname(args, &state);
 924	if (retval != -ENOATTR && retval != -EEXIST)
 925		goto out;
 926
 927	blk = &state->path.blk[ state->path.active-1 ];
 928	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
 929	if (retval == -ENOATTR && (args->attr_flags & XATTR_REPLACE))
 930		goto out;
 931	if (retval == -EEXIST) {
 932		if (args->attr_flags & XATTR_CREATE)
 933			goto out;
 934
 935		trace_xfs_attr_node_replace(args);
 936
 937		/* save the attribute state for later removal*/
 938		args->op_flags |= XFS_DA_OP_RENAME;	/* atomic rename op */
 939		xfs_attr_save_rmt_blk(args);
 940
 941		/*
 942		 * clear the remote attr state now that it is saved so that the
 943		 * values reflect the state of the attribute we are about to
 944		 * add, not the attribute we just found and will remove later.
 945		 */
 946		args->rmtblkno = 0;
 947		args->rmtblkcnt = 0;
 948		args->rmtvaluelen = 0;
 949	}
 950
 951	retval = xfs_attr3_leaf_add(blk->bp, state->args);
 952	if (retval == -ENOSPC) {
 953		if (state->path.active == 1) {
 954			/*
 955			 * Its really a single leaf node, but it had
 956			 * out-of-line values so it looked like it *might*
 957			 * have been a b-tree.
 958			 */
 959			xfs_da_state_free(state);
 960			state = NULL;
 961			error = xfs_attr3_leaf_to_node(args);
 962			if (error)
 963				goto out;
 964			error = xfs_defer_finish(&args->trans);
 965			if (error)
 966				goto out;
 967
 968			/*
 969			 * Commit the node conversion and start the next
 970			 * trans in the chain.
 971			 */
 972			error = xfs_trans_roll_inode(&args->trans, dp);
 973			if (error)
 974				goto out;
 975
 976			goto restart;
 977		}
 978
 979		/*
 980		 * Split as many Btree elements as required.
 981		 * This code tracks the new and old attr's location
 982		 * in the index/blkno/rmtblkno/rmtblkcnt fields and
 983		 * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
 984		 */
 985		error = xfs_da3_split(state);
 986		if (error)
 987			goto out;
 988		error = xfs_defer_finish(&args->trans);
 989		if (error)
 990			goto out;
 991	} else {
 992		/*
 993		 * Addition succeeded, update Btree hashvals.
 994		 */
 995		xfs_da3_fixhashpath(state, &state->path);
 996	}
 997
 998	/*
 999	 * Kill the state structure, we're done with it and need to
1000	 * allow the buffers to come back later.
1001	 */
1002	xfs_da_state_free(state);
1003	state = NULL;
1004
1005	/*
1006	 * Commit the leaf addition or btree split and start the next
1007	 * trans in the chain.
1008	 */
1009	error = xfs_trans_roll_inode(&args->trans, dp);
1010	if (error)
1011		goto out;
1012
1013	/*
1014	 * If there was an out-of-line value, allocate the blocks we
1015	 * identified for its storage and copy the value.  This is done
1016	 * after we create the attribute so that we don't overflow the
1017	 * maximum size of a transaction and/or hit a deadlock.
1018	 */
1019	if (args->rmtblkno > 0) {
1020		error = xfs_attr_rmtval_set(args);
1021		if (error)
1022			return error;
1023	}
1024
1025	if (!(args->op_flags & XFS_DA_OP_RENAME)) {
1026		/*
1027		 * Added a "remote" value, just clear the incomplete flag.
1028		 */
1029		if (args->rmtblkno > 0)
1030			error = xfs_attr3_leaf_clearflag(args);
1031		retval = error;
1032		goto out;
1033	}
1034
1035	/*
1036	 * If this is an atomic rename operation, we must "flip" the incomplete
1037	 * flags on the "new" and "old" attribute/value pairs so that one
1038	 * disappears and one appears atomically.  Then we must remove the "old"
1039	 * attribute/value pair.
1040	 *
1041	 * In a separate transaction, set the incomplete flag on the "old" attr
1042	 * and clear the incomplete flag on the "new" attr.
1043	 */
1044	error = xfs_attr3_leaf_flipflags(args);
1045	if (error)
1046		goto out;
1047	/*
1048	 * Commit the flag value change and start the next trans in series
1049	 */
1050	error = xfs_trans_roll_inode(&args->trans, args->dp);
1051	if (error)
1052		goto out;
1053
1054	/*
1055	 * Dismantle the "old" attribute/value pair by removing a "remote" value
1056	 * (if it exists).
1057	 */
1058	xfs_attr_restore_rmt_blk(args);
1059
1060	if (args->rmtblkno) {
1061		error = xfs_attr_rmtval_invalidate(args);
1062		if (error)
1063			return error;
1064
1065		error = xfs_attr_rmtval_remove(args);
1066		if (error)
1067			return error;
1068	}
1069
1070	/*
1071	 * Re-find the "old" attribute entry after any split ops. The INCOMPLETE
1072	 * flag means that we will find the "old" attr, not the "new" one.
1073	 */
1074	args->attr_filter |= XFS_ATTR_INCOMPLETE;
1075	state = xfs_da_state_alloc(args);
1076	state->inleaf = 0;
1077	error = xfs_da3_node_lookup_int(state, &retval);
1078	if (error)
1079		goto out;
1080
1081	/*
1082	 * Remove the name and update the hashvals in the tree.
1083	 */
1084	blk = &state->path.blk[state->path.active-1];
1085	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1086	error = xfs_attr3_leaf_remove(blk->bp, args);
1087	xfs_da3_fixhashpath(state, &state->path);
1088
1089	/*
1090	 * Check to see if the tree needs to be collapsed.
1091	 */
1092	if (retval && (state->path.active > 1)) {
1093		error = xfs_da3_join(state);
1094		if (error)
1095			goto out;
1096	}
1097	retval = error = 0;
1098
1099out:
1100	if (state)
1101		xfs_da_state_free(state);
1102	if (error)
1103		return error;
1104	return retval;
1105}
1106
1107/*
1108 * Shrink an attribute from leaf to shortform
1109 */
1110STATIC int
1111xfs_attr_node_shrink(
1112	struct xfs_da_args	*args,
1113	struct xfs_da_state     *state)
1114{
1115	struct xfs_inode	*dp = args->dp;
1116	int			error, forkoff;
1117	struct xfs_buf		*bp;
1118
1119	/*
1120	 * Have to get rid of the copy of this dabuf in the state.
1121	 */
1122	ASSERT(state->path.active == 1);
1123	ASSERT(state->path.blk[0].bp);
1124	state->path.blk[0].bp = NULL;
1125
1126	error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp);
1127	if (error)
1128		return error;
1129
1130	forkoff = xfs_attr_shortform_allfit(bp, dp);
1131	if (forkoff) {
1132		error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1133		/* bp is gone due to xfs_da_shrink_inode */
1134	} else
1135		xfs_trans_brelse(args->trans, bp);
1136
1137	return error;
1138}
1139
1140/*
1141 * Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
1142 * for later deletion of the entry.
1143 */
1144STATIC int
1145xfs_attr_leaf_mark_incomplete(
1146	struct xfs_da_args	*args,
1147	struct xfs_da_state	*state)
1148{
1149	int			error;
1150
1151	/*
1152	 * Fill in disk block numbers in the state structure
1153	 * so that we can get the buffers back after we commit
1154	 * several transactions in the following calls.
1155	 */
1156	error = xfs_attr_fillstate(state);
1157	if (error)
1158		return error;
1159
1160	/*
1161	 * Mark the attribute as INCOMPLETE
1162	 */
1163	return xfs_attr3_leaf_setflag(args);
1164}
1165
1166/*
1167 * Initial setup for xfs_attr_node_removename.  Make sure the attr is there and
1168 * the blocks are valid.  Attr keys with remote blocks will be marked
1169 * incomplete.
1170 */
1171STATIC
1172int xfs_attr_node_removename_setup(
1173	struct xfs_da_args	*args,
1174	struct xfs_da_state	**state)
1175{
1176	int			error;
1177
1178	error = xfs_attr_node_hasname(args, state);
1179	if (error != -EEXIST)
1180		return error;
1181
1182	ASSERT((*state)->path.blk[(*state)->path.active - 1].bp != NULL);
1183	ASSERT((*state)->path.blk[(*state)->path.active - 1].magic ==
1184		XFS_ATTR_LEAF_MAGIC);
1185
1186	if (args->rmtblkno > 0) {
1187		error = xfs_attr_leaf_mark_incomplete(args, *state);
1188		if (error)
1189			return error;
1190
1191		return xfs_attr_rmtval_invalidate(args);
1192	}
1193
1194	return 0;
1195}
1196
1197STATIC int
1198xfs_attr_node_remove_rmt(
1199	struct xfs_da_args	*args,
1200	struct xfs_da_state	*state)
1201{
1202	int			error = 0;
1203
1204	error = xfs_attr_rmtval_remove(args);
1205	if (error)
1206		return error;
1207
1208	/*
1209	 * Refill the state structure with buffers, the prior calls released our
1210	 * buffers.
1211	 */
1212	return xfs_attr_refillstate(state);
1213}
1214
1215/*
1216 * Remove a name from a B-tree attribute list.
1217 *
1218 * This will involve walking down the Btree, and may involve joining
1219 * leaf nodes and even joining intermediate nodes up to and including
1220 * the root node (a special case of an intermediate node).
1221 */
1222STATIC int
1223xfs_attr_node_removename(
1224	struct xfs_da_args	*args)
1225{
1226	struct xfs_da_state	*state;
1227	struct xfs_da_state_blk	*blk;
1228	int			retval, error;
1229	struct xfs_inode	*dp = args->dp;
1230
1231	trace_xfs_attr_node_removename(args);
1232
1233	error = xfs_attr_node_removename_setup(args, &state);
1234	if (error)
1235		goto out;
1236
1237	/*
1238	 * If there is an out-of-line value, de-allocate the blocks.
1239	 * This is done before we remove the attribute so that we don't
1240	 * overflow the maximum size of a transaction and/or hit a deadlock.
1241	 */
1242	if (args->rmtblkno > 0) {
1243		error = xfs_attr_node_remove_rmt(args, state);
1244		if (error)
1245			goto out;
1246	}
1247
1248	/*
1249	 * Remove the name and update the hashvals in the tree.
1250	 */
1251	blk = &state->path.blk[ state->path.active-1 ];
1252	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1253	retval = xfs_attr3_leaf_remove(blk->bp, args);
1254	xfs_da3_fixhashpath(state, &state->path);
1255
1256	/*
1257	 * Check to see if the tree needs to be collapsed.
1258	 */
1259	if (retval && (state->path.active > 1)) {
1260		error = xfs_da3_join(state);
1261		if (error)
1262			goto out;
1263		error = xfs_defer_finish(&args->trans);
1264		if (error)
1265			goto out;
1266		/*
1267		 * Commit the Btree join operation and start a new trans.
1268		 */
1269		error = xfs_trans_roll_inode(&args->trans, dp);
1270		if (error)
1271			goto out;
1272	}
1273
1274	/*
1275	 * If the result is small enough, push it all into the inode.
1276	 */
1277	if (xfs_bmap_one_block(dp, XFS_ATTR_FORK))
1278		error = xfs_attr_node_shrink(args, state);
1279
1280out:
1281	if (state)
1282		xfs_da_state_free(state);
1283	return error;
1284}
1285
1286/*
1287 * Fill in the disk block numbers in the state structure for the buffers
1288 * that are attached to the state structure.
1289 * This is done so that we can quickly reattach ourselves to those buffers
1290 * after some set of transaction commits have released these buffers.
1291 */
1292STATIC int
1293xfs_attr_fillstate(xfs_da_state_t *state)
1294{
1295	xfs_da_state_path_t *path;
1296	xfs_da_state_blk_t *blk;
1297	int level;
1298
1299	trace_xfs_attr_fillstate(state->args);
1300
1301	/*
1302	 * Roll down the "path" in the state structure, storing the on-disk
1303	 * block number for those buffers in the "path".
1304	 */
1305	path = &state->path;
1306	ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1307	for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1308		if (blk->bp) {
1309			blk->disk_blkno = XFS_BUF_ADDR(blk->bp);
1310			blk->bp = NULL;
1311		} else {
1312			blk->disk_blkno = 0;
1313		}
1314	}
1315
1316	/*
1317	 * Roll down the "altpath" in the state structure, storing the on-disk
1318	 * block number for those buffers in the "altpath".
1319	 */
1320	path = &state->altpath;
1321	ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1322	for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1323		if (blk->bp) {
1324			blk->disk_blkno = XFS_BUF_ADDR(blk->bp);
1325			blk->bp = NULL;
1326		} else {
1327			blk->disk_blkno = 0;
1328		}
1329	}
1330
1331	return 0;
1332}
1333
1334/*
1335 * Reattach the buffers to the state structure based on the disk block
1336 * numbers stored in the state structure.
1337 * This is done after some set of transaction commits have released those
1338 * buffers from our grip.
1339 */
1340STATIC int
1341xfs_attr_refillstate(xfs_da_state_t *state)
1342{
1343	xfs_da_state_path_t *path;
1344	xfs_da_state_blk_t *blk;
1345	int level, error;
1346
1347	trace_xfs_attr_refillstate(state->args);
1348
1349	/*
1350	 * Roll down the "path" in the state structure, storing the on-disk
1351	 * block number for those buffers in the "path".
1352	 */
1353	path = &state->path;
1354	ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1355	for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1356		if (blk->disk_blkno) {
1357			error = xfs_da3_node_read_mapped(state->args->trans,
1358					state->args->dp, blk->disk_blkno,
1359					&blk->bp, XFS_ATTR_FORK);
1360			if (error)
1361				return error;
1362		} else {
1363			blk->bp = NULL;
1364		}
1365	}
1366
1367	/*
1368	 * Roll down the "altpath" in the state structure, storing the on-disk
1369	 * block number for those buffers in the "altpath".
1370	 */
1371	path = &state->altpath;
1372	ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1373	for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1374		if (blk->disk_blkno) {
1375			error = xfs_da3_node_read_mapped(state->args->trans,
1376					state->args->dp, blk->disk_blkno,
1377					&blk->bp, XFS_ATTR_FORK);
1378			if (error)
1379				return error;
1380		} else {
1381			blk->bp = NULL;
1382		}
1383	}
1384
1385	return 0;
1386}
1387
1388/*
1389 * Retrieve the attribute data from a node attribute list.
1390 *
1391 * This routine gets called for any attribute fork that has more than one
1392 * block, ie: both true Btree attr lists and for single-leaf-blocks with
1393 * "remote" values taking up more blocks.
1394 *
1395 * Returns 0 on successful retrieval, otherwise an error.
1396 */
1397STATIC int
1398xfs_attr_node_get(
1399	struct xfs_da_args	*args)
1400{
1401	struct xfs_da_state	*state;
1402	struct xfs_da_state_blk	*blk;
1403	int			i;
1404	int			error;
1405
1406	trace_xfs_attr_node_get(args);
1407
1408	/*
1409	 * Search to see if name exists, and get back a pointer to it.
1410	 */
1411	error = xfs_attr_node_hasname(args, &state);
1412	if (error != -EEXIST)
1413		goto out_release;
1414
1415	/*
1416	 * Get the value, local or "remote"
1417	 */
1418	blk = &state->path.blk[state->path.active - 1];
1419	error = xfs_attr3_leaf_getvalue(blk->bp, args);
1420
1421	/*
1422	 * If not in a transaction, we have to release all the buffers.
1423	 */
1424out_release:
1425	for (i = 0; state != NULL && i < state->path.active; i++) {
1426		xfs_trans_brelse(args->trans, state->path.blk[i].bp);
1427		state->path.blk[i].bp = NULL;
1428	}
1429
1430	if (state)
1431		xfs_da_state_free(state);
1432	return error;
1433}
1434
1435/* Returns true if the attribute entry name is valid. */
1436bool
1437xfs_attr_namecheck(
1438	const void	*name,
1439	size_t		length)
1440{
1441	/*
1442	 * MAXNAMELEN includes the trailing null, but (name/length) leave it
1443	 * out, so use >= for the length check.
1444	 */
1445	if (length >= MAXNAMELEN)
1446		return false;
1447
1448	/* There shouldn't be any nulls here */
1449	return !memchr(name, 0, length);
1450}