@@ -424,7 +424,12 @@ xfs_attr_complete_op(
args->op_flags &= ~XFS_DA_OP_REPLACE;
if (do_replace) {
args->attr_filter &= ~XFS_ATTR_INCOMPLETE;
- if (args->new_namelen > 0) {
+ if (args->op_flags & XFS_DA_OP_VLOOKUP) {
+ args->name = args->new_name;
+ args->namelen = args->new_namelen;
+ args->hashval = xfs_da_hashname(args->name,
+ args->namelen);
+ } else if (args->new_namelen > 0) {
args->name = args->new_name;
args->namelen = args->new_namelen;
args->hashval = xfs_da_hashname(args->name,
@@ -933,11 +938,13 @@ xfs_attr_defer_replace(
struct xfs_da_args *args)
{
struct xfs_attr_intent *new;
- int op_flag;
+ int op_flag = XFS_ATTRI_OP_FLAGS_REPLACE;
int error = 0;
- op_flag = args->new_namelen == 0 ? XFS_ATTRI_OP_FLAGS_REPLACE :
- XFS_ATTRI_OP_FLAGS_NVREPLACE;
+ if (args->op_flags & XFS_DA_OP_VLOOKUP)
+ op_flag = XFS_ATTRI_OP_FLAGS_NVREPLACEXXX;
+ else if (args->new_namelen > 0)
+ op_flag = XFS_ATTRI_OP_FLAGS_NVREPLACE;
error = xfs_attr_intent_init(args, op_flag, &new);
if (error)
@@ -961,6 +961,7 @@ struct xfs_icreate_log {
#define XFS_ATTRI_OP_FLAGS_NVREPLACE 4 /* Replace attr name and val */
#define XFS_ATTRI_OP_FLAGS_NVREMOVE 5 /* Remove attr w/ vlookup */
#define XFS_ATTRI_OP_FLAGS_NVSET 6 /* Set attr with w/ vlookup */
+#define XFS_ATTRI_OP_FLAGS_NVREPLACEXXX 7 /* Replace attr name and val */
#define XFS_ATTRI_OP_FLAGS_TYPE_MASK 0xFF /* Flags type mask */
/*
@@ -403,7 +403,10 @@ xfs_attr_log_item(
attrp->alfi_op_flags = attr->xattri_op_flags;
attrp->alfi_value_len = attr->xattri_nameval->value.i_len;
- if (xfs_attr_log_item_op(attrp) == XFS_ATTRI_OP_FLAGS_NVREPLACE) {
+ if (xfs_attr_log_item_op(attrp) == XFS_ATTRI_OP_FLAGS_NVREPLACEXXX) {
+ attrp->alfi_oldname_len = attr->xattri_nameval->name.i_len;
+ attrp->alfi_newname_len = attr->xattri_nameval->newname.i_len;
+ } else if (xfs_attr_log_item_op(attrp) == XFS_ATTRI_OP_FLAGS_NVREPLACE) {
attrp->alfi_oldname_len = attr->xattri_nameval->name.i_len;
attrp->alfi_newname_len = attr->xattri_nameval->newname.i_len;
} else {
@@ -564,6 +567,7 @@ xfs_attri_validate(
if (attrp->alfi_value_len > XATTR_SIZE_MAX)
return false;
break;
+ case XFS_ATTRI_OP_FLAGS_NVREPLACEXXX:
case XFS_ATTRI_OP_FLAGS_NVREPLACE:
if (attrp->alfi_oldname_len == 0 ||
attrp->alfi_oldname_len > XATTR_NAME_MAX)
@@ -649,6 +653,7 @@ xfs_attri_item_recover(
switch (attr->xattri_op_flags) {
case XFS_ATTRI_OP_FLAGS_NVSET:
+ case XFS_ATTRI_OP_FLAGS_NVREPLACEXXX:
args->op_flags |= XFS_DA_OP_VLOOKUP;
fallthrough;
case XFS_ATTRI_OP_FLAGS_SET:
@@ -747,7 +752,10 @@ xfs_attri_item_relog(
new_attrp->alfi_ino = old_attrp->alfi_ino;
new_attrp->alfi_op_flags = old_attrp->alfi_op_flags;
new_attrp->alfi_value_len = old_attrp->alfi_value_len;
- if (xfs_attr_log_item_op(old_attrp) == XFS_ATTRI_OP_FLAGS_NVREPLACE) {
+ if (xfs_attr_log_item_op(old_attrp) == XFS_ATTRI_OP_FLAGS_NVREPLACEXXX) {
+ new_attrp->alfi_newname_len = old_attrp->alfi_newname_len;
+ new_attrp->alfi_oldname_len = old_attrp->alfi_oldname_len;
+ } else if (xfs_attr_log_item_op(old_attrp) == XFS_ATTRI_OP_FLAGS_NVREPLACE) {
new_attrp->alfi_newname_len = old_attrp->alfi_newname_len;
new_attrp->alfi_oldname_len = old_attrp->alfi_oldname_len;
} else {
@@ -815,6 +823,7 @@ xlog_recover_attri_commit_pass2(
}
name_len = attri_formatp->alfi_name_len;
break;
+ case XFS_ATTRI_OP_FLAGS_NVREPLACEXXX:
case XFS_ATTRI_OP_FLAGS_NVREPLACE:
if (item->ri_total != 3 && item->ri_total != 4) {
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,