2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "xfs_types.h"
25 #include "xfs_trans.h"
29 #include "xfs_dmapi.h"
30 #include "xfs_mount.h"
31 #include "xfs_da_btree.h"
32 #include "xfs_bmap_btree.h"
33 #include "xfs_alloc_btree.h"
34 #include "xfs_ialloc_btree.h"
35 #include "xfs_dir2_sf.h"
36 #include "xfs_attr_sf.h"
37 #include "xfs_dinode.h"
38 #include "xfs_inode.h"
39 #include "xfs_alloc.h"
40 #include "xfs_btree.h"
41 #include "xfs_inode_item.h"
44 #include "xfs_attr_leaf.h"
45 #include "xfs_error.h"
46 #include "xfs_quota.h"
47 #include "xfs_trans_space.h"
50 #include "xfs_vnodeops.h"
55 * Provide the external interfaces to manage attribute lists.
58 /*========================================================================
59 * Function prototypes for the kernel.
60 *========================================================================*/
63 * Internal routines when attribute list fits inside the inode.
65 STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
68 * Internal routines when attribute list is one block.
70 STATIC int xfs_attr_leaf_get(xfs_da_args_t *args);
71 STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args);
72 STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args);
73 STATIC int xfs_attr_leaf_list(xfs_attr_list_context_t *context);
76 * Internal routines when attribute list is more than one block.
78 STATIC int xfs_attr_node_get(xfs_da_args_t *args);
79 STATIC int xfs_attr_node_addname(xfs_da_args_t *args);
80 STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
81 STATIC int xfs_attr_node_list(xfs_attr_list_context_t *context);
82 STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
83 STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
86 * Routines to manipulate out-of-line attribute values.
88 STATIC int xfs_attr_rmtval_set(xfs_da_args_t *args);
89 STATIC int xfs_attr_rmtval_remove(xfs_da_args_t *args);
91 #define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */
93 #if defined(XFS_ATTR_TRACE)
94 ktrace_t *xfs_attr_trace_buf;
98 xfs_attr_name_to_xname(
99 struct xfs_name *xname,
105 xname->len = strlen(aname);
106 if (xname->len >= MAXNAMELEN)
107 return EFAULT; /* match IRIX behaviour */
114 struct xfs_inode *ip)
116 if (!XFS_IFORK_Q(ip) ||
117 (ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
118 ip->i_d.di_anextents == 0))
123 /*========================================================================
124 * Overall external interface routines.
125 *========================================================================*/
128 xfs_attr_fetch(xfs_inode_t *ip, struct xfs_name *name,
129 char *value, int *valuelenp, int flags)
134 if (!xfs_inode_hasattr(ip))
138 * Fill in the arg structure for this request.
140 memset((char *)&args, 0, sizeof(args));
141 args.name = name->name;
142 args.namelen = name->len;
144 args.valuelen = *valuelenp;
146 args.hashval = xfs_da_hashname(args.name, args.namelen);
148 args.whichfork = XFS_ATTR_FORK;
151 * Decide on what work routines to call based on the inode size.
153 if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
154 error = xfs_attr_shortform_getvalue(&args);
155 } else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK)) {
156 error = xfs_attr_leaf_get(&args);
158 error = xfs_attr_node_get(&args);
162 * Return the number of bytes in the value to the caller.
164 *valuelenp = args.valuelen;
180 struct xfs_name xname;
182 XFS_STATS_INC(xs_attr_get);
184 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
187 error = xfs_attr_name_to_xname(&xname, name);
191 xfs_ilock(ip, XFS_ILOCK_SHARED);
192 error = xfs_attr_fetch(ip, &xname, value, valuelenp, flags);
193 xfs_iunlock(ip, XFS_ILOCK_SHARED);
198 xfs_attr_set_int(xfs_inode_t *dp, struct xfs_name *name,
199 char *value, int valuelen, int flags)
202 xfs_fsblock_t firstblock;
203 xfs_bmap_free_t flist;
204 int error, err2, committed;
207 xfs_mount_t *mp = dp->i_mount;
208 int rsvd = (flags & ATTR_ROOT) != 0;
211 * Attach the dquots to the inode.
213 if ((error = XFS_QM_DQATTACH(mp, dp, 0)))
217 * If the inode doesn't have an attribute fork, add one.
218 * (inode must not be locked when we call this routine)
220 if (XFS_IFORK_Q(dp) == 0) {
221 int sf_size = sizeof(xfs_attr_sf_hdr_t) +
222 XFS_ATTR_SF_ENTSIZE_BYNAME(name->len, valuelen);
224 if ((error = xfs_bmap_add_attrfork(dp, sf_size, rsvd)))
229 * Fill in the arg structure for this request.
231 memset((char *)&args, 0, sizeof(args));
232 args.name = name->name;
233 args.namelen = name->len;
235 args.valuelen = valuelen;
237 args.hashval = xfs_da_hashname(args.name, args.namelen);
239 args.firstblock = &firstblock;
241 args.whichfork = XFS_ATTR_FORK;
242 args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
245 * Determine space new attribute will use, and if it would be
246 * "local" or "remote" (note: local != inline).
248 size = xfs_attr_leaf_newentsize(name->len, valuelen,
249 mp->m_sb.sb_blocksize, &local);
251 nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
253 if (size > (mp->m_sb.sb_blocksize >> 1)) {
254 /* Double split possible */
258 uint dblocks = XFS_B_TO_FSB(mp, valuelen);
259 /* Out of line attribute, cannot double split, but make
260 * room for the attribute value itself.
263 nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
266 /* Size is now blocks for attribute data */
270 * Start our first transaction of the day.
272 * All future transactions during this code must be "chained" off
273 * this one via the trans_dup() call. All transactions will contain
274 * the inode, and the inode will always be marked with trans_ihold().
275 * Since the inode will be locked in all transactions, we must log
276 * the inode in every transaction to let it float upward through
279 args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_SET);
282 * Root fork attributes can use reserved data blocks for this
283 * operation if necessary
287 args.trans->t_flags |= XFS_TRANS_RESERVE;
289 if ((error = xfs_trans_reserve(args.trans, (uint) nblks,
290 XFS_ATTRSET_LOG_RES(mp, nblks),
291 0, XFS_TRANS_PERM_LOG_RES,
292 XFS_ATTRSET_LOG_COUNT))) {
293 xfs_trans_cancel(args.trans, 0);
296 xfs_ilock(dp, XFS_ILOCK_EXCL);
298 error = XFS_TRANS_RESERVE_QUOTA_NBLKS(mp, args.trans, dp, nblks, 0,
299 rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
300 XFS_QMOPT_RES_REGBLKS);
302 xfs_iunlock(dp, XFS_ILOCK_EXCL);
303 xfs_trans_cancel(args.trans, XFS_TRANS_RELEASE_LOG_RES);
307 xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
308 xfs_trans_ihold(args.trans, dp);
311 * If the attribute list is non-existent or a shortform list,
312 * upgrade it to a single-leaf-block attribute list.
314 if ((dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) ||
315 ((dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS) &&
316 (dp->i_d.di_anextents == 0))) {
319 * Build initial attribute list (if required).
321 if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS)
322 xfs_attr_shortform_create(&args);
325 * Try to add the attr to the attribute list in
328 error = xfs_attr_shortform_addname(&args);
329 if (error != ENOSPC) {
331 * Commit the shortform mods, and we're done.
332 * NOTE: this is also the error path (EEXIST, etc).
334 ASSERT(args.trans != NULL);
337 * If this is a synchronous mount, make sure that
338 * the transaction goes to disk before returning
341 if (mp->m_flags & XFS_MOUNT_WSYNC) {
342 xfs_trans_set_sync(args.trans);
344 err2 = xfs_trans_commit(args.trans,
345 XFS_TRANS_RELEASE_LOG_RES);
346 xfs_iunlock(dp, XFS_ILOCK_EXCL);
349 * Hit the inode change time.
351 if (!error && (flags & ATTR_KERNOTIME) == 0) {
352 xfs_ichgtime(dp, XFS_ICHGTIME_CHG);
354 return(error == 0 ? err2 : error);
358 * It won't fit in the shortform, transform to a leaf block.
359 * GROT: another possible req'mt for a double-split btree op.
361 XFS_BMAP_INIT(args.flist, args.firstblock);
362 error = xfs_attr_shortform_to_leaf(&args);
364 error = xfs_bmap_finish(&args.trans, args.flist,
370 xfs_bmap_cancel(&flist);
375 * bmap_finish() may have committed the last trans and started
376 * a new one. We need the inode to be in all transactions.
379 xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
380 xfs_trans_ihold(args.trans, dp);
384 * Commit the leaf transformation. We'll need another (linked)
385 * transaction to add the new attribute to the leaf.
387 if ((error = xfs_attr_rolltrans(&args.trans, dp)))
392 if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
393 error = xfs_attr_leaf_addname(&args);
395 error = xfs_attr_node_addname(&args);
402 * If this is a synchronous mount, make sure that the
403 * transaction goes to disk before returning to the user.
405 if (mp->m_flags & XFS_MOUNT_WSYNC) {
406 xfs_trans_set_sync(args.trans);
410 * Commit the last in the sequence of transactions.
412 xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
413 error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES);
414 xfs_iunlock(dp, XFS_ILOCK_EXCL);
417 * Hit the inode change time.
419 if (!error && (flags & ATTR_KERNOTIME) == 0) {
420 xfs_ichgtime(dp, XFS_ICHGTIME_CHG);
427 xfs_trans_cancel(args.trans,
428 XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
429 xfs_iunlock(dp, XFS_ILOCK_EXCL);
442 struct xfs_name xname;
444 XFS_STATS_INC(xs_attr_set);
446 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
449 error = xfs_attr_name_to_xname(&xname, name);
453 return xfs_attr_set_int(dp, &xname, value, valuelen, flags);
457 * Generic handler routine to remove a name from an attribute list.
458 * Transitions attribute list from Btree to shortform as necessary.
461 xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
464 xfs_fsblock_t firstblock;
465 xfs_bmap_free_t flist;
467 xfs_mount_t *mp = dp->i_mount;
470 * Fill in the arg structure for this request.
472 memset((char *)&args, 0, sizeof(args));
473 args.name = name->name;
474 args.namelen = name->len;
476 args.hashval = xfs_da_hashname(args.name, args.namelen);
478 args.firstblock = &firstblock;
481 args.whichfork = XFS_ATTR_FORK;
484 * Attach the dquots to the inode.
486 if ((error = XFS_QM_DQATTACH(mp, dp, 0)))
490 * Start our first transaction of the day.
492 * All future transactions during this code must be "chained" off
493 * this one via the trans_dup() call. All transactions will contain
494 * the inode, and the inode will always be marked with trans_ihold().
495 * Since the inode will be locked in all transactions, we must log
496 * the inode in every transaction to let it float upward through
499 args.trans = xfs_trans_alloc(mp, XFS_TRANS_ATTR_RM);
502 * Root fork attributes can use reserved data blocks for this
503 * operation if necessary
506 if (flags & ATTR_ROOT)
507 args.trans->t_flags |= XFS_TRANS_RESERVE;
509 if ((error = xfs_trans_reserve(args.trans,
510 XFS_ATTRRM_SPACE_RES(mp),
511 XFS_ATTRRM_LOG_RES(mp),
512 0, XFS_TRANS_PERM_LOG_RES,
513 XFS_ATTRRM_LOG_COUNT))) {
514 xfs_trans_cancel(args.trans, 0);
518 xfs_ilock(dp, XFS_ILOCK_EXCL);
520 * No need to make quota reservations here. We expect to release some
521 * blocks not allocate in the common case.
523 xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
524 xfs_trans_ihold(args.trans, dp);
527 * Decide on what work routines to call based on the inode size.
529 if (!xfs_inode_hasattr(dp)) {
530 error = XFS_ERROR(ENOATTR);
533 if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
534 ASSERT(dp->i_afp->if_flags & XFS_IFINLINE);
535 error = xfs_attr_shortform_remove(&args);
539 } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
540 error = xfs_attr_leaf_removename(&args);
542 error = xfs_attr_node_removename(&args);
549 * If this is a synchronous mount, make sure that the
550 * transaction goes to disk before returning to the user.
552 if (mp->m_flags & XFS_MOUNT_WSYNC) {
553 xfs_trans_set_sync(args.trans);
557 * Commit the last in the sequence of transactions.
559 xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
560 error = xfs_trans_commit(args.trans, XFS_TRANS_RELEASE_LOG_RES);
561 xfs_iunlock(dp, XFS_ILOCK_EXCL);
564 * Hit the inode change time.
566 if (!error && (flags & ATTR_KERNOTIME) == 0) {
567 xfs_ichgtime(dp, XFS_ICHGTIME_CHG);
574 xfs_trans_cancel(args.trans,
575 XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
576 xfs_iunlock(dp, XFS_ILOCK_EXCL);
587 struct xfs_name xname;
589 XFS_STATS_INC(xs_attr_remove);
591 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
594 error = xfs_attr_name_to_xname(&xname, name);
598 xfs_ilock(dp, XFS_ILOCK_SHARED);
599 if (!xfs_inode_hasattr(dp)) {
600 xfs_iunlock(dp, XFS_ILOCK_SHARED);
601 return XFS_ERROR(ENOATTR);
603 xfs_iunlock(dp, XFS_ILOCK_SHARED);
605 return xfs_attr_remove_int(dp, &xname, flags);
609 xfs_attr_list_int(xfs_attr_list_context_t *context)
612 xfs_inode_t *dp = context->dp;
614 XFS_STATS_INC(xs_attr_list);
616 if (XFS_FORCED_SHUTDOWN(dp->i_mount))
619 xfs_ilock(dp, XFS_ILOCK_SHARED);
620 xfs_attr_trace_l_c("syscall start", context);
623 * Decide on what work routines to call based on the inode size.
625 if (!xfs_inode_hasattr(dp)) {
627 } else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
628 error = xfs_attr_shortform_list(context);
629 } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
630 error = xfs_attr_leaf_list(context);
632 error = xfs_attr_node_list(context);
635 xfs_iunlock(dp, XFS_ILOCK_SHARED);
636 xfs_attr_trace_l_c("syscall end", context);
641 #define ATTR_ENTBASESIZE /* minimum bytes used by an attr */ \
642 (((struct attrlist_ent *) 0)->a_name - (char *) 0)
643 #define ATTR_ENTSIZE(namelen) /* actual bytes used by an attr */ \
644 ((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(u_int32_t)-1) \
645 & ~(sizeof(u_int32_t)-1))
648 * Format an attribute and copy it out to the user's buffer.
649 * Take care to check values and protect against them changing later,
650 * we may be reading them directly out of a user buffer.
654 xfs_attr_put_listent(xfs_attr_list_context_t *context, int flags,
655 char *name, int namelen,
656 int valuelen, char *value)
658 struct attrlist *alist = (struct attrlist *)context->alist;
662 ASSERT(!(context->flags & ATTR_KERNOVAL));
663 ASSERT(context->count >= 0);
664 ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
665 ASSERT(context->firstu >= sizeof(*alist));
666 ASSERT(context->firstu <= context->bufsize);
669 * Only list entries in the right namespace.
671 if (((context->flags & ATTR_SECURE) == 0) !=
672 ((flags & XFS_ATTR_SECURE) == 0))
674 if (((context->flags & ATTR_ROOT) == 0) !=
675 ((flags & XFS_ATTR_ROOT) == 0))
678 arraytop = sizeof(*alist) +
679 context->count * sizeof(alist->al_offset[0]);
680 context->firstu -= ATTR_ENTSIZE(namelen);
681 if (context->firstu < arraytop) {
682 xfs_attr_trace_l_c("buffer full", context);
684 context->seen_enough = 1;
688 aep = (attrlist_ent_t *)&context->alist[context->firstu];
689 aep->a_valuelen = valuelen;
690 memcpy(aep->a_name, name, namelen);
691 aep->a_name[namelen] = 0;
692 alist->al_offset[context->count++] = context->firstu;
693 alist->al_count = context->count;
694 xfs_attr_trace_l_c("add", context);
699 * Generate a list of extended attribute names and optionally
700 * also value lengths. Positive return value follows the XFS
701 * convention of being an error, zero or negative return code
702 * is the length of the buffer returned (negated), indicating
711 attrlist_cursor_kern_t *cursor)
713 xfs_attr_list_context_t context;
714 struct attrlist *alist;
718 * Validate the cursor.
720 if (cursor->pad1 || cursor->pad2)
721 return(XFS_ERROR(EINVAL));
722 if ((cursor->initted == 0) &&
723 (cursor->hashval || cursor->blkno || cursor->offset))
724 return XFS_ERROR(EINVAL);
727 * Check for a properly aligned buffer.
729 if (((long)buffer) & (sizeof(int)-1))
730 return XFS_ERROR(EFAULT);
731 if (flags & ATTR_KERNOVAL)
735 * Initialize the output buffer.
737 memset(&context, 0, sizeof(context));
739 context.cursor = cursor;
741 context.flags = flags;
742 context.alist = buffer;
743 context.bufsize = (bufsize & ~(sizeof(int)-1)); /* align */
744 context.firstu = context.bufsize;
745 context.put_listent = xfs_attr_put_listent;
747 alist = (struct attrlist *)context.alist;
750 alist->al_offset[0] = context.bufsize;
752 error = xfs_attr_list_int(&context);
758 xfs_attr_inactive(xfs_inode_t *dp)
765 ASSERT(! XFS_NOT_DQATTACHED(mp, dp));
767 xfs_ilock(dp, XFS_ILOCK_SHARED);
768 if (!xfs_inode_hasattr(dp) ||
769 dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
770 xfs_iunlock(dp, XFS_ILOCK_SHARED);
773 xfs_iunlock(dp, XFS_ILOCK_SHARED);
776 * Start our first transaction of the day.
778 * All future transactions during this code must be "chained" off
779 * this one via the trans_dup() call. All transactions will contain
780 * the inode, and the inode will always be marked with trans_ihold().
781 * Since the inode will be locked in all transactions, we must log
782 * the inode in every transaction to let it float upward through
785 trans = xfs_trans_alloc(mp, XFS_TRANS_ATTRINVAL);
786 if ((error = xfs_trans_reserve(trans, 0, XFS_ATTRINVAL_LOG_RES(mp), 0,
787 XFS_TRANS_PERM_LOG_RES,
788 XFS_ATTRINVAL_LOG_COUNT))) {
789 xfs_trans_cancel(trans, 0);
792 xfs_ilock(dp, XFS_ILOCK_EXCL);
795 * No need to make quota reservations here. We expect to release some
796 * blocks, not allocate, in the common case.
798 xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL);
799 xfs_trans_ihold(trans, dp);
802 * Decide on what work routines to call based on the inode size.
804 if (!xfs_inode_hasattr(dp) ||
805 dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
809 error = xfs_attr_root_inactive(&trans, dp);
813 * signal synchronous inactive transactions unless this
814 * is a synchronous mount filesystem in which case we
815 * know that we're here because we've been called out of
816 * xfs_inactive which means that the last reference is gone
817 * and the unlink transaction has already hit the disk so
818 * async inactive transactions are safe.
820 if ((error = xfs_itruncate_finish(&trans, dp, 0LL, XFS_ATTR_FORK,
821 (!(mp->m_flags & XFS_MOUNT_WSYNC)
826 * Commit the last in the sequence of transactions.
828 xfs_trans_log_inode(trans, dp, XFS_ILOG_CORE);
829 error = xfs_trans_commit(trans, XFS_TRANS_RELEASE_LOG_RES);
830 xfs_iunlock(dp, XFS_ILOCK_EXCL);
835 xfs_trans_cancel(trans, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
836 xfs_iunlock(dp, XFS_ILOCK_EXCL);
842 /*========================================================================
843 * External routines when attribute list is inside the inode
844 *========================================================================*/
847 * Add a name to the shortform attribute list structure
848 * This is the external routine.
851 xfs_attr_shortform_addname(xfs_da_args_t *args)
853 int newsize, forkoff, retval;
855 retval = xfs_attr_shortform_lookup(args);
856 if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
858 } else if (retval == EEXIST) {
859 if (args->flags & ATTR_CREATE)
861 retval = xfs_attr_shortform_remove(args);
865 if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
866 args->valuelen >= XFS_ATTR_SF_ENTSIZE_MAX)
867 return(XFS_ERROR(ENOSPC));
869 newsize = XFS_ATTR_SF_TOTSIZE(args->dp);
870 newsize += XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen);
872 forkoff = xfs_attr_shortform_bytesfit(args->dp, newsize);
874 return(XFS_ERROR(ENOSPC));
876 xfs_attr_shortform_add(args, forkoff);
881 /*========================================================================
882 * External routines when attribute list is one block
883 *========================================================================*/
886 * Add a name to the leaf attribute list structure
888 * This leaf block cannot have a "remote" value, we only call this routine
889 * if bmap_one_block() says there is only one block (ie: no remote blks).
892 xfs_attr_leaf_addname(xfs_da_args_t *args)
896 int retval, error, committed, forkoff;
899 * Read the (only) block in the attribute list in.
903 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp,
910 * Look up the given attribute in the leaf block. Figure out if
911 * the given flags produce an error or call for an atomic rename.
913 retval = xfs_attr_leaf_lookup_int(bp, args);
914 if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
915 xfs_da_brelse(args->trans, bp);
917 } else if (retval == EEXIST) {
918 if (args->flags & ATTR_CREATE) { /* pure create op */
919 xfs_da_brelse(args->trans, bp);
922 args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */
923 args->blkno2 = args->blkno; /* set 2nd entry info*/
924 args->index2 = args->index;
925 args->rmtblkno2 = args->rmtblkno;
926 args->rmtblkcnt2 = args->rmtblkcnt;
930 * Add the attribute to the leaf block, transitioning to a Btree
933 retval = xfs_attr_leaf_add(bp, args);
935 if (retval == ENOSPC) {
937 * Promote the attribute list to the Btree format, then
938 * Commit that transaction so that the node_addname() call
939 * can manage its own transactions.
941 XFS_BMAP_INIT(args->flist, args->firstblock);
942 error = xfs_attr_leaf_to_node(args);
944 error = xfs_bmap_finish(&args->trans, args->flist,
950 xfs_bmap_cancel(args->flist);
955 * bmap_finish() may have committed the last trans and started
956 * a new one. We need the inode to be in all transactions.
959 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
960 xfs_trans_ihold(args->trans, dp);
964 * Commit the current trans (including the inode) and start
967 if ((error = xfs_attr_rolltrans(&args->trans, dp)))
971 * Fob the whole rest of the problem off on the Btree code.
973 error = xfs_attr_node_addname(args);
978 * Commit the transaction that added the attr name so that
979 * later routines can manage their own transactions.
981 if ((error = xfs_attr_rolltrans(&args->trans, dp)))
985 * If there was an out-of-line value, allocate the blocks we
986 * identified for its storage and copy the value. This is done
987 * after we create the attribute so that we don't overflow the
988 * maximum size of a transaction and/or hit a deadlock.
990 if (args->rmtblkno > 0) {
991 error = xfs_attr_rmtval_set(args);
997 * If this is an atomic rename operation, we must "flip" the
998 * incomplete flags on the "new" and "old" attribute/value pairs
999 * so that one disappears and one appears atomically. Then we
1000 * must remove the "old" attribute/value pair.
1002 if (args->op_flags & XFS_DA_OP_RENAME) {
1004 * In a separate transaction, set the incomplete flag on the
1005 * "old" attr and clear the incomplete flag on the "new" attr.
1007 error = xfs_attr_leaf_flipflags(args);
1012 * Dismantle the "old" attribute/value pair by removing
1013 * a "remote" value (if it exists).
1015 args->index = args->index2;
1016 args->blkno = args->blkno2;
1017 args->rmtblkno = args->rmtblkno2;
1018 args->rmtblkcnt = args->rmtblkcnt2;
1019 if (args->rmtblkno) {
1020 error = xfs_attr_rmtval_remove(args);
1026 * Read in the block containing the "old" attr, then
1027 * remove the "old" attr from that block (neat, huh!)
1029 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1,
1030 &bp, XFS_ATTR_FORK);
1034 (void)xfs_attr_leaf_remove(bp, args);
1037 * If the result is small enough, shrink it all into the inode.
1039 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1040 XFS_BMAP_INIT(args->flist, args->firstblock);
1041 error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
1042 /* bp is gone due to xfs_da_shrink_inode */
1044 error = xfs_bmap_finish(&args->trans,
1051 xfs_bmap_cancel(args->flist);
1056 * bmap_finish() may have committed the last trans
1057 * and started a new one. We need the inode to be
1058 * in all transactions.
1061 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
1062 xfs_trans_ihold(args->trans, dp);
1065 xfs_da_buf_done(bp);
1068 * Commit the remove and start the next trans in series.
1070 error = xfs_attr_rolltrans(&args->trans, dp);
1072 } else if (args->rmtblkno > 0) {
1074 * Added a "remote" value, just clear the incomplete flag.
1076 error = xfs_attr_leaf_clearflag(args);
1082 * Remove a name from the leaf attribute list structure
1084 * This leaf block cannot have a "remote" value, we only call this routine
1085 * if bmap_one_block() says there is only one block (ie: no remote blks).
1088 xfs_attr_leaf_removename(xfs_da_args_t *args)
1092 int error, committed, forkoff;
1095 * Remove the attribute.
1099 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp,
1106 error = xfs_attr_leaf_lookup_int(bp, args);
1107 if (error == ENOATTR) {
1108 xfs_da_brelse(args->trans, bp);
1112 (void)xfs_attr_leaf_remove(bp, args);
1115 * If the result is small enough, shrink it all into the inode.
1117 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1118 XFS_BMAP_INIT(args->flist, args->firstblock);
1119 error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
1120 /* bp is gone due to xfs_da_shrink_inode */
1122 error = xfs_bmap_finish(&args->trans, args->flist,
1128 xfs_bmap_cancel(args->flist);
1133 * bmap_finish() may have committed the last trans and started
1134 * a new one. We need the inode to be in all transactions.
1137 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
1138 xfs_trans_ihold(args->trans, dp);
1141 xfs_da_buf_done(bp);
1146 * Look up a name in a leaf attribute list structure.
1148 * This leaf block cannot have a "remote" value, we only call this routine
1149 * if bmap_one_block() says there is only one block (ie: no remote blks).
1152 xfs_attr_leaf_get(xfs_da_args_t *args)
1158 error = xfs_da_read_buf(args->trans, args->dp, args->blkno, -1, &bp,
1164 error = xfs_attr_leaf_lookup_int(bp, args);
1165 if (error != EEXIST) {
1166 xfs_da_brelse(args->trans, bp);
1169 error = xfs_attr_leaf_getvalue(bp, args);
1170 xfs_da_brelse(args->trans, bp);
1171 if (!error && (args->rmtblkno > 0) && !(args->flags & ATTR_KERNOVAL)) {
1172 error = xfs_attr_rmtval_get(args);
1178 * Copy out attribute entries for attr_list(), for leaf attribute lists.
1181 xfs_attr_leaf_list(xfs_attr_list_context_t *context)
1183 xfs_attr_leafblock_t *leaf;
1187 context->cursor->blkno = 0;
1188 error = xfs_da_read_buf(NULL, context->dp, 0, -1, &bp, XFS_ATTR_FORK);
1190 return XFS_ERROR(error);
1193 if (unlikely(be16_to_cpu(leaf->hdr.info.magic) != XFS_ATTR_LEAF_MAGIC)) {
1194 XFS_CORRUPTION_ERROR("xfs_attr_leaf_list", XFS_ERRLEVEL_LOW,
1195 context->dp->i_mount, leaf);
1196 xfs_da_brelse(NULL, bp);
1197 return XFS_ERROR(EFSCORRUPTED);
1200 error = xfs_attr_leaf_list_int(bp, context);
1201 xfs_da_brelse(NULL, bp);
1202 return XFS_ERROR(error);
1206 /*========================================================================
1207 * External routines when attribute list size > XFS_LBSIZE(mp).
1208 *========================================================================*/
1211 * Add a name to a Btree-format attribute list.
1213 * This will involve walking down the Btree, and may involve splitting
1214 * leaf nodes and even splitting intermediate nodes up to and including
1215 * the root node (a special case of an intermediate node).
1217 * "Remote" attribute values confuse the issue and atomic rename operations
1218 * add a whole extra layer of confusion on top of that.
1221 xfs_attr_node_addname(xfs_da_args_t *args)
1223 xfs_da_state_t *state;
1224 xfs_da_state_blk_t *blk;
1227 int committed, retval, error;
1230 * Fill in bucket of arguments/results/context to carry around.
1235 state = xfs_da_state_alloc();
1238 state->blocksize = state->mp->m_sb.sb_blocksize;
1239 state->node_ents = state->mp->m_attr_node_ents;
1242 * Search to see if name already exists, and get back a pointer
1243 * to where it should go.
1245 error = xfs_da_node_lookup_int(state, &retval);
1248 blk = &state->path.blk[ state->path.active-1 ];
1249 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1250 if ((args->flags & ATTR_REPLACE) && (retval == ENOATTR)) {
1252 } else if (retval == EEXIST) {
1253 if (args->flags & ATTR_CREATE)
1255 args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */
1256 args->blkno2 = args->blkno; /* set 2nd entry info*/
1257 args->index2 = args->index;
1258 args->rmtblkno2 = args->rmtblkno;
1259 args->rmtblkcnt2 = args->rmtblkcnt;
1261 args->rmtblkcnt = 0;
1264 retval = xfs_attr_leaf_add(blk->bp, state->args);
1265 if (retval == ENOSPC) {
1266 if (state->path.active == 1) {
1268 * Its really a single leaf node, but it had
1269 * out-of-line values so it looked like it *might*
1270 * have been a b-tree.
1272 xfs_da_state_free(state);
1273 XFS_BMAP_INIT(args->flist, args->firstblock);
1274 error = xfs_attr_leaf_to_node(args);
1276 error = xfs_bmap_finish(&args->trans,
1283 xfs_bmap_cancel(args->flist);
1288 * bmap_finish() may have committed the last trans
1289 * and started a new one. We need the inode to be
1290 * in all transactions.
1293 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
1294 xfs_trans_ihold(args->trans, dp);
1298 * Commit the node conversion and start the next
1299 * trans in the chain.
1301 if ((error = xfs_attr_rolltrans(&args->trans, dp)))
1308 * Split as many Btree elements as required.
1309 * This code tracks the new and old attr's location
1310 * in the index/blkno/rmtblkno/rmtblkcnt fields and
1311 * in the index2/blkno2/rmtblkno2/rmtblkcnt2 fields.
1313 XFS_BMAP_INIT(args->flist, args->firstblock);
1314 error = xfs_da_split(state);
1316 error = xfs_bmap_finish(&args->trans, args->flist,
1322 xfs_bmap_cancel(args->flist);
1327 * bmap_finish() may have committed the last trans and started
1328 * a new one. We need the inode to be in all transactions.
1331 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
1332 xfs_trans_ihold(args->trans, dp);
1336 * Addition succeeded, update Btree hashvals.
1338 xfs_da_fixhashpath(state, &state->path);
1342 * Kill the state structure, we're done with it and need to
1343 * allow the buffers to come back later.
1345 xfs_da_state_free(state);
1349 * Commit the leaf addition or btree split and start the next
1350 * trans in the chain.
1352 if ((error = xfs_attr_rolltrans(&args->trans, dp)))
1356 * If there was an out-of-line value, allocate the blocks we
1357 * identified for its storage and copy the value. This is done
1358 * after we create the attribute so that we don't overflow the
1359 * maximum size of a transaction and/or hit a deadlock.
1361 if (args->rmtblkno > 0) {
1362 error = xfs_attr_rmtval_set(args);
1368 * If this is an atomic rename operation, we must "flip" the
1369 * incomplete flags on the "new" and "old" attribute/value pairs
1370 * so that one disappears and one appears atomically. Then we
1371 * must remove the "old" attribute/value pair.
1373 if (args->op_flags & XFS_DA_OP_RENAME) {
1375 * In a separate transaction, set the incomplete flag on the
1376 * "old" attr and clear the incomplete flag on the "new" attr.
1378 error = xfs_attr_leaf_flipflags(args);
1383 * Dismantle the "old" attribute/value pair by removing
1384 * a "remote" value (if it exists).
1386 args->index = args->index2;
1387 args->blkno = args->blkno2;
1388 args->rmtblkno = args->rmtblkno2;
1389 args->rmtblkcnt = args->rmtblkcnt2;
1390 if (args->rmtblkno) {
1391 error = xfs_attr_rmtval_remove(args);
1397 * Re-find the "old" attribute entry after any split ops.
1398 * The INCOMPLETE flag means that we will find the "old"
1399 * attr, not the "new" one.
1401 args->flags |= XFS_ATTR_INCOMPLETE;
1402 state = xfs_da_state_alloc();
1405 state->blocksize = state->mp->m_sb.sb_blocksize;
1406 state->node_ents = state->mp->m_attr_node_ents;
1408 error = xfs_da_node_lookup_int(state, &retval);
1413 * Remove the name and update the hashvals in the tree.
1415 blk = &state->path.blk[ state->path.active-1 ];
1416 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1417 error = xfs_attr_leaf_remove(blk->bp, args);
1418 xfs_da_fixhashpath(state, &state->path);
1421 * Check to see if the tree needs to be collapsed.
1423 if (retval && (state->path.active > 1)) {
1424 XFS_BMAP_INIT(args->flist, args->firstblock);
1425 error = xfs_da_join(state);
1427 error = xfs_bmap_finish(&args->trans,
1434 xfs_bmap_cancel(args->flist);
1439 * bmap_finish() may have committed the last trans
1440 * and started a new one. We need the inode to be
1441 * in all transactions.
1444 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
1445 xfs_trans_ihold(args->trans, dp);
1450 * Commit and start the next trans in the chain.
1452 if ((error = xfs_attr_rolltrans(&args->trans, dp)))
1455 } else if (args->rmtblkno > 0) {
1457 * Added a "remote" value, just clear the incomplete flag.
1459 error = xfs_attr_leaf_clearflag(args);
1467 xfs_da_state_free(state);
1474 * Remove a name from a B-tree attribute list.
1476 * This will involve walking down the Btree, and may involve joining
1477 * leaf nodes and even joining intermediate nodes up to and including
1478 * the root node (a special case of an intermediate node).
1481 xfs_attr_node_removename(xfs_da_args_t *args)
1483 xfs_da_state_t *state;
1484 xfs_da_state_blk_t *blk;
1487 int retval, error, committed, forkoff;
1490 * Tie a string around our finger to remind us where we are.
1493 state = xfs_da_state_alloc();
1495 state->mp = dp->i_mount;
1496 state->blocksize = state->mp->m_sb.sb_blocksize;
1497 state->node_ents = state->mp->m_attr_node_ents;
1500 * Search to see if name exists, and get back a pointer to it.
1502 error = xfs_da_node_lookup_int(state, &retval);
1503 if (error || (retval != EEXIST)) {
1510 * If there is an out-of-line value, de-allocate the blocks.
1511 * This is done before we remove the attribute so that we don't
1512 * overflow the maximum size of a transaction and/or hit a deadlock.
1514 blk = &state->path.blk[ state->path.active-1 ];
1515 ASSERT(blk->bp != NULL);
1516 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1517 if (args->rmtblkno > 0) {
1519 * Fill in disk block numbers in the state structure
1520 * so that we can get the buffers back after we commit
1521 * several transactions in the following calls.
1523 error = xfs_attr_fillstate(state);
1528 * Mark the attribute as INCOMPLETE, then bunmapi() the
1531 error = xfs_attr_leaf_setflag(args);
1534 error = xfs_attr_rmtval_remove(args);
1539 * Refill the state structure with buffers, the prior calls
1540 * released our buffers.
1542 error = xfs_attr_refillstate(state);
1548 * Remove the name and update the hashvals in the tree.
1550 blk = &state->path.blk[ state->path.active-1 ];
1551 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1552 retval = xfs_attr_leaf_remove(blk->bp, args);
1553 xfs_da_fixhashpath(state, &state->path);
1556 * Check to see if the tree needs to be collapsed.
1558 if (retval && (state->path.active > 1)) {
1559 XFS_BMAP_INIT(args->flist, args->firstblock);
1560 error = xfs_da_join(state);
1562 error = xfs_bmap_finish(&args->trans, args->flist,
1568 xfs_bmap_cancel(args->flist);
1573 * bmap_finish() may have committed the last trans and started
1574 * a new one. We need the inode to be in all transactions.
1577 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
1578 xfs_trans_ihold(args->trans, dp);
1582 * Commit the Btree join operation and start a new trans.
1584 if ((error = xfs_attr_rolltrans(&args->trans, dp)))
1589 * If the result is small enough, push it all into the inode.
1591 if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
1593 * Have to get rid of the copy of this dabuf in the state.
1595 ASSERT(state->path.active == 1);
1596 ASSERT(state->path.blk[0].bp);
1597 xfs_da_buf_done(state->path.blk[0].bp);
1598 state->path.blk[0].bp = NULL;
1600 error = xfs_da_read_buf(args->trans, args->dp, 0, -1, &bp,
1604 ASSERT(be16_to_cpu(((xfs_attr_leafblock_t *)
1605 bp->data)->hdr.info.magic)
1606 == XFS_ATTR_LEAF_MAGIC);
1608 if ((forkoff = xfs_attr_shortform_allfit(bp, dp))) {
1609 XFS_BMAP_INIT(args->flist, args->firstblock);
1610 error = xfs_attr_leaf_to_shortform(bp, args, forkoff);
1611 /* bp is gone due to xfs_da_shrink_inode */
1613 error = xfs_bmap_finish(&args->trans,
1620 xfs_bmap_cancel(args->flist);
1625 * bmap_finish() may have committed the last trans
1626 * and started a new one. We need the inode to be
1627 * in all transactions.
1630 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
1631 xfs_trans_ihold(args->trans, dp);
1634 xfs_da_brelse(args->trans, bp);
1639 xfs_da_state_free(state);
1644 * Fill in the disk block numbers in the state structure for the buffers
1645 * that are attached to the state structure.
1646 * This is done so that we can quickly reattach ourselves to those buffers
1647 * after some set of transaction commits have released these buffers.
1650 xfs_attr_fillstate(xfs_da_state_t *state)
1652 xfs_da_state_path_t *path;
1653 xfs_da_state_blk_t *blk;
1657 * Roll down the "path" in the state structure, storing the on-disk
1658 * block number for those buffers in the "path".
1660 path = &state->path;
1661 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1662 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1664 blk->disk_blkno = xfs_da_blkno(blk->bp);
1665 xfs_da_buf_done(blk->bp);
1668 blk->disk_blkno = 0;
1673 * Roll down the "altpath" in the state structure, storing the on-disk
1674 * block number for those buffers in the "altpath".
1676 path = &state->altpath;
1677 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1678 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1680 blk->disk_blkno = xfs_da_blkno(blk->bp);
1681 xfs_da_buf_done(blk->bp);
1684 blk->disk_blkno = 0;
1692 * Reattach the buffers to the state structure based on the disk block
1693 * numbers stored in the state structure.
1694 * This is done after some set of transaction commits have released those
1695 * buffers from our grip.
1698 xfs_attr_refillstate(xfs_da_state_t *state)
1700 xfs_da_state_path_t *path;
1701 xfs_da_state_blk_t *blk;
1705 * Roll down the "path" in the state structure, storing the on-disk
1706 * block number for those buffers in the "path".
1708 path = &state->path;
1709 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1710 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1711 if (blk->disk_blkno) {
1712 error = xfs_da_read_buf(state->args->trans,
1714 blk->blkno, blk->disk_blkno,
1715 &blk->bp, XFS_ATTR_FORK);
1724 * Roll down the "altpath" in the state structure, storing the on-disk
1725 * block number for those buffers in the "altpath".
1727 path = &state->altpath;
1728 ASSERT((path->active >= 0) && (path->active < XFS_DA_NODE_MAXDEPTH));
1729 for (blk = path->blk, level = 0; level < path->active; blk++, level++) {
1730 if (blk->disk_blkno) {
1731 error = xfs_da_read_buf(state->args->trans,
1733 blk->blkno, blk->disk_blkno,
1734 &blk->bp, XFS_ATTR_FORK);
1746 * Look up a filename in a node attribute list.
1748 * This routine gets called for any attribute fork that has more than one
1749 * block, ie: both true Btree attr lists and for single-leaf-blocks with
1750 * "remote" values taking up more blocks.
1753 xfs_attr_node_get(xfs_da_args_t *args)
1755 xfs_da_state_t *state;
1756 xfs_da_state_blk_t *blk;
1760 state = xfs_da_state_alloc();
1762 state->mp = args->dp->i_mount;
1763 state->blocksize = state->mp->m_sb.sb_blocksize;
1764 state->node_ents = state->mp->m_attr_node_ents;
1767 * Search to see if name exists, and get back a pointer to it.
1769 error = xfs_da_node_lookup_int(state, &retval);
1772 } else if (retval == EEXIST) {
1773 blk = &state->path.blk[ state->path.active-1 ];
1774 ASSERT(blk->bp != NULL);
1775 ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
1778 * Get the value, local or "remote"
1780 retval = xfs_attr_leaf_getvalue(blk->bp, args);
1781 if (!retval && (args->rmtblkno > 0)
1782 && !(args->flags & ATTR_KERNOVAL)) {
1783 retval = xfs_attr_rmtval_get(args);
1788 * If not in a transaction, we have to release all the buffers.
1790 for (i = 0; i < state->path.active; i++) {
1791 xfs_da_brelse(args->trans, state->path.blk[i].bp);
1792 state->path.blk[i].bp = NULL;
1795 xfs_da_state_free(state);
1799 STATIC int /* error */
1800 xfs_attr_node_list(xfs_attr_list_context_t *context)
1802 attrlist_cursor_kern_t *cursor;
1803 xfs_attr_leafblock_t *leaf;
1804 xfs_da_intnode_t *node;
1805 xfs_da_node_entry_t *btree;
1809 cursor = context->cursor;
1810 cursor->initted = 1;
1813 * Do all sorts of validation on the passed-in cursor structure.
1814 * If anything is amiss, ignore the cursor and look up the hashval
1815 * starting from the btree root.
1818 if (cursor->blkno > 0) {
1819 error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1,
1820 &bp, XFS_ATTR_FORK);
1821 if ((error != 0) && (error != EFSCORRUPTED))
1825 switch (be16_to_cpu(node->hdr.info.magic)) {
1826 case XFS_DA_NODE_MAGIC:
1827 xfs_attr_trace_l_cn("wrong blk", context, node);
1828 xfs_da_brelse(NULL, bp);
1831 case XFS_ATTR_LEAF_MAGIC:
1833 if (cursor->hashval > be32_to_cpu(leaf->entries[
1834 be16_to_cpu(leaf->hdr.count)-1].hashval)) {
1835 xfs_attr_trace_l_cl("wrong blk",
1837 xfs_da_brelse(NULL, bp);
1839 } else if (cursor->hashval <=
1840 be32_to_cpu(leaf->entries[0].hashval)) {
1841 xfs_attr_trace_l_cl("maybe wrong blk",
1843 xfs_da_brelse(NULL, bp);
1848 xfs_attr_trace_l_c("wrong blk - ??", context);
1849 xfs_da_brelse(NULL, bp);
1856 * We did not find what we expected given the cursor's contents,
1857 * so we start from the top and work down based on the hash value.
1858 * Note that start of node block is same as start of leaf block.
1863 error = xfs_da_read_buf(NULL, context->dp,
1864 cursor->blkno, -1, &bp,
1868 if (unlikely(bp == NULL)) {
1869 XFS_ERROR_REPORT("xfs_attr_node_list(2)",
1871 context->dp->i_mount);
1872 return(XFS_ERROR(EFSCORRUPTED));
1875 if (be16_to_cpu(node->hdr.info.magic)
1876 == XFS_ATTR_LEAF_MAGIC)
1878 if (unlikely(be16_to_cpu(node->hdr.info.magic)
1879 != XFS_DA_NODE_MAGIC)) {
1880 XFS_CORRUPTION_ERROR("xfs_attr_node_list(3)",
1882 context->dp->i_mount,
1884 xfs_da_brelse(NULL, bp);
1885 return(XFS_ERROR(EFSCORRUPTED));
1887 btree = node->btree;
1888 for (i = 0; i < be16_to_cpu(node->hdr.count);
1891 <= be32_to_cpu(btree->hashval)) {
1892 cursor->blkno = be32_to_cpu(btree->before);
1893 xfs_attr_trace_l_cb("descending",
1898 if (i == be16_to_cpu(node->hdr.count)) {
1899 xfs_da_brelse(NULL, bp);
1902 xfs_da_brelse(NULL, bp);
1908 * Roll upward through the blocks, processing each leaf block in
1909 * order. As long as there is space in the result buffer, keep
1910 * adding the information.
1914 if (unlikely(be16_to_cpu(leaf->hdr.info.magic)
1915 != XFS_ATTR_LEAF_MAGIC)) {
1916 XFS_CORRUPTION_ERROR("xfs_attr_node_list(4)",
1918 context->dp->i_mount, leaf);
1919 xfs_da_brelse(NULL, bp);
1920 return(XFS_ERROR(EFSCORRUPTED));
1922 error = xfs_attr_leaf_list_int(bp, context);
1924 xfs_da_brelse(NULL, bp);
1927 if (context->seen_enough || leaf->hdr.info.forw == 0)
1929 cursor->blkno = be32_to_cpu(leaf->hdr.info.forw);
1930 xfs_da_brelse(NULL, bp);
1931 error = xfs_da_read_buf(NULL, context->dp, cursor->blkno, -1,
1932 &bp, XFS_ATTR_FORK);
1935 if (unlikely((bp == NULL))) {
1936 XFS_ERROR_REPORT("xfs_attr_node_list(5)",
1938 context->dp->i_mount);
1939 return(XFS_ERROR(EFSCORRUPTED));
1942 xfs_da_brelse(NULL, bp);
1947 /*========================================================================
1948 * External routines for manipulating out-of-line attribute values.
1949 *========================================================================*/
1952 * Read the value associated with an attribute from the out-of-line buffer
1953 * that we stored it in.
1956 xfs_attr_rmtval_get(xfs_da_args_t *args)
1958 xfs_bmbt_irec_t map[ATTR_RMTVALUE_MAPSIZE];
1963 int nmap, error, tmp, valuelen, blkcnt, i;
1966 ASSERT(!(args->flags & ATTR_KERNOVAL));
1968 mp = args->dp->i_mount;
1970 valuelen = args->valuelen;
1971 lblkno = args->rmtblkno;
1972 while (valuelen > 0) {
1973 nmap = ATTR_RMTVALUE_MAPSIZE;
1974 error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,
1976 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
1977 NULL, 0, map, &nmap, NULL, NULL);
1982 for (i = 0; (i < nmap) && (valuelen > 0); i++) {
1983 ASSERT((map[i].br_startblock != DELAYSTARTBLOCK) &&
1984 (map[i].br_startblock != HOLESTARTBLOCK));
1985 dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock);
1986 blkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
1987 error = xfs_read_buf(mp, mp->m_ddev_targp, dblkno,
1988 blkcnt, XFS_BUF_LOCK, &bp);
1992 tmp = (valuelen < XFS_BUF_SIZE(bp))
1993 ? valuelen : XFS_BUF_SIZE(bp);
1994 xfs_biomove(bp, 0, tmp, dst, XFS_B_READ);
1999 lblkno += map[i].br_blockcount;
2002 ASSERT(valuelen == 0);
2007 * Write the value associated with an attribute into the out-of-line buffer
2008 * that we have defined for it.
2011 xfs_attr_rmtval_set(xfs_da_args_t *args)
2014 xfs_fileoff_t lfileoff;
2016 xfs_bmbt_irec_t map;
2021 int blkcnt, valuelen, nmap, error, tmp, committed;
2028 * Find a "hole" in the attribute address space large enough for
2029 * us to drop the new attribute's value into.
2031 blkcnt = XFS_B_TO_FSB(mp, args->valuelen);
2033 error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff,
2038 args->rmtblkno = lblkno = (xfs_dablk_t)lfileoff;
2039 args->rmtblkcnt = blkcnt;
2042 * Roll through the "value", allocating blocks on disk as required.
2044 while (blkcnt > 0) {
2046 * Allocate a single extent, up to the size of the value.
2048 XFS_BMAP_INIT(args->flist, args->firstblock);
2050 error = xfs_bmapi(args->trans, dp, (xfs_fileoff_t)lblkno,
2052 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |
2054 args->firstblock, args->total, &map, &nmap,
2057 error = xfs_bmap_finish(&args->trans, args->flist,
2063 xfs_bmap_cancel(args->flist);
2068 * bmap_finish() may have committed the last trans and started
2069 * a new one. We need the inode to be in all transactions.
2072 xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
2073 xfs_trans_ihold(args->trans, dp);
2077 ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
2078 (map.br_startblock != HOLESTARTBLOCK));
2079 lblkno += map.br_blockcount;
2080 blkcnt -= map.br_blockcount;
2083 * Start the next trans in the chain.
2085 if ((error = xfs_attr_rolltrans(&args->trans, dp)))
2090 * Roll through the "value", copying the attribute value to the
2091 * already-allocated blocks. Blocks are written synchronously
2092 * so that we can know they are all on disk before we turn off
2093 * the INCOMPLETE flag.
2095 lblkno = args->rmtblkno;
2096 valuelen = args->valuelen;
2097 while (valuelen > 0) {
2099 * Try to remember where we decided to put the value.
2101 XFS_BMAP_INIT(args->flist, args->firstblock);
2103 error = xfs_bmapi(NULL, dp, (xfs_fileoff_t)lblkno,
2105 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2106 args->firstblock, 0, &map, &nmap,
2112 ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
2113 (map.br_startblock != HOLESTARTBLOCK));
2115 dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
2116 blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
2118 bp = xfs_buf_get_flags(mp->m_ddev_targp, dblkno,
2119 blkcnt, XFS_BUF_LOCK);
2121 ASSERT(!XFS_BUF_GETERROR(bp));
2123 tmp = (valuelen < XFS_BUF_SIZE(bp)) ? valuelen :
2125 xfs_biomove(bp, 0, tmp, src, XFS_B_WRITE);
2126 if (tmp < XFS_BUF_SIZE(bp))
2127 xfs_biozero(bp, tmp, XFS_BUF_SIZE(bp) - tmp);
2128 if ((error = xfs_bwrite(mp, bp))) {/* GROT: NOTE: synchronous write */
2134 lblkno += map.br_blockcount;
2136 ASSERT(valuelen == 0);
2141 * Remove the value associated with an attribute by deleting the
2142 * out-of-line buffer that it is stored on.
2145 xfs_attr_rmtval_remove(xfs_da_args_t *args)
2148 xfs_bmbt_irec_t map;
2152 int valuelen, blkcnt, nmap, error, done, committed;
2154 mp = args->dp->i_mount;
2157 * Roll through the "value", invalidating the attribute value's
2160 lblkno = args->rmtblkno;
2161 valuelen = args->rmtblkcnt;
2162 while (valuelen > 0) {
2164 * Try to remember where we decided to put the value.
2166 XFS_BMAP_INIT(args->flist, args->firstblock);
2168 error = xfs_bmapi(NULL, args->dp, (xfs_fileoff_t)lblkno,
2170 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2171 args->firstblock, 0, &map, &nmap,
2177 ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
2178 (map.br_startblock != HOLESTARTBLOCK));
2180 dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
2181 blkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
2184 * If the "remote" value is in the cache, remove it.
2186 bp = xfs_incore(mp->m_ddev_targp, dblkno, blkcnt,
2187 XFS_INCORE_TRYLOCK);
2190 XFS_BUF_UNDELAYWRITE(bp);
2195 valuelen -= map.br_blockcount;
2197 lblkno += map.br_blockcount;
2201 * Keep de-allocating extents until the remote-value region is gone.
2203 lblkno = args->rmtblkno;
2204 blkcnt = args->rmtblkcnt;
2207 XFS_BMAP_INIT(args->flist, args->firstblock);
2208 error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
2209 XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
2210 1, args->firstblock, args->flist,
2213 error = xfs_bmap_finish(&args->trans, args->flist,
2219 xfs_bmap_cancel(args->flist);
2224 * bmap_finish() may have committed the last trans and started
2225 * a new one. We need the inode to be in all transactions.
2228 xfs_trans_ijoin(args->trans, args->dp, XFS_ILOCK_EXCL);
2229 xfs_trans_ihold(args->trans, args->dp);
2233 * Close out trans and start the next one in the chain.
2235 if ((error = xfs_attr_rolltrans(&args->trans, args->dp)))
2241 #if defined(XFS_ATTR_TRACE)
2243 * Add a trace buffer entry for an attr_list context structure.
2246 xfs_attr_trace_l_c(char *where, struct xfs_attr_list_context *context)
2248 xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_C, where, context,
2249 (__psunsigned_t)NULL,
2250 (__psunsigned_t)NULL,
2251 (__psunsigned_t)NULL);
2255 * Add a trace buffer entry for a context structure and a Btree node.
2258 xfs_attr_trace_l_cn(char *where, struct xfs_attr_list_context *context,
2259 struct xfs_da_intnode *node)
2261 xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CN, where, context,
2262 (__psunsigned_t)be16_to_cpu(node->hdr.count),
2263 (__psunsigned_t)be32_to_cpu(node->btree[0].hashval),
2264 (__psunsigned_t)be32_to_cpu(node->btree[
2265 be16_to_cpu(node->hdr.count)-1].hashval));
2269 * Add a trace buffer entry for a context structure and a Btree element.
2272 xfs_attr_trace_l_cb(char *where, struct xfs_attr_list_context *context,
2273 struct xfs_da_node_entry *btree)
2275 xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CB, where, context,
2276 (__psunsigned_t)be32_to_cpu(btree->hashval),
2277 (__psunsigned_t)be32_to_cpu(btree->before),
2278 (__psunsigned_t)NULL);
2282 * Add a trace buffer entry for a context structure and a leaf block.
2285 xfs_attr_trace_l_cl(char *where, struct xfs_attr_list_context *context,
2286 struct xfs_attr_leafblock *leaf)
2288 xfs_attr_trace_enter(XFS_ATTR_KTRACE_L_CL, where, context,
2289 (__psunsigned_t)be16_to_cpu(leaf->hdr.count),
2290 (__psunsigned_t)be32_to_cpu(leaf->entries[0].hashval),
2291 (__psunsigned_t)be32_to_cpu(leaf->entries[
2292 be16_to_cpu(leaf->hdr.count)-1].hashval));
2296 * Add a trace buffer entry for the arguments given to the routine,
2300 xfs_attr_trace_enter(int type, char *where,
2301 struct xfs_attr_list_context *context,
2302 __psunsigned_t a13, __psunsigned_t a14,
2305 ASSERT(xfs_attr_trace_buf);
2306 ktrace_enter(xfs_attr_trace_buf, (void *)((__psunsigned_t)type),
2307 (void *)((__psunsigned_t)where),
2308 (void *)((__psunsigned_t)context->dp),
2309 (void *)((__psunsigned_t)context->cursor->hashval),
2310 (void *)((__psunsigned_t)context->cursor->blkno),
2311 (void *)((__psunsigned_t)context->cursor->offset),
2312 (void *)((__psunsigned_t)context->alist),
2313 (void *)((__psunsigned_t)context->bufsize),
2314 (void *)((__psunsigned_t)context->count),
2315 (void *)((__psunsigned_t)context->firstu),
2317 (void *)((__psunsigned_t)context->dupcnt),
2318 (void *)((__psunsigned_t)context->flags),
2319 (void *)a13, (void *)a14, (void *)a15);
2321 #endif /* XFS_ATTR_TRACE */