Received: by 2002:a05:6358:11c7:b0:104:8066:f915 with SMTP id i7csp6104352rwl; Tue, 4 Apr 2023 07:56:52 -0700 (PDT) X-Google-Smtp-Source: AKy350ZTl96XZvAoGlOHT9bH3i0XfDv5J9mKH8MW358q7VyNpg7s90TnCs0LL3qBnvXGFsLScsV0 X-Received: by 2002:a17:907:e90:b0:930:3916:df17 with SMTP id ho16-20020a1709070e9000b009303916df17mr3426689ejc.0.1680620212219; Tue, 04 Apr 2023 07:56:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1680620212; cv=none; d=google.com; s=arc-20160816; b=LZZkE0/RGMG+cj+BVQjnajJ6nwaVuI2WI8lIE3iasqbpyq/HNHsYO7AE2Gs3gZA1zN 2uBBYLbwnqZVLnmmDA4P4T7slOA8hQraHX9kK2rz/UWqoYqjxYbwkDsZJnxzE1aGdNYj 4sdjZrStHQD6geN4ZvxMijnNhvAAx9LAIA2js6O67qPqVswLPRKg/pUXTc1IRCXhSciC UKLx16xk9YuBxeyPeMIkYTSsgbGh1t6Z1tSxlkYIOhEMYxuz81W6LdkV19DG+wFfQhyR gsqC90Tx+5w/xk08wcy23oyOTvSFPuzxj+l8YGIBK3bknA6K6ZMambyYdD52g4iXRIy2 6MEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Mu/TYgURhfr8hK7U6stIfBangv6J3wSWfzsQZ+cJkGQ=; b=m9gO9ACtP66nT9n6M3bC1lnQwArUa6IlnrtMijCN4FIz8HYFKBXKqYKh00Jv1mY3XN eNjDb6jKLVASPuDyqcCqS++qw8Am8wbfzqLH47tcVS6V48LSZnB4D8wYSzof3szSPZm2 mFJJ0qoTQwSbQX1PMt1JibrxGjBqNyST9RK+rWhkX7xEMnlv5eEqUVaX7heImUP8pVp5 XIzuUTZgiRTIQTq7yImfnQj3LMUzqg/w03imu6NFI8RkygO/5fgf7TT6+hgdMZ/w6UZr V+X3etI2KtAbvsEFsO+ZFLzX+nvRnvuv6hqULTTrfH3ssDadfXAxP6CHy7bbXT76669J MkBw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Rl1aPwif; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id f24-20020a170906739800b008e828688d69si694668ejl.798.2023.04.04.07.56.26; Tue, 04 Apr 2023 07:56:52 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Rl1aPwif; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233059AbjDDO4B (ORCPT + 99 others); Tue, 4 Apr 2023 10:56:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57970 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232964AbjDDOz6 (ORCPT ); Tue, 4 Apr 2023 10:55:58 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E8E414EE9 for ; Tue, 4 Apr 2023 07:54:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1680620086; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Mu/TYgURhfr8hK7U6stIfBangv6J3wSWfzsQZ+cJkGQ=; b=Rl1aPwifRp26zCj0nbkFETB/TOWCQ1gjeu5Qq26gtU+cFO0AxKK8KhP12Rhwn3oxYjjXUb +4RtjqaJF3Q1zMCm/OUJpt8Vx9MlV0vMbcWD3a7k2R3h0oIgpyU46KUTdZj5v8PHwfTUv6 4cH5pjJ3xiGTjZMeAjMxuY04UZIpLcg= Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-596-oE4SBhkvPEScDuW6IjH4vA-1; Tue, 04 Apr 2023 10:54:44 -0400 X-MC-Unique: oE4SBhkvPEScDuW6IjH4vA-1 Received: by mail-qk1-f199.google.com with SMTP id t23-20020a374617000000b0074a4dba4b5aso2199876qka.16 for ; Tue, 04 Apr 2023 07:54:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680620084; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Mu/TYgURhfr8hK7U6stIfBangv6J3wSWfzsQZ+cJkGQ=; b=LB5a8YjC0JuRDD4wKtljMGKljEE3ZwoOGSZWsW5FeQhVR6pFDtukncuW68n+Y+n269 G62GgT0zkBHZ8xRANH5r2RsokW2QmZXOlldtoUAW1NKeVWuQ4/PG28Sfz9X1MH8OYkKp GyZ5U5aFW9wCwGS3TFzyBggH8NGhnknguZ8CVnLH35cyBeYLpNs+aMtyY5vhf9yshRdQ MqRZExh+WJRBEhlqnL0sfvvXE9g77xgtQzR3WV5OtIFuDYTAVwuc9SGz5oQKl1lfCxPm 0ORYjJfbRzWO6BloaF1k77ultEQjodvYpWSXNoa7pRkAq+SrJa+V20OpK+AtpU1JjmBL fx/A== X-Gm-Message-State: AAQBX9ciuhlGNWeHgPECRqMVr3X9P78O+ij00ULi06oLHdu+EdMFyKck JLT1LxLfIY0WfKZkkgvRRPnzQRds8RdA/K9oykiDQLk+yamQlwlf/o2HHxXrFWw1g3JEfKnHadG X9gqy2jO+WkOMJrqTSlLy X-Received: by 2002:ac8:5a13:0:b0:3e3:937b:2a64 with SMTP id n19-20020ac85a13000000b003e3937b2a64mr3736995qta.18.1680620083958; Tue, 04 Apr 2023 07:54:43 -0700 (PDT) X-Received: by 2002:ac8:5a13:0:b0:3e3:937b:2a64 with SMTP id n19-20020ac85a13000000b003e3937b2a64mr3736946qta.18.1680620083477; Tue, 04 Apr 2023 07:54:43 -0700 (PDT) Received: from aalbersh.remote.csb ([109.183.6.197]) by smtp.gmail.com with ESMTPSA id j4-20020ac86644000000b003e6387431dcsm3296539qtp.7.2023.04.04.07.54.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Apr 2023 07:54:43 -0700 (PDT) From: Andrey Albershteyn To: djwong@kernel.org, dchinner@redhat.com, ebiggers@kernel.org, hch@infradead.org, linux-xfs@vger.kernel.org, fsverity@lists.linux.dev Cc: rpeterso@redhat.com, agruenba@redhat.com, xiang@kernel.org, chao@kernel.org, damien.lemoal@opensource.wdc.com, jth@kernel.org, linux-erofs@lists.ozlabs.org, linux-btrfs@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, cluster-devel@redhat.com, Allison Henderson Subject: [PATCH v2 01/23] xfs: Add new name to attri/d Date: Tue, 4 Apr 2023 16:52:57 +0200 Message-Id: <20230404145319.2057051-2-aalbersh@redhat.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230404145319.2057051-1-aalbersh@redhat.com> References: <20230404145319.2057051-1-aalbersh@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.2 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Allison Henderson This patch adds two new fields to the atti/d. They are nname and nnamelen. This will be used for parent pointer updates since a rename operation may cause the parent pointer to update both the name and value. So we need to carry both the new name as well as the target name in the attri/d. Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 12 ++- fs/xfs/libxfs/xfs_attr.h | 4 +- fs/xfs/libxfs/xfs_da_btree.h | 2 + fs/xfs/libxfs/xfs_log_format.h | 6 +- fs/xfs/xfs_attr_item.c | 135 +++++++++++++++++++++++++++------ fs/xfs/xfs_attr_item.h | 1 + 6 files changed, 133 insertions(+), 27 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index e28d93d232de..b1dbed7655e8 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -423,6 +423,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) { + args->name = args->new_name; + args->namelen = args->new_namelen; + args->hashval = xfs_da_hashname(args->name, + args->namelen); + } return replace_state; } return XFS_DAS_DONE; @@ -922,9 +928,13 @@ xfs_attr_defer_replace( struct xfs_da_args *args) { struct xfs_attr_intent *new; + int op_flag; int error = 0; - error = xfs_attr_intent_init(args, XFS_ATTRI_OP_FLAGS_REPLACE, &new); + op_flag = args->new_namelen == 0 ? XFS_ATTRI_OP_FLAGS_REPLACE : + XFS_ATTRI_OP_FLAGS_NVREPLACE; + + error = xfs_attr_intent_init(args, op_flag, &new); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index 81be9b3e4004..3e81f3f48560 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -510,8 +510,8 @@ struct xfs_attr_intent { struct xfs_da_args *xattri_da_args; /* - * Shared buffer containing the attr name and value so that the logging - * code can share large memory buffers between log items. + * Shared buffer containing the attr name, new name, and value so that + * the logging code can share large memory buffers between log items. */ struct xfs_attri_log_nameval *xattri_nameval; diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h index ffa3df5b2893..a4b29827603f 100644 --- a/fs/xfs/libxfs/xfs_da_btree.h +++ b/fs/xfs/libxfs/xfs_da_btree.h @@ -55,7 +55,9 @@ enum xfs_dacmp { typedef struct xfs_da_args { struct xfs_da_geometry *geo; /* da block geometry */ const uint8_t *name; /* string (maybe not NULL terminated) */ + const uint8_t *new_name; /* new attr name */ int namelen; /* length of string (maybe no NULL) */ + int new_namelen; /* new attr name len */ uint8_t filetype; /* filetype of inode for directories */ void *value; /* set of bytes (maybe contain NULLs) */ int valuelen; /* length of value */ diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h index f13e0809dc63..ae9c99762a24 100644 --- a/fs/xfs/libxfs/xfs_log_format.h +++ b/fs/xfs/libxfs/xfs_log_format.h @@ -117,7 +117,8 @@ struct xfs_unmount_log_format { #define XLOG_REG_TYPE_ATTRD_FORMAT 28 #define XLOG_REG_TYPE_ATTR_NAME 29 #define XLOG_REG_TYPE_ATTR_VALUE 30 -#define XLOG_REG_TYPE_MAX 30 +#define XLOG_REG_TYPE_ATTR_NNAME 31 +#define XLOG_REG_TYPE_MAX 31 /* @@ -957,6 +958,7 @@ struct xfs_icreate_log { #define XFS_ATTRI_OP_FLAGS_SET 1 /* Set the attribute */ #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_NVREPLACE 4 /* Replace attr name and val */ #define XFS_ATTRI_OP_FLAGS_TYPE_MASK 0xFF /* Flags type mask */ /* @@ -974,7 +976,7 @@ struct xfs_icreate_log { struct xfs_attri_log_format { uint16_t alfi_type; /* attri log item type */ uint16_t alfi_size; /* size of this item */ - uint32_t __pad; /* pad to 64 bit aligned */ + uint32_t alfi_nname_len; /* attr new name length */ uint64_t alfi_id; /* attri identifier */ uint64_t alfi_ino; /* the inode for this attr operation */ uint32_t alfi_op_flags; /* marks the op as a set or remove */ diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c index 2788a6f2edcd..95e9ecbb4a67 100644 --- a/fs/xfs/xfs_attr_item.c +++ b/fs/xfs/xfs_attr_item.c @@ -75,6 +75,8 @@ static inline struct xfs_attri_log_nameval * xfs_attri_log_nameval_alloc( const void *name, unsigned int name_len, + const void *nname, + unsigned int nname_len, const void *value, unsigned int value_len) { @@ -85,15 +87,25 @@ xfs_attri_log_nameval_alloc( * this. But kvmalloc() utterly sucks, so we use our own version. */ nv = xlog_kvmalloc(sizeof(struct xfs_attri_log_nameval) + - name_len + value_len); + name_len + nname_len + value_len); nv->name.i_addr = nv + 1; nv->name.i_len = name_len; nv->name.i_type = XLOG_REG_TYPE_ATTR_NAME; memcpy(nv->name.i_addr, name, name_len); + if (nname_len) { + nv->nname.i_addr = nv->name.i_addr + name_len; + nv->nname.i_len = nname_len; + memcpy(nv->nname.i_addr, nname, nname_len); + } else { + nv->nname.i_addr = NULL; + nv->nname.i_len = 0; + } + nv->nname.i_type = XLOG_REG_TYPE_ATTR_NNAME; + if (value_len) { - nv->value.i_addr = nv->name.i_addr + name_len; + nv->value.i_addr = nv->name.i_addr + nname_len + name_len; nv->value.i_len = value_len; memcpy(nv->value.i_addr, value, value_len); } else { @@ -147,11 +159,15 @@ xfs_attri_item_size( *nbytes += sizeof(struct xfs_attri_log_format) + xlog_calc_iovec_len(nv->name.i_len); - if (!nv->value.i_len) - return; + if (nv->nname.i_len) { + *nvecs += 1; + *nbytes += xlog_calc_iovec_len(nv->nname.i_len); + } - *nvecs += 1; - *nbytes += xlog_calc_iovec_len(nv->value.i_len); + if (nv->value.i_len) { + *nvecs += 1; + *nbytes += xlog_calc_iovec_len(nv->value.i_len); + } } /* @@ -181,6 +197,9 @@ xfs_attri_item_format( ASSERT(nv->name.i_len > 0); attrip->attri_format.alfi_size++; + if (nv->nname.i_len > 0) + attrip->attri_format.alfi_size++; + if (nv->value.i_len > 0) attrip->attri_format.alfi_size++; @@ -188,6 +207,10 @@ xfs_attri_item_format( &attrip->attri_format, sizeof(struct xfs_attri_log_format)); xlog_copy_from_iovec(lv, &vecp, &nv->name); + + if (nv->nname.i_len > 0) + xlog_copy_from_iovec(lv, &vecp, &nv->nname); + if (nv->value.i_len > 0) xlog_copy_from_iovec(lv, &vecp, &nv->value); } @@ -374,6 +397,7 @@ xfs_attr_log_item( attrp->alfi_op_flags = attr->xattri_op_flags; attrp->alfi_value_len = attr->xattri_nameval->value.i_len; attrp->alfi_name_len = attr->xattri_nameval->name.i_len; + attrp->alfi_nname_len = attr->xattri_nameval->nname.i_len; ASSERT(!(attr->xattri_da_args->attr_filter & ~XFS_ATTRI_FILTER_MASK)); attrp->alfi_attr_filter = attr->xattri_da_args->attr_filter; } @@ -415,7 +439,8 @@ xfs_attr_create_intent( * deferred work state structure. */ attr->xattri_nameval = xfs_attri_log_nameval_alloc(args->name, - args->namelen, args->value, args->valuelen); + args->namelen, args->new_name, + args->new_namelen, args->value, args->valuelen); } attrip = xfs_attri_init(mp, attr->xattri_nameval); @@ -503,7 +528,8 @@ xfs_attri_validate( unsigned int op = attrp->alfi_op_flags & XFS_ATTRI_OP_FLAGS_TYPE_MASK; - if (attrp->__pad != 0) + if (attrp->alfi_op_flags != XFS_ATTRI_OP_FLAGS_NVREPLACE && + attrp->alfi_nname_len != 0) return false; if (attrp->alfi_op_flags & ~XFS_ATTRI_OP_FLAGS_TYPE_MASK) @@ -517,6 +543,7 @@ xfs_attri_validate( case XFS_ATTRI_OP_FLAGS_SET: case XFS_ATTRI_OP_FLAGS_REPLACE: case XFS_ATTRI_OP_FLAGS_REMOVE: + case XFS_ATTRI_OP_FLAGS_NVREPLACE: break; default: return false; @@ -526,9 +553,14 @@ xfs_attri_validate( return false; if ((attrp->alfi_name_len > XATTR_NAME_MAX) || + (attrp->alfi_nname_len > XATTR_NAME_MAX) || (attrp->alfi_name_len == 0)) return false; + if (op == XFS_ATTRI_OP_FLAGS_REMOVE && + attrp->alfi_value_len != 0) + return false; + return xfs_verify_ino(mp, attrp->alfi_ino); } @@ -589,6 +621,8 @@ xfs_attri_item_recover( args->whichfork = XFS_ATTR_FORK; args->name = nv->name.i_addr; args->namelen = nv->name.i_len; + args->new_name = nv->nname.i_addr; + args->new_namelen = nv->nname.i_len; args->hashval = xfs_da_hashname(args->name, args->namelen); args->attr_filter = attrp->alfi_attr_filter & XFS_ATTRI_FILTER_MASK; args->op_flags = XFS_DA_OP_RECOVERY | XFS_DA_OP_OKNOENT | @@ -599,6 +633,7 @@ xfs_attri_item_recover( switch (attr->xattri_op_flags) { case XFS_ATTRI_OP_FLAGS_SET: case XFS_ATTRI_OP_FLAGS_REPLACE: + case XFS_ATTRI_OP_FLAGS_NVREPLACE: args->value = nv->value.i_addr; args->valuelen = nv->value.i_len; args->total = xfs_attr_calc_size(args, &local); @@ -688,6 +723,7 @@ xfs_attri_item_relog( new_attrp->alfi_op_flags = old_attrp->alfi_op_flags; new_attrp->alfi_value_len = old_attrp->alfi_value_len; new_attrp->alfi_name_len = old_attrp->alfi_name_len; + new_attrp->alfi_nname_len = old_attrp->alfi_nname_len; new_attrp->alfi_attr_filter = old_attrp->alfi_attr_filter; xfs_trans_add_item(tp, &new_attrip->attri_item); @@ -710,48 +746,102 @@ xlog_recover_attri_commit_pass2( const void *attr_value = NULL; const void *attr_name; size_t len; - - attri_formatp = item->ri_buf[0].i_addr; - attr_name = item->ri_buf[1].i_addr; + const void *attr_nname = NULL; + int op, i = 0; /* Validate xfs_attri_log_format before the large memory allocation */ len = sizeof(struct xfs_attri_log_format); - if (item->ri_buf[0].i_len != len) { + if (item->ri_buf[i].i_len != len) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, - item->ri_buf[0].i_addr, item->ri_buf[0].i_len); + item->ri_buf[i].i_addr, item->ri_buf[i].i_len); return -EFSCORRUPTED; } + attri_formatp = item->ri_buf[i].i_addr; if (!xfs_attri_validate(mp, attri_formatp)) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, - item->ri_buf[0].i_addr, item->ri_buf[0].i_len); + item->ri_buf[i].i_addr, item->ri_buf[i].i_len); return -EFSCORRUPTED; } + op = attri_formatp->alfi_op_flags & XFS_ATTRI_OP_FLAGS_TYPE_MASK; + switch (op) { + case XFS_ATTRI_OP_FLAGS_SET: + case XFS_ATTRI_OP_FLAGS_REPLACE: + if (item->ri_total != 3) { + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, + attri_formatp, len); + return -EFSCORRUPTED; + } + break; + case XFS_ATTRI_OP_FLAGS_REMOVE: + if (item->ri_total != 2) { + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, + attri_formatp, len); + return -EFSCORRUPTED; + } + break; + case XFS_ATTRI_OP_FLAGS_NVREPLACE: + if (item->ri_total != 4) { + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, + attri_formatp, len); + return -EFSCORRUPTED; + } + break; + default: + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, + attri_formatp, len); + return -EFSCORRUPTED; + } + + i++; /* Validate the attr name */ - if (item->ri_buf[1].i_len != + if (item->ri_buf[i].i_len != xlog_calc_iovec_len(attri_formatp->alfi_name_len)) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, - item->ri_buf[0].i_addr, item->ri_buf[0].i_len); + attri_formatp, len); return -EFSCORRUPTED; } + attr_name = item->ri_buf[i].i_addr; if (!xfs_attr_namecheck(attr_name, attri_formatp->alfi_name_len)) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, - item->ri_buf[1].i_addr, item->ri_buf[1].i_len); + item->ri_buf[i].i_addr, item->ri_buf[i].i_len); return -EFSCORRUPTED; } + i++; + if (attri_formatp->alfi_nname_len) { + /* Validate the attr nname */ + if (item->ri_buf[i].i_len != + xlog_calc_iovec_len(attri_formatp->alfi_nname_len)) { + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, + item->ri_buf[i].i_addr, + item->ri_buf[i].i_len); + return -EFSCORRUPTED; + } + + attr_nname = item->ri_buf[i].i_addr; + if (!xfs_attr_namecheck(attr_nname, + attri_formatp->alfi_nname_len)) { + XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, + item->ri_buf[i].i_addr, + item->ri_buf[i].i_len); + return -EFSCORRUPTED; + } + i++; + } + + /* Validate the attr value, if present */ if (attri_formatp->alfi_value_len != 0) { - if (item->ri_buf[2].i_len != xlog_calc_iovec_len(attri_formatp->alfi_value_len)) { + if (item->ri_buf[i].i_len != xlog_calc_iovec_len(attri_formatp->alfi_value_len)) { XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, - item->ri_buf[0].i_addr, - item->ri_buf[0].i_len); + attri_formatp, len); return -EFSCORRUPTED; } - attr_value = item->ri_buf[2].i_addr; + attr_value = item->ri_buf[i].i_addr; } /* @@ -760,7 +850,8 @@ xlog_recover_attri_commit_pass2( * reference. */ nv = xfs_attri_log_nameval_alloc(attr_name, - attri_formatp->alfi_name_len, attr_value, + attri_formatp->alfi_name_len, attr_nname, + attri_formatp->alfi_nname_len, attr_value, attri_formatp->alfi_value_len); attrip = xfs_attri_init(mp, nv); diff --git a/fs/xfs/xfs_attr_item.h b/fs/xfs/xfs_attr_item.h index 3280a7930287..24d4968dd6cc 100644 --- a/fs/xfs/xfs_attr_item.h +++ b/fs/xfs/xfs_attr_item.h @@ -13,6 +13,7 @@ struct kmem_zone; struct xfs_attri_log_nameval { struct xfs_log_iovec name; + struct xfs_log_iovec nname; struct xfs_log_iovec value; refcount_t refcount; -- 2.38.4