@@ -60,7 +60,7 @@ STATIC int xfs_attr_node_get(xfs_da_args_t *args);
6060STATIC void xfs_attr_restore_rmt_blk (struct xfs_da_args * args );
6161static int xfs_attr_node_try_addname (struct xfs_attr_item * attr );
6262STATIC int xfs_attr_node_addname_find_attr (struct xfs_attr_item * attr );
63- STATIC int xfs_attr_node_addname_clear_incomplete (struct xfs_attr_item * attr );
63+ STATIC int xfs_attr_node_remove_attr (struct xfs_attr_item * attr );
6464STATIC int xfs_attr_node_hasname (xfs_da_args_t * args ,
6565 struct xfs_da_state * * state );
6666STATIC int xfs_attr_fillstate (xfs_da_state_t * state );
@@ -443,6 +443,77 @@ xfs_attr_rmtval_alloc(
443443 return error ;
444444}
445445
446+ /*
447+ * Remove the original attr we have just replaced. This is dependent on the
448+ * original lookup and insert placing the old attr in args->blkno/args->index
449+ * and the new attr in args->blkno2/args->index2.
450+ */
451+ static int
452+ xfs_attr_leaf_remove_attr (
453+ struct xfs_attr_item * attr )
454+ {
455+ struct xfs_da_args * args = attr -> xattri_da_args ;
456+ struct xfs_inode * dp = args -> dp ;
457+ struct xfs_buf * bp = NULL ;
458+ int forkoff ;
459+ int error ;
460+
461+ error = xfs_attr3_leaf_read (args -> trans , args -> dp , args -> blkno ,
462+ & bp );
463+ if (error )
464+ return error ;
465+
466+ xfs_attr3_leaf_remove (bp , args );
467+
468+ forkoff = xfs_attr_shortform_allfit (bp , dp );
469+ if (forkoff )
470+ error = xfs_attr3_leaf_to_shortform (bp , args , forkoff );
471+ /* bp is gone due to xfs_da_shrink_inode */
472+
473+ return error ;
474+ }
475+
476+ /*
477+ * Shrink an attribute from leaf to shortform. Used by the node format remove
478+ * path when the node format collapses to a single block and so we have to check
479+ * if it can be collapsed further.
480+ */
481+ static int
482+ xfs_attr_leaf_shrink (
483+ struct xfs_da_args * args ,
484+ struct xfs_da_state * state )
485+ {
486+ struct xfs_inode * dp = args -> dp ;
487+ int error , forkoff ;
488+ struct xfs_buf * bp ;
489+
490+ if (!xfs_attr_is_leaf (dp ))
491+ return 0 ;
492+
493+ /*
494+ * Have to get rid of the copy of this dabuf in the state.
495+ */
496+ if (state ) {
497+ ASSERT (state -> path .active == 1 );
498+ ASSERT (state -> path .blk [0 ].bp );
499+ state -> path .blk [0 ].bp = NULL ;
500+ }
501+
502+ error = xfs_attr3_leaf_read (args -> trans , args -> dp , 0 , & bp );
503+ if (error )
504+ return error ;
505+
506+ forkoff = xfs_attr_shortform_allfit (bp , dp );
507+ if (forkoff ) {
508+ error = xfs_attr3_leaf_to_shortform (bp , args , forkoff );
509+ /* bp is gone due to xfs_da_shrink_inode */
510+ } else {
511+ xfs_trans_brelse (args -> trans , bp );
512+ }
513+
514+ return error ;
515+ }
516+
446517/*
447518 * Set the attribute specified in @args.
448519 * This routine is meant to function as a delayed operation, and may return
@@ -455,9 +526,7 @@ xfs_attr_set_iter(
455526 struct xfs_attr_item * attr )
456527{
457528 struct xfs_da_args * args = attr -> xattri_da_args ;
458- struct xfs_inode * dp = args -> dp ;
459- struct xfs_buf * bp = NULL ;
460- int forkoff , error = 0 ;
529+ int error = 0 ;
461530
462531 /* State machine switch */
463532next_state :
@@ -548,32 +617,16 @@ xfs_attr_set_iter(
548617 attr -> xattri_dela_state ++ ;
549618 break ;
550619
551- case XFS_DAS_RD_LEAF :
552- /*
553- * This is the last step for leaf format. Read the block with
554- * the old attr, remove the old attr, check for shortform
555- * conversion and return.
556- */
557- error = xfs_attr3_leaf_read (args -> trans , args -> dp , args -> blkno ,
558- & bp );
559- if (error )
560- return error ;
561-
562- xfs_attr3_leaf_remove (bp , args );
563-
564- forkoff = xfs_attr_shortform_allfit (bp , dp );
565- if (forkoff )
566- error = xfs_attr3_leaf_to_shortform (bp , args , forkoff );
567- /* bp is gone due to xfs_da_shrink_inode */
568-
569- return error ;
620+ case XFS_DAS_LEAF_REMOVE_ATTR :
621+ error = xfs_attr_leaf_remove_attr (attr );
622+ attr -> xattri_dela_state = XFS_DAS_DONE ;
623+ break ;
570624
571- case XFS_DAS_CLR_FLAG :
572- /*
573- * The last state for node format. Look up the old attr and
574- * remove it.
575- */
576- error = xfs_attr_node_addname_clear_incomplete (attr );
625+ case XFS_DAS_NODE_REMOVE_ATTR :
626+ error = xfs_attr_node_remove_attr (attr );
627+ if (!error )
628+ error = xfs_attr_leaf_shrink (args , NULL );
629+ attr -> xattri_dela_state = XFS_DAS_DONE ;
577630 break ;
578631 default :
579632 ASSERT (0 );
@@ -1268,8 +1321,8 @@ xfs_attr_node_try_addname(
12681321}
12691322
12701323
1271- STATIC int
1272- xfs_attr_node_addname_clear_incomplete (
1324+ static int
1325+ xfs_attr_node_remove_attr (
12731326 struct xfs_attr_item * attr )
12741327{
12751328 struct xfs_da_args * args = attr -> xattri_da_args ;
@@ -1310,38 +1363,6 @@ xfs_attr_node_addname_clear_incomplete(
13101363 return retval ;
13111364}
13121365
1313- /*
1314- * Shrink an attribute from leaf to shortform
1315- */
1316- STATIC int
1317- xfs_attr_node_shrink (
1318- struct xfs_da_args * args ,
1319- struct xfs_da_state * state )
1320- {
1321- struct xfs_inode * dp = args -> dp ;
1322- int error , forkoff ;
1323- struct xfs_buf * bp ;
1324-
1325- /*
1326- * Have to get rid of the copy of this dabuf in the state.
1327- */
1328- ASSERT (state -> path .active == 1 );
1329- ASSERT (state -> path .blk [0 ].bp );
1330- state -> path .blk [0 ].bp = NULL ;
1331-
1332- error = xfs_attr3_leaf_read (args -> trans , args -> dp , 0 , & bp );
1333- if (error )
1334- return error ;
1335-
1336- forkoff = xfs_attr_shortform_allfit (bp , dp );
1337- if (forkoff ) {
1338- error = xfs_attr3_leaf_to_shortform (bp , args , forkoff );
1339- /* bp is gone due to xfs_da_shrink_inode */
1340- } else
1341- xfs_trans_brelse (args -> trans , bp );
1342-
1343- return error ;
1344- }
13451366
13461367/*
13471368 * Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
@@ -1550,7 +1571,7 @@ xfs_attr_remove_iter(
15501571 * transaction.
15511572 */
15521573 if (xfs_attr_is_leaf (dp ))
1553- error = xfs_attr_node_shrink (args , state );
1574+ error = xfs_attr_leaf_shrink (args , state );
15541575 ASSERT (error != - EAGAIN );
15551576 break ;
15561577 default :
0 commit comments