@@ -51,7 +51,6 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
51
51
STATIC int xfs_attr_leaf_get (xfs_da_args_t * args );
52
52
STATIC int xfs_attr_leaf_removename (xfs_da_args_t * args );
53
53
STATIC int xfs_attr_leaf_hasname (struct xfs_da_args * args , struct xfs_buf * * bp );
54
- STATIC int xfs_attr_leaf_try_add (struct xfs_da_args * args );
55
54
56
55
/*
57
56
* Internal routines when attribute list is more than one block.
@@ -437,6 +436,33 @@ xfs_attr_hashval(
437
436
return xfs_attr_hashname (name , namelen );
438
437
}
439
438
439
+ /* Save the current remote block info and clear the current pointers. */
440
+ static void
441
+ xfs_attr_save_rmt_blk (
442
+ struct xfs_da_args * args )
443
+ {
444
+ args -> blkno2 = args -> blkno ;
445
+ args -> index2 = args -> index ;
446
+ args -> rmtblkno2 = args -> rmtblkno ;
447
+ args -> rmtblkcnt2 = args -> rmtblkcnt ;
448
+ args -> rmtvaluelen2 = args -> rmtvaluelen ;
449
+ args -> rmtblkno = 0 ;
450
+ args -> rmtblkcnt = 0 ;
451
+ args -> rmtvaluelen = 0 ;
452
+ }
453
+
454
+ /* Set stored info about a remote block */
455
+ static void
456
+ xfs_attr_restore_rmt_blk (
457
+ struct xfs_da_args * args )
458
+ {
459
+ args -> blkno = args -> blkno2 ;
460
+ args -> index = args -> index2 ;
461
+ args -> rmtblkno = args -> rmtblkno2 ;
462
+ args -> rmtblkcnt = args -> rmtblkcnt2 ;
463
+ args -> rmtvaluelen = args -> rmtvaluelen2 ;
464
+ }
465
+
440
466
/*
441
467
* PPTR_REPLACE operations require the caller to set the old and new names and
442
468
* values explicitly. Update the canonical fields to the new name and value
@@ -482,49 +508,77 @@ xfs_attr_complete_op(
482
508
return replace_state ;
483
509
}
484
510
511
+ /*
512
+ * Try to add an attribute to an inode in leaf form.
513
+ */
485
514
static int
486
515
xfs_attr_leaf_addname (
487
516
struct xfs_attr_intent * attr )
488
517
{
489
518
struct xfs_da_args * args = attr -> xattri_da_args ;
519
+ struct xfs_buf * bp ;
490
520
int error ;
491
521
492
522
ASSERT (xfs_attr_is_leaf (args -> dp ));
493
523
524
+ error = xfs_attr3_leaf_read (args -> trans , args -> dp , args -> owner , 0 , & bp );
525
+ if (error )
526
+ return error ;
527
+
494
528
/*
495
- * Use the leaf buffer we may already hold locked as a result of
496
- * a sf-to-leaf conversion.
529
+ * Look up the xattr name to set the insertion point for the new xattr.
497
530
*/
498
- error = xfs_attr_leaf_try_add (args );
499
-
500
- if (error == - ENOSPC ) {
501
- error = xfs_attr3_leaf_to_node (args );
502
- if (error )
503
- return error ;
531
+ error = xfs_attr3_leaf_lookup_int (bp , args );
532
+ switch (error ) {
533
+ case - ENOATTR :
534
+ if (args -> op_flags & XFS_DA_OP_REPLACE )
535
+ goto out_brelse ;
536
+ break ;
537
+ case - EEXIST :
538
+ if (!(args -> op_flags & XFS_DA_OP_REPLACE ))
539
+ goto out_brelse ;
504
540
541
+ trace_xfs_attr_leaf_replace (args );
505
542
/*
506
- * We're not in leaf format anymore, so roll the transaction and
507
- * retry the add to the newly allocated node block.
543
+ * Save the existing remote attr state so that the current
544
+ * values reflect the state of the new attribute we are about to
545
+ * add, not the attribute we just found and will remove later.
508
546
*/
509
- attr -> xattri_dela_state = XFS_DAS_NODE_ADD ;
510
- goto out ;
547
+ xfs_attr_save_rmt_blk (args );
548
+ break ;
549
+ case 0 :
550
+ break ;
551
+ default :
552
+ goto out_brelse ;
511
553
}
512
- if (error )
513
- return error ;
514
554
515
555
/*
516
556
* We need to commit and roll if we need to allocate remote xattr blocks
517
557
* or perform more xattr manipulations. Otherwise there is nothing more
518
558
* to do and we can return success.
519
559
*/
520
- if (args -> rmtblkno )
560
+ error = xfs_attr3_leaf_add (bp , args );
561
+ if (error ) {
562
+ if (error != - ENOSPC )
563
+ return error ;
564
+ error = xfs_attr3_leaf_to_node (args );
565
+ if (error )
566
+ return error ;
567
+
568
+ attr -> xattri_dela_state = XFS_DAS_NODE_ADD ;
569
+ } else if (args -> rmtblkno ) {
521
570
attr -> xattri_dela_state = XFS_DAS_LEAF_SET_RMT ;
522
- else
523
- attr -> xattri_dela_state = xfs_attr_complete_op (attr ,
524
- XFS_DAS_LEAF_REPLACE );
525
- out :
571
+ } else {
572
+ attr -> xattri_dela_state =
573
+ xfs_attr_complete_op (attr , XFS_DAS_LEAF_REPLACE );
574
+ }
575
+
526
576
trace_xfs_attr_leaf_addname_return (attr -> xattri_dela_state , args -> dp );
527
577
return error ;
578
+
579
+ out_brelse :
580
+ xfs_trans_brelse (args -> trans , bp );
581
+ return error ;
528
582
}
529
583
530
584
/*
@@ -1170,88 +1224,6 @@ xfs_attr_shortform_addname(
1170
1224
* External routines when attribute list is one block
1171
1225
*========================================================================*/
1172
1226
1173
- /* Save the current remote block info and clear the current pointers. */
1174
- static void
1175
- xfs_attr_save_rmt_blk (
1176
- struct xfs_da_args * args )
1177
- {
1178
- args -> blkno2 = args -> blkno ;
1179
- args -> index2 = args -> index ;
1180
- args -> rmtblkno2 = args -> rmtblkno ;
1181
- args -> rmtblkcnt2 = args -> rmtblkcnt ;
1182
- args -> rmtvaluelen2 = args -> rmtvaluelen ;
1183
- args -> rmtblkno = 0 ;
1184
- args -> rmtblkcnt = 0 ;
1185
- args -> rmtvaluelen = 0 ;
1186
- }
1187
-
1188
- /* Set stored info about a remote block */
1189
- static void
1190
- xfs_attr_restore_rmt_blk (
1191
- struct xfs_da_args * args )
1192
- {
1193
- args -> blkno = args -> blkno2 ;
1194
- args -> index = args -> index2 ;
1195
- args -> rmtblkno = args -> rmtblkno2 ;
1196
- args -> rmtblkcnt = args -> rmtblkcnt2 ;
1197
- args -> rmtvaluelen = args -> rmtvaluelen2 ;
1198
- }
1199
-
1200
- /*
1201
- * Tries to add an attribute to an inode in leaf form
1202
- *
1203
- * This function is meant to execute as part of a delayed operation and leaves
1204
- * the transaction handling to the caller. On success the attribute is added
1205
- * and the inode and transaction are left dirty. If there is not enough space,
1206
- * the attr data is converted to node format and -ENOSPC is returned. Caller is
1207
- * responsible for handling the dirty inode and transaction or adding the attr
1208
- * in node format.
1209
- */
1210
- STATIC int
1211
- xfs_attr_leaf_try_add (
1212
- struct xfs_da_args * args )
1213
- {
1214
- struct xfs_buf * bp ;
1215
- int error ;
1216
-
1217
- error = xfs_attr3_leaf_read (args -> trans , args -> dp , args -> owner , 0 , & bp );
1218
- if (error )
1219
- return error ;
1220
-
1221
- /*
1222
- * Look up the xattr name to set the insertion point for the new xattr.
1223
- */
1224
- error = xfs_attr3_leaf_lookup_int (bp , args );
1225
- switch (error ) {
1226
- case - ENOATTR :
1227
- if (args -> op_flags & XFS_DA_OP_REPLACE )
1228
- goto out_brelse ;
1229
- break ;
1230
- case - EEXIST :
1231
- if (!(args -> op_flags & XFS_DA_OP_REPLACE ))
1232
- goto out_brelse ;
1233
-
1234
- trace_xfs_attr_leaf_replace (args );
1235
- /*
1236
- * Save the existing remote attr state so that the current
1237
- * values reflect the state of the new attribute we are about to
1238
- * add, not the attribute we just found and will remove later.
1239
- */
1240
- xfs_attr_save_rmt_blk (args );
1241
- break ;
1242
- case 0 :
1243
- break ;
1244
- default :
1245
- goto out_brelse ;
1246
- }
1247
-
1248
- return xfs_attr3_leaf_add (bp , args );
1249
-
1250
- out_brelse :
1251
- xfs_trans_brelse (args -> trans , bp );
1252
- return error ;
1253
- }
1254
-
1255
1227
/*
1256
1228
* Return EEXIST if attr is found, or ENOATTR if not
1257
1229
*/
0 commit comments