if (xfs_attr_is_leaf(dp)) {
error = xfs_attr_leaf_try_add(args, bp);
- if (error == -ENOSPC)
+ if (error == -ENOSPC) {
+ /*
+ * Promote the attribute list to the Btree format.
+ */
+ error = xfs_attr3_leaf_to_node(args);
+ if (error)
+ return error;
+
+ /*
+ * Finish any deferred work items and roll the transaction once
+ * more. The goal here is to call node_addname with the inode
+ * and transaction in the same state (inode locked and joined,
+ * transaction clean) no matter how we got to this step.
+ */
+ error = xfs_defer_finish(&args->trans);
+ if (error)
+ return error;
+
+ /*
+ * Commit the current trans (including the inode) and
+ * start a new one.
+ */
+ error = xfs_trans_roll_inode(&args->trans, dp);
+ if (error)
+ return error;
+
goto node;
- else if (error)
+ } else if (error) {
return error;
+ }
/*
* Commit the transaction that added the attr name so that
/* bp is gone due to xfs_da_shrink_inode */
return error;
+ }
node:
- /*
- * Promote the attribute list to the Btree format.
- */
- error = xfs_attr3_leaf_to_node(args);
- if (error)
- return error;
-
- /*
- * Finish any deferred work items and roll the transaction once
- * more. The goal here is to call node_addname with the inode
- * and transaction in the same state (inode locked and joined,
- * transaction clean) no matter how we got to this step.
- */
- error = xfs_defer_finish(&args->trans);
- if (error)
- return error;
- /*
- * Commit the current trans (including the inode) and
- * start a new one.
- */
- error = xfs_trans_roll_inode(&args->trans, dp);
- if (error)
- return error;
- }
do {
error = xfs_attr_node_addname_find_attr(args, &state);