@@ -51,7 +51,6 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args);
5151STATIC int xfs_attr_leaf_get (xfs_da_args_t * args );
5252STATIC int xfs_attr_leaf_removename (xfs_da_args_t * args );
5353STATIC 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 );
5554
5655/*
5756 * Internal routines when attribute list is more than one block.
@@ -437,6 +436,33 @@ xfs_attr_hashval(
437436 return xfs_attr_hashname (name , namelen );
438437}
439438
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+
440466/*
441467 * PPTR_REPLACE operations require the caller to set the old and new names and
442468 * values explicitly. Update the canonical fields to the new name and value
@@ -482,49 +508,77 @@ xfs_attr_complete_op(
482508 return replace_state ;
483509}
484510
511+ /*
512+ * Try to add an attribute to an inode in leaf form.
513+ */
485514static int
486515xfs_attr_leaf_addname (
487516 struct xfs_attr_intent * attr )
488517{
489518 struct xfs_da_args * args = attr -> xattri_da_args ;
519+ struct xfs_buf * bp ;
490520 int error ;
491521
492522 ASSERT (xfs_attr_is_leaf (args -> dp ));
493523
524+ error = xfs_attr3_leaf_read (args -> trans , args -> dp , args -> owner , 0 , & bp );
525+ if (error )
526+ return error ;
527+
494528 /*
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.
497530 */
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 ;
504540
541+ trace_xfs_attr_leaf_replace (args );
505542 /*
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.
508546 */
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 ;
511553 }
512- if (error )
513- return error ;
514554
515555 /*
516556 * We need to commit and roll if we need to allocate remote xattr blocks
517557 * or perform more xattr manipulations. Otherwise there is nothing more
518558 * to do and we can return success.
519559 */
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 ) {
521570 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+
526576 trace_xfs_attr_leaf_addname_return (attr -> xattri_dela_state , args -> dp );
527577 return error ;
578+
579+ out_brelse :
580+ xfs_trans_brelse (args -> trans , bp );
581+ return error ;
528582}
529583
530584/*
@@ -1170,88 +1224,6 @@ xfs_attr_shortform_addname(
11701224 * External routines when attribute list is one block
11711225 *========================================================================*/
11721226
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-
12551227/*
12561228 * Return EEXIST if attr is found, or ENOATTR if not
12571229 */
0 commit comments