@@ -60,7 +60,7 @@ STATIC int xfs_attr_node_get(xfs_da_args_t *args);
60
60
STATIC void xfs_attr_restore_rmt_blk (struct xfs_da_args * args );
61
61
static int xfs_attr_node_try_addname (struct xfs_attr_item * attr );
62
62
STATIC 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 );
64
64
STATIC int xfs_attr_node_hasname (xfs_da_args_t * args ,
65
65
struct xfs_da_state * * state );
66
66
STATIC int xfs_attr_fillstate (xfs_da_state_t * state );
@@ -443,6 +443,77 @@ xfs_attr_rmtval_alloc(
443
443
return error ;
444
444
}
445
445
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
+
446
517
/*
447
518
* Set the attribute specified in @args.
448
519
* This routine is meant to function as a delayed operation, and may return
@@ -455,9 +526,7 @@ xfs_attr_set_iter(
455
526
struct xfs_attr_item * attr )
456
527
{
457
528
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 ;
461
530
462
531
/* State machine switch */
463
532
next_state :
@@ -548,32 +617,16 @@ xfs_attr_set_iter(
548
617
attr -> xattri_dela_state ++ ;
549
618
break ;
550
619
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 ;
570
624
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 ;
577
630
break ;
578
631
default :
579
632
ASSERT (0 );
@@ -1268,8 +1321,8 @@ xfs_attr_node_try_addname(
1268
1321
}
1269
1322
1270
1323
1271
- STATIC int
1272
- xfs_attr_node_addname_clear_incomplete (
1324
+ static int
1325
+ xfs_attr_node_remove_attr (
1273
1326
struct xfs_attr_item * attr )
1274
1327
{
1275
1328
struct xfs_da_args * args = attr -> xattri_da_args ;
@@ -1310,38 +1363,6 @@ xfs_attr_node_addname_clear_incomplete(
1310
1363
return retval ;
1311
1364
}
1312
1365
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
- }
1345
1366
1346
1367
/*
1347
1368
* Mark an attribute entry INCOMPLETE and save pointers to the relevant buffers
@@ -1550,7 +1571,7 @@ xfs_attr_remove_iter(
1550
1571
* transaction.
1551
1572
*/
1552
1573
if (xfs_attr_is_leaf (dp ))
1553
- error = xfs_attr_node_shrink (args , state );
1574
+ error = xfs_attr_leaf_shrink (args , state );
1554
1575
ASSERT (error != - EAGAIN );
1555
1576
break ;
1556
1577
default :
0 commit comments