File Index
Files and directories
Sign in
FILE

xfs_attr.c

File preview with syntax highlighting.

linux-6.19.14/fs/xfs/libxfs/xfs_attr.c C
   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#include "xfs_attr_item.h"
  28#include "xfs_xattr.h"
  29#include "xfs_parent.h"
  30
  31struct kmem_cache		*xfs_attr_intent_cache;
  32
  33/*
  34 * xfs_attr.c
  35 *
  36 * Provide the external interfaces to manage attribute lists.
  37 */
  38
  39/*========================================================================
  40 * Function prototypes for the kernel.
  41 *========================================================================*/
  42
  43/*
  44 * Internal routines when attribute list fits inside the inode.
  45 */
  46STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
  47
  48/*
  49 * Internal routines when attribute list is one block.
  50 */
  51STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
  52STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
  53
  54/*
  55 * Internal routines when attribute list is more than one block.
  56 */
  57STATIC int xfs_attr_node_get(xfs_da_args_t *args);
  58STATIC void xfs_attr_restore_rmt_blk(struct xfs_da_args *args);
  59static int xfs_attr_node_try_addname(struct xfs_attr_intent *attr);
  60STATIC int xfs_attr_node_addname_find_attr(struct xfs_attr_intent *attr);
  61STATIC int xfs_attr_node_remove_attr(struct xfs_attr_intent *attr);
  62STATIC int xfs_attr_node_lookup(struct xfs_da_args *args,
  63		struct xfs_da_state *state);
  64
  65int
  66xfs_inode_hasattr(
  67	struct xfs_inode	*ip)
  68{
  69	if (!xfs_inode_has_attr_fork(ip))
  70		return 0;
  71	if (ip->i_af.if_format == XFS_DINODE_FMT_EXTENTS &&
  72	    ip->i_af.if_nextents == 0)
  73		return 0;
  74	return 1;
  75}
  76
  77/*
  78 * Returns true if the there is exactly only block in the attr fork, in which
  79 * case the attribute fork consists of a single leaf block entry.
  80 */
  81bool
  82xfs_attr_is_leaf(
  83	struct xfs_inode	*ip)
  84{
  85	struct xfs_ifork	*ifp = &ip->i_af;
  86	struct xfs_iext_cursor	icur;
  87	struct xfs_bmbt_irec	imap;
  88
  89	ASSERT(!xfs_need_iread_extents(ifp));
  90
  91	if (ifp->if_nextents != 1 || ifp->if_format != XFS_DINODE_FMT_EXTENTS)
  92		return false;
  93
  94	xfs_iext_first(ifp, &icur);
  95	xfs_iext_get_extent(ifp, &icur, &imap);
  96	return imap.br_startoff == 0 && imap.br_blockcount == 1;
  97}
  98
  99/*
 100 * XXX (dchinner): name path state saving and refilling is an optimisation to
 101 * avoid needing to look up name entries after rolling transactions removing
 102 * remote xattr blocks between the name entry lookup and name entry removal.
 103 * This optimisation got sidelined when combining the set and remove state
 104 * machines, but the code has been left in place because it is worthwhile to
 105 * restore the optimisation once the combined state machine paths have settled.
 106 *
 107 * This comment is a public service announcement to remind Future Dave that he
 108 * still needs to restore this code to working order.
 109 */
 110#if 0
 111/*
 112 * Fill in the disk block numbers in the state structure for the buffers
 113 * that are attached to the state structure.
 114 * This is done so that we can quickly reattach ourselves to those buffers
 115 * after some set of transaction commits have released these buffers.
 116 */
 117static int
 118xfs_attr_fillstate(xfs_da_state_t *state)
 119{
 120	xfs_da_state_path_t *path;
 121	xfs_da_state_blk_t *blk;
 122	int level;
 123
 124	trace_xfs_attr_fillstate(state->args);
 125
 126	/*
 127	 * Roll down the "path" in the state structure, storing the on-disk
 128	 * block number for those buffers in the "path".
 129	 */
 130	path = &state->path;
 131	ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
 132	for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
 133		if (blk->bp) {
 134			blk->disk_blkno = xfs_buf_daddr(blk->bp);
 135			blk->bp = NULL;
 136		} else {
 137			blk->disk_blkno = 0;
 138		}
 139	}
 140
 141	/*
 142	 * Roll down the "altpath" in the state structure, storing the on-disk
 143	 * block number for those buffers in the "altpath".
 144	 */
 145	path = &state->altpath;
 146	ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
 147	for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
 148		if (blk->bp) {
 149			blk->disk_blkno = xfs_buf_daddr(blk->bp);
 150			blk->bp = NULL;
 151		} else {
 152			blk->disk_blkno = 0;
 153		}
 154	}
 155
 156	return 0;
 157}
 158
 159/*
 160 * Reattach the buffers to the state structure based on the disk block
 161 * numbers stored in the state structure.
 162 * This is done after some set of transaction commits have released those
 163 * buffers from our grip.
 164 */
 165static int
 166xfs_attr_refillstate(xfs_da_state_t *state)
 167{
 168	xfs_da_state_path_t *path;
 169	xfs_da_state_blk_t *blk;
 170	int level, error;
 171
 172	trace_xfs_attr_refillstate(state->args);
 173
 174	/*
 175	 * Roll down the "path" in the state structure, storing the on-disk
 176	 * block number for those buffers in the "path".
 177	 */
 178	path = &state->path;
 179	ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
 180	for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
 181		if (blk->disk_blkno) {
 182			error = xfs_da3_node_read_mapped(state->args->trans,
 183					state->args->dp, blk->disk_blkno,
 184					&blk->bp, XFS_ATTR_FORK);
 185			if (error)
 186				return error;
 187		} else {
 188			blk->bp = NULL;
 189		}
 190	}
 191
 192	/*
 193	 * Roll down the "altpath" in the state structure, storing the on-disk
 194	 * block number for those buffers in the "altpath".
 195	 */
 196	path = &state->altpath;
 197	ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
 198	for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
 199		if (blk->disk_blkno) {
 200			error = xfs_da3_node_read_mapped(state->args->trans,
 201					state->args->dp, blk->disk_blkno,
 202					&blk->bp, XFS_ATTR_FORK);
 203			if (error)
 204				return error;
 205		} else {
 206			blk->bp = NULL;
 207		}
 208	}
 209
 210	return 0;
 211}
 212#else
 213static int xfs_attr_fillstate(xfs_da_state_t *state) { return 0; }
 214#endif
 215
 216/*========================================================================
 217 * Overall external interface routines.
 218 *========================================================================*/
 219
 220/*
 221 * Retrieve an extended attribute and its value.  Must have ilock.
 222 * Returns 0 on successful retrieval, otherwise an error.
 223 */
 224int
 225xfs_attr_get_ilocked(
 226	struct xfs_da_args	*args)
 227{
 228	int			error;
 229
 230	xfs_assert_ilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL);
 231
 232	if (!xfs_inode_hasattr(args->dp))
 233		return -ENOATTR;
 234
 235	/*
 236	 * The incore attr fork iext tree must be loaded for xfs_attr_is_leaf
 237	 * to work correctly.
 238	 */
 239	error = xfs_iread_extents(args->trans, args->dp, XFS_ATTR_FORK);
 240	if (error)
 241		return error;
 242
 243	if (args->dp->i_af.if_format == XFS_DINODE_FMT_LOCAL)
 244		return xfs_attr_shortform_getvalue(args);
 245	if (xfs_attr_is_leaf(args->dp))
 246		return xfs_attr_leaf_get(args);
 247	return xfs_attr_node_get(args);
 248}
 249
 250/*
 251 * Retrieve an extended attribute by name, and its value if requested.
 252 *
 253 * If args->valuelen is zero, then the caller does not want the value, just an
 254 * indication whether the attribute exists and the size of the value if it
 255 * exists. The size is returned in args.valuelen.
 256 *
 257 * If args->value is NULL but args->valuelen is non-zero, allocate the buffer
 258 * for the value after existence of the attribute has been determined. The
 259 * caller always has to free args->value if it is set, no matter if this
 260 * function was successful or not.
 261 *
 262 * If the attribute is found, but exceeds the size limit set by the caller in
 263 * args->valuelen, return -ERANGE with the size of the attribute that was found
 264 * in args->valuelen.
 265 */
 266int
 267xfs_attr_get(
 268	struct xfs_da_args	*args)
 269{
 270	uint			lock_mode;
 271	int			error;
 272
 273	XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
 274
 275	if (xfs_is_shutdown(args->dp->i_mount))
 276		return -EIO;
 277
 278	if (!args->owner)
 279		args->owner = args->dp->i_ino;
 280	args->geo = args->dp->i_mount->m_attr_geo;
 281	args->whichfork = XFS_ATTR_FORK;
 282	xfs_attr_sethash(args);
 283
 284	/* Entirely possible to look up a name which doesn't exist */
 285	args->op_flags = XFS_DA_OP_OKNOENT;
 286
 287	lock_mode = xfs_ilock_attr_map_shared(args->dp);
 288	error = xfs_attr_get_ilocked(args);
 289	xfs_iunlock(args->dp, lock_mode);
 290
 291	return error;
 292}
 293
 294/*
 295 * Calculate how many blocks we need for the new attribute,
 296 */
 297int
 298xfs_attr_calc_size(
 299	struct xfs_da_args	*args,
 300	int			*local)
 301{
 302	struct xfs_mount	*mp = args->dp->i_mount;
 303	int			size;
 304	int			nblks;
 305
 306	/*
 307	 * Determine space new attribute will use, and if it would be
 308	 * "local" or "remote" (note: local != inline).
 309	 */
 310	size = xfs_attr_leaf_newentsize(args, local);
 311	nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
 312	if (*local) {
 313		if (size > (args->geo->blksize / 2)) {
 314			/* Double split possible */
 315			nblks *= 2;
 316		}
 317	} else {
 318		/*
 319		 * Out of line attribute, cannot double split, but
 320		 * make room for the attribute value itself.
 321		 */
 322		uint	dblocks = xfs_attr3_rmt_blocks(mp, args->valuelen);
 323		nblks += dblocks;
 324		nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
 325	}
 326
 327	return nblks;
 328}
 329
 330/* Initialize transaction reservation for an xattr set/replace/upsert */
 331inline struct xfs_trans_res
 332xfs_attr_set_resv(
 333	const struct xfs_da_args	*args)
 334{
 335	struct xfs_mount		*mp = args->dp->i_mount;
 336	struct xfs_trans_res		ret = {
 337		.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
 338			    M_RES(mp)->tr_attrsetrt.tr_logres * args->total,
 339		.tr_logcount		= XFS_ATTRSET_LOG_COUNT,
 340		.tr_logflags		= XFS_TRANS_PERM_LOG_RES,
 341	};
 342
 343	return ret;
 344}
 345
 346/*
 347 * Add an attr to a shortform fork. If there is no space,
 348 * xfs_attr_shortform_addname() will convert to leaf format and return -ENOSPC.
 349 * to use.
 350 */
 351STATIC int
 352xfs_attr_try_sf_addname(
 353	struct xfs_inode	*dp,
 354	struct xfs_da_args	*args)
 355{
 356
 357	int			error;
 358
 359	/*
 360	 * Build initial attribute list (if required).
 361	 */
 362	if (dp->i_af.if_format == XFS_DINODE_FMT_EXTENTS)
 363		xfs_attr_shortform_create(args);
 364
 365	error = xfs_attr_shortform_addname(args);
 366	if (error == -ENOSPC)
 367		return error;
 368
 369	/*
 370	 * Commit the shortform mods, and we're done.
 371	 * NOTE: this is also the error path (EEXIST, etc).
 372	 */
 373	if (!error)
 374		xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
 375
 376	if (xfs_has_wsync(dp->i_mount))
 377		xfs_trans_set_sync(args->trans);
 378
 379	return error;
 380}
 381
 382static int
 383xfs_attr_sf_addname(
 384	struct xfs_attr_intent		*attr)
 385{
 386	struct xfs_da_args		*args = attr->xattri_da_args;
 387	struct xfs_inode		*dp = args->dp;
 388	int				error = 0;
 389
 390	error = xfs_attr_try_sf_addname(dp, args);
 391	if (error != -ENOSPC) {
 392		ASSERT(!error || error == -EEXIST);
 393		attr->xattri_dela_state = XFS_DAS_DONE;
 394		goto out;
 395	}
 396
 397	/*
 398	 * It won't fit in the shortform, transform to a leaf block.  GROT:
 399	 * another possible req'mt for a double-split btree op.
 400	 */
 401	error = xfs_attr_shortform_to_leaf(args);
 402	if (error)
 403		return error;
 404
 405	attr->xattri_dela_state = XFS_DAS_LEAF_ADD;
 406out:
 407	trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp);
 408	return error;
 409}
 410
 411/* Compute the hash value for a user/root/secure extended attribute */
 412xfs_dahash_t
 413xfs_attr_hashname(
 414	const uint8_t		*name,
 415	int			namelen)
 416{
 417	return xfs_da_hashname(name, namelen);
 418}
 419
 420/* Compute the hash value for any extended attribute from any namespace. */
 421xfs_dahash_t
 422xfs_attr_hashval(
 423	struct xfs_mount	*mp,
 424	unsigned int		attr_flags,
 425	const uint8_t		*name,
 426	int			namelen,
 427	const void		*value,
 428	int			valuelen)
 429{
 430	ASSERT(xfs_attr_check_namespace(attr_flags));
 431
 432	if (attr_flags & XFS_ATTR_PARENT)
 433		return xfs_parent_hashattr(mp, name, namelen, value, valuelen);
 434
 435	return xfs_attr_hashname(name, namelen);
 436}
 437
 438/* Save the current remote block info and clear the current pointers. */
 439static void
 440xfs_attr_save_rmt_blk(
 441	struct xfs_da_args	*args)
 442{
 443	args->blkno2 = args->blkno;
 444	args->index2 = args->index;
 445	args->rmtblkno2 = args->rmtblkno;
 446	args->rmtblkcnt2 = args->rmtblkcnt;
 447	args->rmtvaluelen2 = args->rmtvaluelen;
 448	args->rmtblkno = 0;
 449	args->rmtblkcnt = 0;
 450	args->rmtvaluelen = 0;
 451}
 452
 453/* Set stored info about a remote block */
 454static void
 455xfs_attr_restore_rmt_blk(
 456	struct xfs_da_args	*args)
 457{
 458	args->blkno = args->blkno2;
 459	args->index = args->index2;
 460	args->rmtblkno = args->rmtblkno2;
 461	args->rmtblkcnt = args->rmtblkcnt2;
 462	args->rmtvaluelen = args->rmtvaluelen2;
 463}
 464
 465/*
 466 * PPTR_REPLACE operations require the caller to set the old and new names and
 467 * values explicitly.  Update the canonical fields to the new name and value
 468 * here now that the removal phase has finished.
 469 */
 470static void
 471xfs_attr_update_pptr_replace_args(
 472	struct xfs_da_args	*args)
 473{
 474	ASSERT(args->new_namelen > 0);
 475	args->name = args->new_name;
 476	args->namelen = args->new_namelen;
 477	args->value = args->new_value;
 478	args->valuelen = args->new_valuelen;
 479	xfs_attr_sethash(args);
 480}
 481
 482/*
 483 * Handle the state change on completion of a multi-state attr operation.
 484 *
 485 * If the XFS_DA_OP_REPLACE flag is set, this means the operation was the first
 486 * modification in a attr replace operation and we still have to do the second
 487 * state, indicated by @replace_state.
 488 *
 489 * We consume the XFS_DA_OP_REPLACE flag so that when we are called again on
 490 * completion of the second half of the attr replace operation we correctly
 491 * signal that it is done.
 492 */
 493static enum xfs_delattr_state
 494xfs_attr_complete_op(
 495	struct xfs_attr_intent	*attr,
 496	enum xfs_delattr_state	replace_state)
 497{
 498	struct xfs_da_args	*args = attr->xattri_da_args;
 499
 500	if (!(args->op_flags & XFS_DA_OP_REPLACE))
 501		replace_state = XFS_DAS_DONE;
 502	else if (xfs_attr_intent_op(attr) == XFS_ATTRI_OP_FLAGS_PPTR_REPLACE)
 503		xfs_attr_update_pptr_replace_args(args);
 504
 505	args->op_flags &= ~XFS_DA_OP_REPLACE;
 506	args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
 507	return replace_state;
 508}
 509
 510/*
 511 * Try to add an attribute to an inode in leaf form.
 512 */
 513static int
 514xfs_attr_leaf_addname(
 515	struct xfs_attr_intent	*attr)
 516{
 517	struct xfs_da_args	*args = attr->xattri_da_args;
 518	struct xfs_buf		*bp;
 519	int			error;
 520
 521	ASSERT(xfs_attr_is_leaf(args->dp));
 522
 523	error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
 524	if (error)
 525		return error;
 526
 527	/*
 528	 * Look up the xattr name to set the insertion point for the new xattr.
 529	 */
 530	error = xfs_attr3_leaf_lookup_int(bp, args);
 531	switch (error) {
 532	case -ENOATTR:
 533		if (args->op_flags & XFS_DA_OP_REPLACE)
 534			goto out_brelse;
 535		break;
 536	case -EEXIST:
 537		if (!(args->op_flags & XFS_DA_OP_REPLACE))
 538			goto out_brelse;
 539
 540		trace_xfs_attr_leaf_replace(args);
 541		/*
 542		 * Save the existing remote attr state so that the current
 543		 * values reflect the state of the new attribute we are about to
 544		 * add, not the attribute we just found and will remove later.
 545		 */
 546		xfs_attr_save_rmt_blk(args);
 547		break;
 548	case 0:
 549		break;
 550	default:
 551		goto out_brelse;
 552	}
 553
 554	/*
 555	 * We need to commit and roll if we need to allocate remote xattr blocks
 556	 * or perform more xattr manipulations. Otherwise there is nothing more
 557	 * to do and we can return success.
 558	 */
 559	if (!xfs_attr3_leaf_add(bp, args)) {
 560		error = xfs_attr3_leaf_to_node(args);
 561		if (error)
 562			return error;
 563
 564		attr->xattri_dela_state = XFS_DAS_NODE_ADD;
 565	} else if (args->rmtblkno) {
 566		attr->xattri_dela_state = XFS_DAS_LEAF_SET_RMT;
 567	} else {
 568		attr->xattri_dela_state =
 569			xfs_attr_complete_op(attr, XFS_DAS_LEAF_REPLACE);
 570	}
 571
 572	trace_xfs_attr_leaf_addname_return(attr->xattri_dela_state, args->dp);
 573	return 0;
 574
 575out_brelse:
 576	xfs_trans_brelse(args->trans, bp);
 577	return error;
 578}
 579
 580/*
 581 * Add an entry to a node format attr tree.
 582 *
 583 * Note that we might still have a leaf here - xfs_attr_is_leaf() cannot tell
 584 * the difference between leaf + remote attr blocks and a node format tree,
 585 * so we may still end up having to convert from leaf to node format here.
 586 */
 587static int
 588xfs_attr_node_addname(
 589	struct xfs_attr_intent	*attr)
 590{
 591	struct xfs_da_args	*args = attr->xattri_da_args;
 592	int			error;
 593
 594	error = xfs_attr_node_addname_find_attr(attr);
 595	if (error)
 596		return error;
 597
 598	error = xfs_attr_node_try_addname(attr);
 599	if (error == 1) {
 600		error = xfs_attr3_leaf_to_node(args);
 601		if (error)
 602			return error;
 603		/*
 604		 * No state change, we really are in node form now
 605		 * but we need the transaction rolled to continue.
 606		 */
 607		goto out;
 608	}
 609	if (error)
 610		return error;
 611
 612	if (args->rmtblkno)
 613		attr->xattri_dela_state = XFS_DAS_NODE_SET_RMT;
 614	else
 615		attr->xattri_dela_state = xfs_attr_complete_op(attr,
 616							XFS_DAS_NODE_REPLACE);
 617out:
 618	trace_xfs_attr_node_addname_return(attr->xattri_dela_state, args->dp);
 619	return error;
 620}
 621
 622static int
 623xfs_attr_rmtval_alloc(
 624	struct xfs_attr_intent		*attr)
 625{
 626	struct xfs_da_args              *args = attr->xattri_da_args;
 627	int				error = 0;
 628
 629	/*
 630	 * If there was an out-of-line value, allocate the blocks we
 631	 * identified for its storage and copy the value.  This is done
 632	 * after we create the attribute so that we don't overflow the
 633	 * maximum size of a transaction and/or hit a deadlock.
 634	 */
 635	if (attr->xattri_blkcnt > 0) {
 636		error = xfs_attr_rmtval_set_blk(attr);
 637		if (error)
 638			return error;
 639		/* Roll the transaction only if there is more to allocate. */
 640		if (attr->xattri_blkcnt > 0)
 641			goto out;
 642	}
 643
 644	error = xfs_attr_rmtval_set_value(args);
 645	if (error)
 646		return error;
 647
 648	attr->xattri_dela_state = xfs_attr_complete_op(attr,
 649						++attr->xattri_dela_state);
 650	/*
 651	 * If we are not doing a rename, we've finished the operation but still
 652	 * have to clear the incomplete flag protecting the new attr from
 653	 * exposing partially initialised state if we crash during creation.
 654	 */
 655	if (attr->xattri_dela_state == XFS_DAS_DONE)
 656		error = xfs_attr3_leaf_clearflag(args);
 657out:
 658	trace_xfs_attr_rmtval_alloc(attr->xattri_dela_state, args->dp);
 659	return error;
 660}
 661
 662/*
 663 * Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
 664 * for later deletion of the entry.
 665 */
 666static int
 667xfs_attr_leaf_mark_incomplete(
 668	struct xfs_da_args	*args,
 669	struct xfs_da_state	*state)
 670{
 671	int			error;
 672
 673	/*
 674	 * Fill in disk block numbers in the state structure
 675	 * so that we can get the buffers back after we commit
 676	 * several transactions in the following calls.
 677	 */
 678	error = xfs_attr_fillstate(state);
 679	if (error)
 680		return error;
 681
 682	/*
 683	 * Mark the attribute as INCOMPLETE
 684	 */
 685	return xfs_attr3_leaf_setflag(args);
 686}
 687
 688/* Ensure the da state of an xattr deferred work item is ready to go. */
 689static inline void
 690xfs_attr_item_init_da_state(
 691	struct xfs_attr_intent	*attr)
 692{
 693	struct xfs_da_args	*args = attr->xattri_da_args;
 694
 695	if (!attr->xattri_da_state)
 696		attr->xattri_da_state = xfs_da_state_alloc(args);
 697	else
 698		xfs_da_state_reset(attr->xattri_da_state, args);
 699}
 700
 701/*
 702 * Initial setup for xfs_attr_node_removename.  Make sure the attr is there and
 703 * the blocks are valid.  Attr keys with remote blocks will be marked
 704 * incomplete.
 705 */
 706static
 707int xfs_attr_node_removename_setup(
 708	struct xfs_attr_intent		*attr)
 709{
 710	struct xfs_da_args		*args = attr->xattri_da_args;
 711	struct xfs_da_state		*state;
 712	int				error;
 713
 714	xfs_attr_item_init_da_state(attr);
 715	error = xfs_attr_node_lookup(args, attr->xattri_da_state);
 716	if (error != -EEXIST)
 717		goto out;
 718	error = 0;
 719
 720	state = attr->xattri_da_state;
 721	ASSERT(state->path.blk[state->path.active - 1].bp != NULL);
 722	ASSERT(state->path.blk[state->path.active - 1].magic ==
 723		XFS_ATTR_LEAF_MAGIC);
 724
 725	error = xfs_attr_leaf_mark_incomplete(args, state);
 726	if (error)
 727		goto out;
 728	if (args->rmtblkno > 0)
 729		error = xfs_attr_rmtval_invalidate(args);
 730out:
 731	if (error) {
 732		xfs_da_state_free(attr->xattri_da_state);
 733		attr->xattri_da_state = NULL;
 734	}
 735
 736	return error;
 737}
 738
 739/*
 740 * Remove the original attr we have just replaced. This is dependent on the
 741 * original lookup and insert placing the old attr in args->blkno/args->index
 742 * and the new attr in args->blkno2/args->index2.
 743 */
 744static int
 745xfs_attr_leaf_remove_attr(
 746	struct xfs_attr_intent		*attr)
 747{
 748	struct xfs_da_args              *args = attr->xattri_da_args;
 749	struct xfs_inode		*dp = args->dp;
 750	struct xfs_buf			*bp = NULL;
 751	int				forkoff;
 752	int				error;
 753
 754	error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
 755			args->blkno, &bp);
 756	if (error)
 757		return error;
 758
 759	xfs_attr3_leaf_remove(bp, args);
 760
 761	forkoff = xfs_attr_shortform_allfit(bp, dp);
 762	if (forkoff)
 763		error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
 764		/* bp is gone due to xfs_da_shrink_inode */
 765
 766	return error;
 767}
 768
 769/*
 770 * Shrink an attribute from leaf to shortform. Used by the node format remove
 771 * path when the node format collapses to a single block and so we have to check
 772 * if it can be collapsed further.
 773 */
 774static int
 775xfs_attr_leaf_shrink(
 776	struct xfs_da_args	*args)
 777{
 778	struct xfs_inode	*dp = args->dp;
 779	struct xfs_buf		*bp;
 780	int			forkoff;
 781	int			error;
 782
 783	if (!xfs_attr_is_leaf(dp))
 784		return 0;
 785
 786	error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
 787	if (error)
 788		return error;
 789
 790	forkoff = xfs_attr_shortform_allfit(bp, dp);
 791	if (forkoff) {
 792		error = xfs_attr3_leaf_to_shortform(bp, args, forkoff);
 793		/* bp is gone due to xfs_da_shrink_inode */
 794	} else {
 795		xfs_trans_brelse(args->trans, bp);
 796	}
 797
 798	return error;
 799}
 800
 801/*
 802 * Run the attribute operation specified in @attr.
 803 *
 804 * This routine is meant to function as a delayed operation and will set the
 805 * state to XFS_DAS_DONE when the operation is complete.  Calling functions will
 806 * need to handle this, and recall the function until either an error or
 807 * XFS_DAS_DONE is detected.
 808 */
 809int
 810xfs_attr_set_iter(
 811	struct xfs_attr_intent		*attr)
 812{
 813	struct xfs_da_args              *args = attr->xattri_da_args;
 814	int				error = 0;
 815
 816	/* State machine switch */
 817next_state:
 818	switch (attr->xattri_dela_state) {
 819	case XFS_DAS_UNINIT:
 820		ASSERT(0);
 821		return -EFSCORRUPTED;
 822	case XFS_DAS_SF_ADD:
 823		return xfs_attr_sf_addname(attr);
 824	case XFS_DAS_LEAF_ADD:
 825		return xfs_attr_leaf_addname(attr);
 826	case XFS_DAS_NODE_ADD:
 827		return xfs_attr_node_addname(attr);
 828
 829	case XFS_DAS_SF_REMOVE:
 830		error = xfs_attr_sf_removename(args);
 831		attr->xattri_dela_state = xfs_attr_complete_op(attr,
 832						xfs_attr_init_add_state(args));
 833		break;
 834	case XFS_DAS_LEAF_REMOVE:
 835		error = xfs_attr_leaf_removename(args);
 836		attr->xattri_dela_state = xfs_attr_complete_op(attr,
 837						xfs_attr_init_add_state(args));
 838		break;
 839	case XFS_DAS_NODE_REMOVE:
 840		error = xfs_attr_node_removename_setup(attr);
 841		if (error == -ENOATTR &&
 842		    (args->op_flags & XFS_DA_OP_RECOVERY)) {
 843			attr->xattri_dela_state = xfs_attr_complete_op(attr,
 844						xfs_attr_init_add_state(args));
 845			error = 0;
 846			break;
 847		}
 848		if (error)
 849			return error;
 850		attr->xattri_dela_state = XFS_DAS_NODE_REMOVE_RMT;
 851		if (args->rmtblkno == 0)
 852			attr->xattri_dela_state++;
 853		break;
 854
 855	case XFS_DAS_LEAF_SET_RMT:
 856	case XFS_DAS_NODE_SET_RMT:
 857		error = xfs_attr_rmtval_find_space(attr);
 858		if (error)
 859			return error;
 860		attr->xattri_dela_state++;
 861		fallthrough;
 862
 863	case XFS_DAS_LEAF_ALLOC_RMT:
 864	case XFS_DAS_NODE_ALLOC_RMT:
 865		error = xfs_attr_rmtval_alloc(attr);
 866		if (error)
 867			return error;
 868		if (attr->xattri_dela_state == XFS_DAS_DONE)
 869			break;
 870		goto next_state;
 871
 872	case XFS_DAS_LEAF_REPLACE:
 873	case XFS_DAS_NODE_REPLACE:
 874		/*
 875		 * We must "flip" the incomplete flags on the "new" and "old"
 876		 * attribute/value pairs so that one disappears and one appears
 877		 * atomically.
 878		 */
 879		error = xfs_attr3_leaf_flipflags(args);
 880		if (error)
 881			return error;
 882		/*
 883		 * We must commit the flag value change now to make it atomic
 884		 * and then we can start the next trans in series at REMOVE_OLD.
 885		 */
 886		attr->xattri_dela_state++;
 887		break;
 888
 889	case XFS_DAS_LEAF_REMOVE_OLD:
 890	case XFS_DAS_NODE_REMOVE_OLD:
 891		/*
 892		 * If we have a remote attr, start the process of removing it
 893		 * by invalidating any cached buffers.
 894		 *
 895		 * If we don't have a remote attr, we skip the remote block
 896		 * removal state altogether with a second state increment.
 897		 */
 898		xfs_attr_restore_rmt_blk(args);
 899		if (args->rmtblkno) {
 900			error = xfs_attr_rmtval_invalidate(args);
 901			if (error)
 902				return error;
 903		} else {
 904			attr->xattri_dela_state++;
 905		}
 906
 907		attr->xattri_dela_state++;
 908		goto next_state;
 909
 910	case XFS_DAS_LEAF_REMOVE_RMT:
 911	case XFS_DAS_NODE_REMOVE_RMT:
 912		error = xfs_attr_rmtval_remove(attr);
 913		if (error == -EAGAIN) {
 914			error = 0;
 915			break;
 916		}
 917		if (error)
 918			return error;
 919
 920		/*
 921		 * We've finished removing the remote attr blocks, so commit the
 922		 * transaction and move on to removing the attr name from the
 923		 * leaf/node block. Removing the attr might require a full
 924		 * transaction reservation for btree block freeing, so we
 925		 * can't do that in the same transaction where we removed the
 926		 * remote attr blocks.
 927		 */
 928		attr->xattri_dela_state++;
 929		break;
 930
 931	case XFS_DAS_LEAF_REMOVE_ATTR:
 932		error = xfs_attr_leaf_remove_attr(attr);
 933		attr->xattri_dela_state = xfs_attr_complete_op(attr,
 934						xfs_attr_init_add_state(args));
 935		break;
 936
 937	case XFS_DAS_NODE_REMOVE_ATTR:
 938		error = xfs_attr_node_remove_attr(attr);
 939		if (!error)
 940			error = xfs_attr_leaf_shrink(args);
 941		attr->xattri_dela_state = xfs_attr_complete_op(attr,
 942						xfs_attr_init_add_state(args));
 943		break;
 944	default:
 945		ASSERT(0);
 946		break;
 947	}
 948
 949	trace_xfs_attr_set_iter_return(attr->xattri_dela_state, args->dp);
 950	return error;
 951}
 952
 953
 954/*
 955 * Return EEXIST if attr is found, or ENOATTR if not
 956 */
 957static int
 958xfs_attr_lookup(
 959	struct xfs_da_args	*args)
 960{
 961	struct xfs_inode	*dp = args->dp;
 962	struct xfs_buf		*bp = NULL;
 963	struct xfs_da_state	*state;
 964	int			error;
 965
 966	if (!xfs_inode_hasattr(dp))
 967		return -ENOATTR;
 968
 969	if (dp->i_af.if_format == XFS_DINODE_FMT_LOCAL) {
 970		if (xfs_attr_sf_findname(args))
 971			return -EEXIST;
 972		return -ENOATTR;
 973	}
 974
 975	/* Prerequisite for xfs_attr_is_leaf */
 976	error = xfs_iread_extents(args->trans, args->dp, XFS_ATTR_FORK);
 977	if (error)
 978		return error;
 979
 980	if (xfs_attr_is_leaf(dp)) {
 981		error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner,
 982				0, &bp);
 983		if (error)
 984			return error;
 985		error = xfs_attr3_leaf_lookup_int(bp, args);
 986		xfs_trans_brelse(args->trans, bp);
 987		return error;
 988	}
 989
 990	state = xfs_da_state_alloc(args);
 991	error = xfs_attr_node_lookup(args, state);
 992	xfs_da_state_free(state);
 993	return error;
 994}
 995
 996int
 997xfs_attr_add_fork(
 998	struct xfs_inode	*ip,		/* incore inode pointer */
 999	int			size,		/* space new attribute needs */
1000	int			rsvd)		/* xact may use reserved blks */
1001{
1002	struct xfs_mount	*mp = ip->i_mount;
1003	struct xfs_trans	*tp;		/* transaction pointer */
1004	unsigned int		blks;		/* space reservation */
1005	int			error;		/* error return value */
1006
1007	if (!xfs_is_metadir_inode(ip))
1008		ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
1009
1010	blks = XFS_ADDAFORK_SPACE_RES(mp);
1011
1012	error = xfs_trans_alloc_inode(ip, &M_RES(mp)->tr_addafork, blks, 0,
1013			rsvd, &tp);
1014	if (error)
1015		return error;
1016
1017	if (xfs_inode_has_attr_fork(ip))
1018		goto trans_cancel;
1019
1020	error = xfs_bmap_add_attrfork(tp, ip, size, rsvd);
1021	if (error)
1022		goto trans_cancel;
1023
1024	error = xfs_trans_commit(tp);
1025	xfs_iunlock(ip, XFS_ILOCK_EXCL);
1026	return error;
1027
1028trans_cancel:
1029	xfs_trans_cancel(tp);
1030	xfs_iunlock(ip, XFS_ILOCK_EXCL);
1031	return error;
1032}
1033
1034/*
1035 * Make a change to the xattr structure.
1036 *
1037 * The caller must have initialized @args, attached dquots, and must not hold
1038 * any ILOCKs.  Reserved data blocks may be used if @rsvd is set.
1039 *
1040 * Returns -EEXIST for XFS_ATTRUPDATE_CREATE if the name already exists.
1041 * Returns -ENOATTR for XFS_ATTRUPDATE_REMOVE if the name does not exist.
1042 * Returns 0 on success, or a negative errno if something else went wrong.
1043 */
1044int
1045xfs_attr_set(
1046	struct xfs_da_args	*args,
1047	enum xfs_attr_update	op,
1048	bool			rsvd)
1049{
1050	struct xfs_inode	*dp = args->dp;
1051	struct xfs_mount	*mp = dp->i_mount;
1052	struct xfs_trans_res	tres;
1053	int			error, local;
1054	int			rmt_blks = 0;
1055	unsigned int		total = 0;
1056
1057	ASSERT(!args->trans);
1058
1059	switch (op) {
1060	case XFS_ATTRUPDATE_UPSERT:
1061	case XFS_ATTRUPDATE_CREATE:
1062	case XFS_ATTRUPDATE_REPLACE:
1063		XFS_STATS_INC(mp, xs_attr_set);
1064		args->total = xfs_attr_calc_size(args, &local);
1065
1066		/*
1067		 * If the inode doesn't have an attribute fork, add one.
1068		 * (inode must not be locked when we call this routine)
1069		 */
1070		if (xfs_inode_has_attr_fork(dp) == 0) {
1071			int sf_size = sizeof(struct xfs_attr_sf_hdr) +
1072				xfs_attr_sf_entsize_byname(args->namelen,
1073						args->valuelen);
1074
1075			error = xfs_attr_add_fork(dp, sf_size, rsvd);
1076			if (error)
1077				return error;
1078		}
1079
1080		if (!local)
1081			rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
1082
1083		tres = xfs_attr_set_resv(args);
1084		total = args->total;
1085		break;
1086	case XFS_ATTRUPDATE_REMOVE:
1087		XFS_STATS_INC(mp, xs_attr_remove);
1088		rmt_blks = xfs_attr3_max_rmt_blocks(mp);
1089		tres = M_RES(mp)->tr_attrrm;
1090		total = XFS_ATTRRM_SPACE_RES(mp);
1091		break;
1092	}
1093
1094	/*
1095	 * Root fork attributes can use reserved data blocks for this
1096	 * operation if necessary
1097	 */
1098	error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
1099	if (error)
1100		return error;
1101
1102	if (op != XFS_ATTRUPDATE_REMOVE || xfs_inode_hasattr(dp)) {
1103		error = xfs_iext_count_extend(args->trans, dp, XFS_ATTR_FORK,
1104				XFS_IEXT_ATTR_MANIP_CNT(rmt_blks));
1105		if (error)
1106			goto out_trans_cancel;
1107	}
1108
1109	error = xfs_attr_lookup(args);
1110	switch (error) {
1111	case -EEXIST:
1112		if (op == XFS_ATTRUPDATE_REMOVE) {
1113			/* if no value, we are performing a remove operation */
1114			xfs_attr_defer_add(args, XFS_ATTR_DEFER_REMOVE);
1115			break;
1116		}
1117
1118		/* Pure create fails if the attr already exists */
1119		if (op == XFS_ATTRUPDATE_CREATE)
1120			goto out_trans_cancel;
1121		xfs_attr_defer_add(args, XFS_ATTR_DEFER_REPLACE);
1122		break;
1123	case -ENOATTR:
1124		/* Can't remove what isn't there. */
1125		if (op == XFS_ATTRUPDATE_REMOVE)
1126			goto out_trans_cancel;
1127
1128		/* Pure replace fails if no existing attr to replace. */
1129		if (op == XFS_ATTRUPDATE_REPLACE)
1130			goto out_trans_cancel;
1131		xfs_attr_defer_add(args, XFS_ATTR_DEFER_SET);
1132		break;
1133	default:
1134		goto out_trans_cancel;
1135	}
1136
1137	/*
1138	 * If this is a synchronous mount, make sure that the
1139	 * transaction goes to disk before returning to the user.
1140	 */
1141	if (xfs_has_wsync(mp))
1142		xfs_trans_set_sync(args->trans);
1143
1144	xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
1145
1146	/*
1147	 * Commit the last in the sequence of transactions.
1148	 */
1149	xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
1150	error = xfs_trans_commit(args->trans);
1151out_unlock:
1152	xfs_iunlock(dp, XFS_ILOCK_EXCL);
1153	args->trans = NULL;
1154	return error;
1155
1156out_trans_cancel:
1157	if (args->trans)
1158		xfs_trans_cancel(args->trans);
1159	goto out_unlock;
1160}
1161
1162/*========================================================================
1163 * External routines when attribute list is inside the inode
1164 *========================================================================*/
1165
1166int xfs_attr_sf_totsize(struct xfs_inode *dp)
1167{
1168	struct xfs_attr_sf_hdr *sf = dp->i_af.if_data;
1169
1170	return be16_to_cpu(sf->totsize);
1171}
1172
1173/*
1174 * Add a name to the shortform attribute list structure
1175 * This is the external routine.
1176 */
1177static int
1178xfs_attr_shortform_addname(
1179	struct xfs_da_args	*args)
1180{
1181	int			newsize, forkoff;
1182
1183	trace_xfs_attr_sf_addname(args);
1184
1185	if (xfs_attr_sf_findname(args)) {
1186		int		error;
1187
1188		ASSERT(args->op_flags & XFS_DA_OP_REPLACE);
1189
1190		error = xfs_attr_sf_removename(args);
1191		if (error)
1192			return error;
1193
1194		/*
1195		 * Since we have removed the old attr, clear XFS_DA_OP_REPLACE
1196		 * so that the new attr doesn't fit in shortform format, the
1197		 * leaf format add routine won't trip over the attr not being
1198		 * around.
1199		 */
1200		args->op_flags &= ~XFS_DA_OP_REPLACE;
1201	} else {
1202		ASSERT(!(args->op_flags & XFS_DA_OP_REPLACE));
1203	}
1204
1205	if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
1206	    args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
1207		return -ENOSPC;
1208
1209	newsize = xfs_attr_sf_totsize(args->dp);
1210	newsize += xfs_attr_sf_entsize_byname(args->namelen, args->valuelen);
1211
1212	forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
1213	if (!forkoff)
1214		return -ENOSPC;
1215
1216	xfs_attr_shortform_add(args, forkoff);
1217	return 0;
1218}
1219
1220
1221/*========================================================================
1222 * External routines when attribute list is one block
1223 *========================================================================*/
1224
1225/*
1226 * Remove a name from the leaf attribute list structure
1227 *
1228 * This leaf block cannot have a "remote" value, we only call this routine
1229 * if bmap_one_block() says there is only one block (ie: no remote blks).
1230 */
1231STATIC int
1232xfs_attr_leaf_removename(
1233	struct xfs_da_args	*args)
1234{
1235	struct xfs_inode	*dp = args->dp;
1236	int			error, forkoff;
1237	struct xfs_buf		*bp;
1238
1239	trace_xfs_attr_leaf_removename(args);
1240
1241	error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
1242	if (error)
1243		return error;
1244	error = xfs_attr3_leaf_lookup_int(bp, args);
1245	if (error != -EEXIST) {
1246		xfs_trans_brelse(args->trans, bp);
1247		if (error == -ENOATTR && (args->op_flags & XFS_DA_OP_RECOVERY))
1248			return 0;
1249		return error;
1250	}
1251
1252	xfs_attr3_leaf_remove(bp, args);
1253
1254	/*
1255	 * If the result is small enough, shrink it all into the inode.
1256	 */
1257	forkoff = xfs_attr_shortform_allfit(bp, dp);
1258	if (forkoff)
1259		return xfs_attr3_leaf_to_shortform(bp, args, forkoff);
1260		/* bp is gone due to xfs_da_shrink_inode */
1261
1262	return 0;
1263}
1264
1265/*
1266 * Look up a name in a leaf attribute list structure.
1267 *
1268 * This leaf block cannot have a "remote" value, we only call this routine
1269 * if bmap_one_block() says there is only one block (ie: no remote blks).
1270 *
1271 * Returns 0 on successful retrieval, otherwise an error.
1272 */
1273STATIC int
1274xfs_attr_leaf_get(
1275	struct xfs_da_args	*args)
1276{
1277	struct xfs_buf		*bp;
1278	int			error;
1279
1280	trace_xfs_attr_leaf_get(args);
1281
1282	error = xfs_attr3_leaf_read(args->trans, args->dp, args->owner, 0, &bp);
1283	if (error)
1284		return error;
1285	error = xfs_attr3_leaf_lookup_int(bp, args);
1286	if (error == -EEXIST)
1287		error = xfs_attr3_leaf_getvalue(bp, args);
1288	xfs_trans_brelse(args->trans, bp);
1289	return error;
1290}
1291
1292/* Return EEXIST if attr is found, or ENOATTR if not. */
1293STATIC int
1294xfs_attr_node_lookup(
1295	struct xfs_da_args	*args,
1296	struct xfs_da_state	*state)
1297{
1298	int			retval, error;
1299
1300	/*
1301	 * Search to see if name exists, and get back a pointer to it.
1302	 */
1303	error = xfs_da3_node_lookup_int(state, &retval);
1304	if (error)
1305		return error;
1306
1307	return retval;
1308}
1309
1310/*========================================================================
1311 * External routines when attribute list size > geo->blksize
1312 *========================================================================*/
1313
1314STATIC int
1315xfs_attr_node_addname_find_attr(
1316	 struct xfs_attr_intent	*attr)
1317{
1318	struct xfs_da_args	*args = attr->xattri_da_args;
1319	int			error;
1320
1321	/*
1322	 * Search to see if name already exists, and get back a pointer
1323	 * to where it should go.
1324	 */
1325	xfs_attr_item_init_da_state(attr);
1326	error = xfs_attr_node_lookup(args, attr->xattri_da_state);
1327	switch (error) {
1328	case -ENOATTR:
1329		if (args->op_flags & XFS_DA_OP_REPLACE)
1330			goto error;
1331		break;
1332	case -EEXIST:
1333		if (!(args->op_flags & XFS_DA_OP_REPLACE))
1334			goto error;
1335
1336
1337		trace_xfs_attr_node_replace(args);
1338		/*
1339		 * Save the existing remote attr state so that the current
1340		 * values reflect the state of the new attribute we are about to
1341		 * add, not the attribute we just found and will remove later.
1342		 */
1343		xfs_attr_save_rmt_blk(args);
1344		break;
1345	case 0:
1346		break;
1347	default:
1348		goto error;
1349	}
1350
1351	return 0;
1352error:
1353	if (attr->xattri_da_state) {
1354		xfs_da_state_free(attr->xattri_da_state);
1355		attr->xattri_da_state = NULL;
1356	}
1357	return error;
1358}
1359
1360/*
1361 * Add a name to a Btree-format attribute list.
1362 *
1363 * This will involve walking down the Btree, and may involve splitting leaf
1364 * nodes and even splitting intermediate nodes up to and including the root
1365 * node (a special case of an intermediate node).
1366 *
1367 * If the tree was still in single leaf format and needs to converted to
1368 * real node format return 1 and let the caller handle that.
1369 */
1370static int
1371xfs_attr_node_try_addname(
1372	struct xfs_attr_intent		*attr)
1373{
1374	struct xfs_da_state		*state = attr->xattri_da_state;
1375	struct xfs_da_state_blk		*blk;
1376	int				error = 0;
1377
1378	trace_xfs_attr_node_addname(state->args);
1379
1380	blk = &state->path.blk[state->path.active-1];
1381	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1382
1383	if (!xfs_attr3_leaf_add(blk->bp, state->args)) {
1384		if (state->path.active == 1) {
1385			/*
1386			 * Its really a single leaf node, but it had
1387			 * out-of-line values so it looked like it *might*
1388			 * have been a b-tree. Let the caller deal with this.
1389			 */
1390			error = 1;
1391			goto out;
1392		}
1393
1394		/*
1395		 * Split as many Btree elements as required.
1396		 * This code tracks the new and old attr's location
1397		 * in the index/blkno/rmtblkno/rmtblkcnt fields and
1398		 * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
1399		 */
1400		error = xfs_da3_split(state);
1401		if (error)
1402			goto out;
1403	} else {
1404		/*
1405		 * Addition succeeded, update Btree hashvals.
1406		 */
1407		xfs_da3_fixhashpath(state, &state->path);
1408	}
1409
1410out:
1411	xfs_da_state_free(state);
1412	attr->xattri_da_state = NULL;
1413	return error;
1414}
1415
1416static int
1417xfs_attr_node_removename(
1418	struct xfs_da_args	*args,
1419	struct xfs_da_state	*state)
1420{
1421	struct xfs_da_state_blk	*blk;
1422	int			retval;
1423
1424	/*
1425	 * Remove the name and update the hashvals in the tree.
1426	 */
1427	blk = &state->path.blk[state->path.active-1];
1428	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1429	retval = xfs_attr3_leaf_remove(blk->bp, args);
1430	xfs_da3_fixhashpath(state, &state->path);
1431
1432	return retval;
1433}
1434
1435static int
1436xfs_attr_node_remove_attr(
1437	struct xfs_attr_intent		*attr)
1438{
1439	struct xfs_da_args		*args = attr->xattri_da_args;
1440	struct xfs_da_state		*state = xfs_da_state_alloc(args);
1441	int				retval = 0;
1442	int				error = 0;
1443
1444	/*
1445	 * The attr we are removing has already been marked incomplete, so
1446	 * we need to set the filter appropriately to re-find the "old"
1447	 * attribute entry after any split ops.
1448	 */
1449	args->attr_filter |= XFS_ATTR_INCOMPLETE;
1450	error = xfs_da3_node_lookup_int(state, &retval);
1451	if (error)
1452		goto out;
1453
1454	error = xfs_attr_node_removename(args, state);
1455
1456	/*
1457	 * Check to see if the tree needs to be collapsed.
1458	 */
1459	if (retval && (state->path.active > 1)) {
1460		error = xfs_da3_join(state);
1461		if (error)
1462			goto out;
1463	}
1464	retval = error = 0;
1465
1466out:
1467	xfs_da_state_free(state);
1468	if (error)
1469		return error;
1470	return retval;
1471}
1472
1473/*
1474 * Retrieve the attribute data from a node attribute list.
1475 *
1476 * This routine gets called for any attribute fork that has more than one
1477 * block, ie: both true Btree attr lists and for single-leaf-blocks with
1478 * "remote" values taking up more blocks.
1479 *
1480 * Returns 0 on successful retrieval, otherwise an error.
1481 */
1482STATIC int
1483xfs_attr_node_get(
1484	struct xfs_da_args	*args)
1485{
1486	struct xfs_da_state	*state;
1487	struct xfs_da_state_blk	*blk;
1488	int			i;
1489	int			error;
1490
1491	trace_xfs_attr_node_get(args);
1492
1493	/*
1494	 * Search to see if name exists, and get back a pointer to it.
1495	 */
1496	state = xfs_da_state_alloc(args);
1497	error = xfs_attr_node_lookup(args, state);
1498	if (error != -EEXIST)
1499		goto out_release;
1500
1501	/*
1502	 * Get the value, local or "remote"
1503	 */
1504	blk = &state->path.blk[state->path.active - 1];
1505	error = xfs_attr3_leaf_getvalue(blk->bp, args);
1506
1507	/*
1508	 * If not in a transaction, we have to release all the buffers.
1509	 */
1510out_release:
1511	for (i = 0; i < state->path.active; i++) {
1512		xfs_trans_brelse(args->trans, state->path.blk[i].bp);
1513		state->path.blk[i].bp = NULL;
1514	}
1515
1516	xfs_da_state_free(state);
1517	return error;
1518}
1519
1520/* Enforce that there is at most one namespace bit per attr. */
1521inline bool xfs_attr_check_namespace(unsigned int attr_flags)
1522{
1523	return hweight32(attr_flags & XFS_ATTR_NSP_ONDISK_MASK) < 2;
1524}
1525
1526/* Returns true if the attribute entry name is valid. */
1527bool
1528xfs_attr_namecheck(
1529	unsigned int	attr_flags,
1530	const void	*name,
1531	size_t		length)
1532{
1533	/* Only one namespace bit allowed. */
1534	if (!xfs_attr_check_namespace(attr_flags))
1535		return false;
1536
1537	/*
1538	 * MAXNAMELEN includes the trailing null, but (name/length) leave it
1539	 * out, so use >= for the length check.
1540	 */
1541	if (length >= MAXNAMELEN)
1542		return false;
1543
1544	/* Parent pointers have their own validation. */
1545	if (attr_flags & XFS_ATTR_PARENT)
1546		return xfs_parent_namecheck(attr_flags, name, length);
1547
1548	/* There shouldn't be any nulls here */
1549	return !memchr(name, 0, length);
1550}
1551
1552int __init
1553xfs_attr_intent_init_cache(void)
1554{
1555	xfs_attr_intent_cache = kmem_cache_create("xfs_attr_intent",
1556			sizeof(struct xfs_attr_intent),
1557			0, 0, NULL);
1558
1559	return xfs_attr_intent_cache != NULL ? 0 : -ENOMEM;
1560}
1561
1562void
1563xfs_attr_intent_destroy_cache(void)
1564{
1565	kmem_cache_destroy(xfs_attr_intent_cache);
1566	xfs_attr_intent_cache = NULL;
1567}
~/ Read-only file preview.