@@ -903,9 +903,13 @@ xfs_attr_defer_add(
struct xfs_da_args *args)
{
struct xfs_attr_intent *new;
+ int op_flag = XFS_ATTRI_OP_FLAGS_SET;
int error = 0;
- error = xfs_attr_intent_init(args, XFS_ATTRI_OP_FLAGS_SET, &new);
+ if (args->op_flags & XFS_DA_OP_NVLOOKUP)
+ op_flag = XFS_ATTRI_OP_FLAGS_NVSET;
+
+ error = xfs_attr_intent_init(args, op_flag, &new);
if (error)
return error;
@@ -958,6 +958,7 @@ struct xfs_icreate_log {
#define XFS_ATTRI_OP_FLAGS_REMOVE 2 /* Remove the attribute */
#define XFS_ATTRI_OP_FLAGS_REPLACE 3 /* Replace the attribute */
#define XFS_ATTRI_OP_FLAGS_NVREMOVE 4 /* Remove attr w/ vlookup */
+#define XFS_ATTRI_OP_FLAGS_NVSET 5 /* Set attr with w/ vlookup */
#define XFS_ATTRI_OP_FLAGS_TYPE_MASK 0xFF /* Flags type mask */
/*
@@ -523,6 +523,7 @@ xfs_attri_validate(
case XFS_ATTRI_OP_FLAGS_REPLACE:
case XFS_ATTRI_OP_FLAGS_REMOVE:
case XFS_ATTRI_OP_FLAGS_NVREMOVE:
+ case XFS_ATTRI_OP_FLAGS_NVSET:
break;
default:
return false;
@@ -604,6 +605,9 @@ xfs_attri_item_recover(
ASSERT(xfs_sb_version_haslogxattrs(&mp->m_sb));
switch (xfs_attr_intent_op(attr)) {
+ case XFS_ATTRI_OP_FLAGS_NVSET:
+ args->op_flags |= XFS_DA_OP_NVLOOKUP;
+ fallthrough;
case XFS_ATTRI_OP_FLAGS_SET:
case XFS_ATTRI_OP_FLAGS_REPLACE:
args->total = xfs_attr_calc_size(args, &local);
@@ -740,6 +744,7 @@ xlog_recover_attri_commit_pass2(
/* Check the number of log iovecs makes sense for the op code. */
op = xfs_attr_log_item_op(attri_formatp);
switch (op) {
+ case XFS_ATTRI_OP_FLAGS_NVSET:
case XFS_ATTRI_OP_FLAGS_NVREMOVE:
/* Log item, attr name, optional attr value */
if (item->ri_total != 3 && item->ri_total != 2) {
@@ -824,6 +829,7 @@ xlog_recover_attri_commit_pass2(
return -EFSCORRUPTED;
}
fallthrough;
+ case XFS_ATTRI_OP_FLAGS_NVSET:
case XFS_ATTRI_OP_FLAGS_NVREMOVE:
case XFS_ATTRI_OP_FLAGS_SET:
case XFS_ATTRI_OP_FLAGS_REPLACE:
@@ -832,7 +838,7 @@ xlog_recover_attri_commit_pass2(
* and do not take a newname. Values are optional for set and
* replace.
*
- * Name-value remove operations must have a name, do not
+ * Name-value set/remove operations must have a name, do not
* take a newname, and can take a value.
*/
if (attr_name == NULL || name_len == 0) {