From patchwork Fri Apr 12 22:50:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Allison Henderson X-Patchwork-Id: 10899199 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5AF421515 for ; Fri, 12 Apr 2019 22:52:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4117F28E0B for ; Fri, 12 Apr 2019 22:52:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3585C28F20; Fri, 12 Apr 2019 22:52:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 73A1328E0B for ; Fri, 12 Apr 2019 22:52:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727020AbfDLWwt (ORCPT ); Fri, 12 Apr 2019 18:52:49 -0400 Received: from userp2130.oracle.com ([156.151.31.86]:43604 "EHLO userp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726902AbfDLWws (ORCPT ); Fri, 12 Apr 2019 18:52:48 -0400 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMdcsc010255 for ; Fri, 12 Apr 2019 22:52:47 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=JvwAqhxbdI9gj23SqjvVeh0udOW2P9f8rjQhf9z0P9o=; b=j/ivRUkr/HNBJWI1P3t7EUmvdvrvuCKc/QWvKnSXRzNH2dNMO2ewjqmXJkbASEmNIgkJ x1bML+1JWH2Qe9i1BgWgTdtibjWgK/QUaIznDKWQe6+CdtBKBMPoM+MobJcKYjUs7Tbg U54OFtSniEewpkzcM5d0gCfpiRkcmvuAn6fTQgYHO/ewjX58OxgSm3MOU6lr6MviMTWL Dr9BOUb4HhpCWUY20DHcVnDUBpccog/xqyDe2wCKZS/5ez5F8FAbAaHbtQT/VmXJof1s W8K232rHEMPNW99CHufzJYuug+YRHZvhJn/dnSazMKJEh+B9vVcYzQdNSPnl9WzyA4o7 7Q== Received: from aserp3030.oracle.com (aserp3030.oracle.com [141.146.126.71]) by userp2130.oracle.com with ESMTP id 2rpkhtgtwm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:47 +0000 Received: from pps.filterd (aserp3030.oracle.com [127.0.0.1]) by aserp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMpiAc144325 for ; Fri, 12 Apr 2019 22:52:46 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserp3030.oracle.com with ESMTP id 2rt9uqcvkr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:46 +0000 Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x3CMqjBP017239 for ; Fri, 12 Apr 2019 22:52:45 GMT Received: from localhost.localdomain (/70.176.225.12) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 12 Apr 2019 15:52:44 -0700 From: Allison Henderson To: linux-xfs@vger.kernel.org Subject: [PATCH 1/9] xfs: Remove all strlen in all xfs_attr_* functions for attr names. Date: Fri, 12 Apr 2019 15:50:28 -0700 Message-Id: <20190412225036.22939-2-allison.henderson@oracle.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190412225036.22939-1-allison.henderson@oracle.com> References: <20190412225036.22939-1-allison.henderson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=3 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This helps to pre-simplify the extra handling of the null terminator in delayed operations which use memcpy rather than strlen. Later when we introduce parent pointers, attribute names will become binary, so strlen will not work at all. Removing uses of strlen now will help reduce complexities later Signed-off-by: Allison Henderson Reviewed-by: Darrick J. Wong Reviewed-by: Brian Foster --- fs/xfs/libxfs/xfs_attr.c | 12 ++++++++---- fs/xfs/libxfs/xfs_attr.h | 9 ++++++--- fs/xfs/xfs_acl.c | 12 +++++++----- fs/xfs/xfs_ioctl.c | 13 ++++++++++--- fs/xfs/xfs_iops.c | 6 ++++-- fs/xfs/xfs_xattr.c | 10 ++++++---- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 2dd9ee2..3da6b0d 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -67,6 +67,7 @@ xfs_attr_args_init( struct xfs_da_args *args, struct xfs_inode *dp, const unsigned char *name, + size_t namelen, int flags) { @@ -79,7 +80,7 @@ xfs_attr_args_init( args->dp = dp; args->flags = flags; args->name = name; - args->namelen = strlen((const char *)name); + args->namelen = namelen; if (args->namelen >= MAXNAMELEN) return -EFAULT; /* match IRIX behaviour */ @@ -125,6 +126,7 @@ int xfs_attr_get( struct xfs_inode *ip, const unsigned char *name, + size_t namelen, unsigned char *value, int *valuelenp, int flags) @@ -138,7 +140,7 @@ xfs_attr_get( if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return -EIO; - error = xfs_attr_args_init(&args, ip, name, flags); + error = xfs_attr_args_init(&args, ip, name, namelen, flags); if (error) return error; @@ -317,6 +319,7 @@ int xfs_attr_set( struct xfs_inode *dp, const unsigned char *name, + size_t namelen, unsigned char *value, int valuelen, int flags) @@ -333,7 +336,7 @@ xfs_attr_set( if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return -EIO; - error = xfs_attr_args_init(&args, dp, name, flags); + error = xfs_attr_args_init(&args, dp, name, namelen, flags); if (error) return error; @@ -425,6 +428,7 @@ int xfs_attr_remove( struct xfs_inode *dp, const unsigned char *name, + size_t namelen, int flags) { struct xfs_mount *mp = dp->i_mount; @@ -436,7 +440,7 @@ xfs_attr_remove( if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return -EIO; - error = xfs_attr_args_init(&args, dp, name, flags); + error = xfs_attr_args_init(&args, dp, name, namelen, flags); if (error) return error; diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index 2297d84..52f63dc 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -137,11 +137,14 @@ int xfs_attr_list_int(struct xfs_attr_list_context *); int xfs_inode_hasattr(struct xfs_inode *ip); int xfs_attr_get_ilocked(struct xfs_inode *ip, struct xfs_da_args *args); int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name, - unsigned char *value, int *valuelenp, int flags); + size_t namelen, unsigned char *value, int *valuelenp, + int flags); int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name, - unsigned char *value, int valuelen, int flags); + size_t namelen, unsigned char *value, int valuelen, + int flags); int xfs_attr_set_args(struct xfs_da_args *args, struct xfs_buf **leaf_bp); -int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags); +int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, + size_t namelen, int flags); int xfs_attr_remove_args(struct xfs_da_args *args); int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize, int flags, struct attrlist_cursor_kern *cursor); diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 8039e35..142de8d 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -141,8 +141,8 @@ xfs_get_acl(struct inode *inode, int type) if (!xfs_acl) return ERR_PTR(-ENOMEM); - error = xfs_attr_get(ip, ea_name, (unsigned char *)xfs_acl, - &len, ATTR_ROOT); + error = xfs_attr_get(ip, ea_name, strlen(ea_name), + (unsigned char *)xfs_acl, &len, ATTR_ROOT); if (error) { /* * If the attribute doesn't exist make sure we have a negative @@ -192,15 +192,17 @@ __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) len -= sizeof(struct xfs_acl_entry) * (XFS_ACL_MAX_ENTRIES(ip->i_mount) - acl->a_count); - error = xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl, - len, ATTR_ROOT); + error = xfs_attr_set(ip, ea_name, strlen(ea_name), + (unsigned char *)xfs_acl, len, ATTR_ROOT); kmem_free(xfs_acl); } else { /* * A NULL ACL argument means we want to remove the ACL. */ - error = xfs_attr_remove(ip, ea_name, ATTR_ROOT); + error = xfs_attr_remove(ip, ea_name, + strlen(ea_name), + ATTR_ROOT); /* * If the attribute didn't exist to start with that's fine. diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 6ecdbb3..ab341d6 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -437,6 +437,7 @@ xfs_attrmulti_attr_get( { unsigned char *kbuf; int error = -EFAULT; + size_t namelen; if (*len > XFS_XATTR_SIZE_MAX) return -EINVAL; @@ -444,7 +445,9 @@ xfs_attrmulti_attr_get( if (!kbuf) return -ENOMEM; - error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags); + namelen = strlen(name); + error = xfs_attr_get(XFS_I(inode), name, namelen, + kbuf, (int *)len, flags); if (error) goto out_kfree; @@ -466,6 +469,7 @@ xfs_attrmulti_attr_set( { unsigned char *kbuf; int error; + size_t namelen; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EPERM; @@ -476,7 +480,8 @@ xfs_attrmulti_attr_set( if (IS_ERR(kbuf)) return PTR_ERR(kbuf); - error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); + namelen = strlen(name); + error = xfs_attr_set(XFS_I(inode), name, namelen, kbuf, len, flags); if (!error) xfs_forget_acl(inode, name, flags); kfree(kbuf); @@ -490,10 +495,12 @@ xfs_attrmulti_attr_remove( uint32_t flags) { int error; + size_t namelen; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EPERM; - error = xfs_attr_remove(XFS_I(inode), name, flags); + namelen = strlen(name); + error = xfs_attr_remove(XFS_I(inode), name, namelen, flags); if (!error) xfs_forget_acl(inode, name, flags); return error; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 74047bd..e73c21a 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -59,8 +59,10 @@ xfs_initxattrs( int error = 0; for (xattr = xattr_array; xattr->name != NULL; xattr++) { - error = xfs_attr_set(ip, xattr->name, xattr->value, - xattr->value_len, ATTR_SECURE); + error = xfs_attr_set(ip, xattr->name, + strlen(xattr->name), + xattr->value, xattr->value_len, + ATTR_SECURE); if (error < 0) break; } diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 9a63016..3013746 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -26,6 +26,7 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused, int xflags = handler->flags; struct xfs_inode *ip = XFS_I(inode); int error, asize = size; + size_t namelen = strlen(name); /* Convert Linux syscall to XFS internal ATTR flags */ if (!size) { @@ -33,7 +34,7 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused, value = NULL; } - error = xfs_attr_get(ip, (unsigned char *)name, value, &asize, xflags); + error = xfs_attr_get(ip, name, namelen, value, &asize, xflags); if (error) return error; return asize; @@ -69,6 +70,7 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused, int xflags = handler->flags; struct xfs_inode *ip = XFS_I(inode); int error; + size_t namelen = strlen(name); /* Convert Linux syscall to XFS internal ATTR flags */ if (flags & XATTR_CREATE) @@ -77,9 +79,9 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused, xflags |= ATTR_REPLACE; if (!value) - return xfs_attr_remove(ip, (unsigned char *)name, xflags); - error = xfs_attr_set(ip, (unsigned char *)name, - (void *)value, size, xflags); + return xfs_attr_remove(ip, name, + namelen, xflags); + error = xfs_attr_set(ip, name, namelen, (void *)value, size, xflags); if (!error) xfs_forget_acl(inode, name, xflags); From patchwork Fri Apr 12 22:50:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Allison Henderson X-Patchwork-Id: 10899193 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C8B7013B5 for ; Fri, 12 Apr 2019 22:52:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AEA4E28E0B for ; Fri, 12 Apr 2019 22:52:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A2FC728EC4; Fri, 12 Apr 2019 22:52:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 48B4F28E0B for ; Fri, 12 Apr 2019 22:52:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726944AbfDLWwr (ORCPT ); Fri, 12 Apr 2019 18:52:47 -0400 Received: from userp2130.oracle.com ([156.151.31.86]:43592 "EHLO userp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726477AbfDLWwr (ORCPT ); Fri, 12 Apr 2019 18:52:47 -0400 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMd9KW010185 for ; Fri, 12 Apr 2019 22:52:46 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=KgLexfQVbepFrSU1Y9N9aYKpzmVUQofkZPF8E6q8sQA=; b=BA6An5KkUjrdXSJqSUfOBMA52C77i26sXu+er5MbC2NqqUuOmL2fgMOsmDgC0auo3j70 ZWMtAXFmMqPJbEOR6qIoW5UOzyWWgvuqGki0CdwUlS8b5DqvjpoJBzuVY09YZi087Ejb XNpH+vc1tinsCCbhUdcI5YrVknYA3esxiCSnIm18mJ+e9MX85z7eX273nIlezCZlRw2U Ar4dRePgKQ2bSNMwsja7Zzz6lFFLTpLtWOqroSNhFTVEtRSCrngIL8BxGzLyYnIED5zQ r+myiuR32AGH51xzj+cUlWM+QG1dO0U1WoqL7BHHnszKq+4OtG/3JJeEvBc8Of9+RpWO sA== Received: from userp3030.oracle.com (userp3030.oracle.com [156.151.31.80]) by userp2130.oracle.com with ESMTP id 2rpkhtgtwk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:46 +0000 Received: from pps.filterd (userp3030.oracle.com [127.0.0.1]) by userp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMqb9g076136 for ; Fri, 12 Apr 2019 22:52:46 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userp3030.oracle.com with ESMTP id 2rtqnpaknf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:45 +0000 Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x3CMqjaH020688 for ; Fri, 12 Apr 2019 22:52:45 GMT Received: from localhost.localdomain (/70.176.225.12) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 12 Apr 2019 15:52:45 -0700 From: Allison Henderson To: linux-xfs@vger.kernel.org Subject: [PATCH 2/9] xfs: Hold inode locks in xfs_ialloc Date: Fri, 12 Apr 2019 15:50:29 -0700 Message-Id: <20190412225036.22939-3-allison.henderson@oracle.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190412225036.22939-1-allison.henderson@oracle.com> References: <20190412225036.22939-1-allison.henderson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=681 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=703 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Modify xfs_ialloc to hold locks after return. Caller will be responsible for manual unlock. We will need this later to hold locks across parent pointer operations Signed-off-by: Allison Henderson --- fs/xfs/xfs_inode.c | 6 +++++- fs/xfs/xfs_qm.c | 1 + fs/xfs/xfs_symlink.c | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index f643a92..30a3130 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -744,6 +744,8 @@ xfs_lookup( * to attach to or associate with (i.e. pip == NULL) because they * are not linked into the directory structure - they are attached * directly to the superblock - and so have no parent. + * + * Caller is responsible for unlocking the inode manually upon return */ static int xfs_ialloc( @@ -942,7 +944,7 @@ xfs_ialloc( /* * Log the new values stuffed into the inode. */ - xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); + xfs_trans_ijoin(tp, ip, 0); xfs_trans_log_inode(tp, ip, flags); /* now that we have an i_mode we can setup the inode structure */ @@ -1264,6 +1266,7 @@ xfs_create( xfs_qm_dqrele(pdqp); *ipp = ip; + xfs_iunlock(ip, XFS_ILOCK_EXCL); return 0; out_trans_cancel: @@ -1359,6 +1362,7 @@ xfs_create_tmpfile( xfs_qm_dqrele(pdqp); *ipp = ip; + xfs_iunlock(ip, XFS_ILOCK_EXCL); return 0; out_trans_cancel: diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 52ed790..69006e5 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -820,6 +820,7 @@ xfs_qm_qino_alloc( } if (need_alloc) xfs_finish_inode_setup(*ip); + xfs_iunlock(*ip, XFS_ILOCK_EXCL); return error; } diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index b2c1177..13d31fe 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -353,6 +353,7 @@ xfs_symlink( xfs_qm_dqrele(pdqp); *ipp = ip; + xfs_iunlock(ip, XFS_ILOCK_EXCL); return 0; out_trans_cancel: @@ -374,6 +375,8 @@ xfs_symlink( if (unlock_dp_on_error) xfs_iunlock(dp, XFS_ILOCK_EXCL); + if (ip) + xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; } From patchwork Fri Apr 12 22:50:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Allison Henderson X-Patchwork-Id: 10899205 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C72A917E0 for ; Fri, 12 Apr 2019 22:52:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ADA3E28E0B for ; Fri, 12 Apr 2019 22:52:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A178928EC2; Fri, 12 Apr 2019 22:52:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 655C728EC4 for ; Fri, 12 Apr 2019 22:52:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726788AbfDLWwt (ORCPT ); Fri, 12 Apr 2019 18:52:49 -0400 Received: from userp2130.oracle.com ([156.151.31.86]:43602 "EHLO userp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726850AbfDLWwt (ORCPT ); Fri, 12 Apr 2019 18:52:49 -0400 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMeO2I010804 for ; Fri, 12 Apr 2019 22:52:47 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=HpmrjSHi4b7WtVq6rjLcLod4H3F2FwE9+TIxd5l96jM=; b=w+edswsAWoOVOCUFjXtg3eaVdP11qClL1KJxpog2Dj/hYp7RINNOblLbRklWwu0Jr2Gx HnZZEk7nCjoGSgQZyW25/OuzoYZ9rABkvnhqzQEps1dhRjVqTztdtTnZhumy9yj8aiJ+ Rgv4avWLOVGU92rEKpVDY6Zxg2vSuSMD0tFCdMAOEx5hc7BppqNcQEb0SatzEHs41C9F BO8F/vvjVn66WXDbBz+k3DoGttPCniOKHAvClTGlkgTLXWrshfaEsTQbApz0Z+bblde/ SGSJmuk+WCvA9MJm9oyX+kxlGjuRI1hIJVTJNbFK1Y+o+hMFXBi3MJZuLvyOi6TxRcMx hQ== Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by userp2130.oracle.com with ESMTP id 2rpkhtgtwn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:46 +0000 Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMq3VL100992 for ; Fri, 12 Apr 2019 22:52:46 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userp3020.oracle.com with ESMTP id 2rtyj2ub79-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:46 +0000 Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x3CMqjel017242 for ; Fri, 12 Apr 2019 22:52:45 GMT Received: from localhost.localdomain (/70.176.225.12) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 12 Apr 2019 15:52:45 -0700 From: Allison Henderson To: linux-xfs@vger.kernel.org Subject: [PATCH 3/9] xfs: Add trans toggle to attr routines Date: Fri, 12 Apr 2019 15:50:30 -0700 Message-Id: <20190412225036.22939-4-allison.henderson@oracle.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190412225036.22939-1-allison.henderson@oracle.com> References: <20190412225036.22939-1-allison.henderson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds a roll_trans parameter to all attribute routines that may roll a transaction. Calling functions may pass true to roll transactions as normal, or false to hold them. This patch is temporary and will be removed later when all code paths have been made to pass a false value. The temporary boolean assists us to introduce changes across multiple smaller patches instead of handling all affected code paths in one large patch. Signed-off-by: Allison Henderson Reviewed-by: Brian Foster --- fs/xfs/libxfs/xfs_attr.c | 257 +++++++++++++++++++++++----------------- fs/xfs/libxfs/xfs_attr.h | 5 +- fs/xfs/libxfs/xfs_attr_leaf.c | 20 +++- fs/xfs/libxfs/xfs_attr_leaf.h | 8 +- fs/xfs/libxfs/xfs_attr_remote.c | 50 ++++---- fs/xfs/libxfs/xfs_attr_remote.h | 4 +- 6 files changed, 203 insertions(+), 141 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 3da6b0d..c50bbf6 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -49,15 +49,15 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args); * Internal routines when attribute list is one block. */ STATIC int xfs_attr_leaf_get(xfs_da_args_t *args); -STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args); -STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args); +STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args, bool roll_trans); +STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args, bool roll_trans); /* * Internal routines when attribute list is more than one block. */ STATIC int xfs_attr_node_get(xfs_da_args_t *args); -STATIC int xfs_attr_node_addname(xfs_da_args_t *args); -STATIC int xfs_attr_node_removename(xfs_da_args_t *args); +STATIC int xfs_attr_node_addname(xfs_da_args_t *args, bool roll_trans); +STATIC int xfs_attr_node_removename(xfs_da_args_t *args, bool roll_trans); STATIC int xfs_attr_fillstate(xfs_da_state_t *state); STATIC int xfs_attr_refillstate(xfs_da_state_t *state); @@ -196,11 +196,12 @@ xfs_attr_calc_size( STATIC int xfs_attr_try_sf_addname( struct xfs_inode *dp, - struct xfs_da_args *args) + struct xfs_da_args *args, + bool roll_trans) { struct xfs_mount *mp = dp->i_mount; - int error, error2; + int error, error2 = 0; error = xfs_attr_shortform_addname(args); if (error == -ENOSPC) @@ -216,8 +217,11 @@ xfs_attr_try_sf_addname( if (mp->m_flags & XFS_MOUNT_WSYNC) xfs_trans_set_sync(args->trans); - error2 = xfs_trans_commit(args->trans); - args->trans = NULL; + if (roll_trans) { + error2 = xfs_trans_commit(args->trans); + args->trans = NULL; + } + return error ? error : error2; } @@ -227,10 +231,11 @@ xfs_attr_try_sf_addname( int xfs_attr_set_args( struct xfs_da_args *args, - struct xfs_buf **leaf_bp) + struct xfs_buf **leaf_bp, + bool roll_trans) { struct xfs_inode *dp = args->dp; - int error; + int error = 0; /* * If the attribute list is non-existent or a shortform list, @@ -249,7 +254,7 @@ xfs_attr_set_args( /* * Try to add the attr to the attribute list in the inode. */ - error = xfs_attr_try_sf_addname(dp, args); + error = xfs_attr_try_sf_addname(dp, args, roll_trans); if (error != -ENOSPC) return error; @@ -261,33 +266,35 @@ xfs_attr_set_args( if (error) return error; - /* - * Prevent the leaf buffer from being unlocked so that a - * concurrent AIL push cannot grab the half-baked leaf - * buffer and run into problems with the write verifier. - */ - xfs_trans_bhold(args->trans, *leaf_bp); + if (roll_trans) { + /* + * Prevent the leaf buffer from being unlocked so that a + * concurrent AIL push cannot grab the half-baked leaf + * buffer and run into problems with the write verifier. + */ + xfs_trans_bhold(args->trans, *leaf_bp); - error = xfs_defer_finish(&args->trans); - if (error) - return error; + error = xfs_defer_finish(&args->trans); + if (error) + return error; - /* - * Commit the leaf transformation. We'll need another - * (linked) transaction to add the new attribute to the - * leaf. - */ - error = xfs_trans_roll_inode(&args->trans, dp); - if (error) - return error; - xfs_trans_bjoin(args->trans, *leaf_bp); - *leaf_bp = NULL; + /* + * Commit the leaf transformation. We'll need another + * (linked) transaction to add the new attribute to the + * leaf. + */ + error = xfs_trans_roll_inode(&args->trans, dp); + if (error) + return error; + xfs_trans_bjoin(args->trans, *leaf_bp); + *leaf_bp = NULL; + } } if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) - error = xfs_attr_leaf_addname(args); + error = xfs_attr_leaf_addname(args, roll_trans); else - error = xfs_attr_node_addname(args); + error = xfs_attr_node_addname(args, roll_trans); return error; } @@ -296,7 +303,8 @@ xfs_attr_set_args( */ int xfs_attr_remove_args( - struct xfs_da_args *args) + struct xfs_da_args *args, + bool roll_trans) { struct xfs_inode *dp = args->dp; int error; @@ -307,9 +315,9 @@ xfs_attr_remove_args( ASSERT(dp->i_afp->if_flags & XFS_IFINLINE); error = xfs_attr_shortform_remove(args); } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { - error = xfs_attr_leaf_removename(args); + error = xfs_attr_leaf_removename(args, roll_trans); } else { - error = xfs_attr_node_removename(args); + error = xfs_attr_node_removename(args, roll_trans); } return error; @@ -384,7 +392,7 @@ xfs_attr_set( goto out_trans_cancel; xfs_trans_ijoin(args.trans, dp, 0); - error = xfs_attr_set_args(&args, &leaf_bp); + error = xfs_attr_set_args(&args, &leaf_bp, true); if (error) goto out_release_leaf; if (!args.trans) { @@ -473,7 +481,8 @@ xfs_attr_remove( */ xfs_trans_ijoin(args.trans, dp, 0); - error = xfs_attr_remove_args(&args); + error = xfs_attr_remove_args(&args, true); + if (error) goto out; @@ -563,7 +572,8 @@ xfs_attr_shortform_addname(xfs_da_args_t *args) */ STATIC int xfs_attr_leaf_addname( - struct xfs_da_args *args) + struct xfs_da_args *args, + bool roll_trans) { struct xfs_inode *dp; struct xfs_buf *bp; @@ -628,32 +638,37 @@ xfs_attr_leaf_addname( error = xfs_attr3_leaf_to_node(args); if (error) return error; - 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; + if (roll_trans) { + 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; + } /* * Fob the whole rest of the problem off on the Btree code. */ - error = xfs_attr_node_addname(args); + error = xfs_attr_node_addname(args, roll_trans); return error; } - /* - * Commit the transaction that added the attr name so that - * later routines can manage their own transactions. - */ - error = xfs_trans_roll_inode(&args->trans, dp); - if (error) - return error; + if (roll_trans) { + /* + * Commit the transaction that added the attr name so that + * later routines can manage their own transactions. + */ + error = xfs_trans_roll_inode(&args->trans, dp); + if (error) + return error; + } /* * If there was an out-of-line value, allocate the blocks we @@ -662,7 +677,7 @@ xfs_attr_leaf_addname( * maximum size of a transaction and/or hit a deadlock. */ if (args->rmtblkno > 0) { - error = xfs_attr_rmtval_set(args); + error = xfs_attr_rmtval_set(args, roll_trans); if (error) return error; } @@ -678,7 +693,7 @@ xfs_attr_leaf_addname( * In a separate transaction, set the incomplete flag on the * "old" attr and clear the incomplete flag on the "new" attr. */ - error = xfs_attr3_leaf_flipflags(args); + error = xfs_attr3_leaf_flipflags(args, roll_trans); if (error) return error; @@ -692,7 +707,7 @@ xfs_attr_leaf_addname( args->rmtblkcnt = args->rmtblkcnt2; args->rmtvaluelen = args->rmtvaluelen2; if (args->rmtblkno) { - error = xfs_attr_rmtval_remove(args); + error = xfs_attr_rmtval_remove(args, roll_trans); if (error) return error; } @@ -716,21 +731,25 @@ xfs_attr_leaf_addname( /* bp is gone due to xfs_da_shrink_inode */ if (error) return error; - error = xfs_defer_finish(&args->trans); - if (error) - return error; + + if (roll_trans) { + error = xfs_defer_finish(&args->trans); + if (error) + return error; + } } /* * Commit the remove and start the next trans in series. */ - error = xfs_trans_roll_inode(&args->trans, dp); + if (roll_trans) + error = xfs_trans_roll_inode(&args->trans, dp); } else if (args->rmtblkno > 0) { /* * Added a "remote" value, just clear the incomplete flag. */ - error = xfs_attr3_leaf_clearflag(args); + error = xfs_attr3_leaf_clearflag(args, roll_trans); } return error; } @@ -743,7 +762,8 @@ xfs_attr_leaf_addname( */ STATIC int xfs_attr_leaf_removename( - struct xfs_da_args *args) + struct xfs_da_args *args, + bool roll_trans) { struct xfs_inode *dp; struct xfs_buf *bp; @@ -776,9 +796,12 @@ xfs_attr_leaf_removename( /* bp is gone due to xfs_da_shrink_inode */ if (error) return error; - error = xfs_defer_finish(&args->trans); - if (error) - return error; + + if (roll_trans) { + error = xfs_defer_finish(&args->trans); + if (error) + return error; + } } return 0; } @@ -831,7 +854,8 @@ xfs_attr_leaf_get(xfs_da_args_t *args) */ STATIC int xfs_attr_node_addname( - struct xfs_da_args *args) + struct xfs_da_args *args, + bool roll_trans) { struct xfs_da_state *state; struct xfs_da_state_blk *blk; @@ -899,17 +923,20 @@ xfs_attr_node_addname( error = xfs_attr3_leaf_to_node(args); if (error) goto out; - error = xfs_defer_finish(&args->trans); - if (error) - goto out; - /* - * Commit the node conversion and start the next - * trans in the chain. - */ - error = xfs_trans_roll_inode(&args->trans, dp); - if (error) - goto out; + if (roll_trans) { + error = xfs_defer_finish(&args->trans); + if (error) + goto out; + + /* + * Commit the node conversion and start the next + * trans in the chain. + */ + error = xfs_trans_roll_inode(&args->trans, dp); + if (error) + goto out; + } goto restart; } @@ -923,9 +950,13 @@ xfs_attr_node_addname( error = xfs_da3_split(state); if (error) goto out; - error = xfs_defer_finish(&args->trans); - if (error) - goto out; + + if (roll_trans) { + error = xfs_defer_finish(&args->trans); + if (error) + goto out; + } + } else { /* * Addition succeeded, update Btree hashvals. @@ -944,9 +975,11 @@ xfs_attr_node_addname( * Commit the leaf addition or btree split and start the next * trans in the chain. */ - error = xfs_trans_roll_inode(&args->trans, dp); - if (error) - goto out; + if (roll_trans) { + error = xfs_trans_roll_inode(&args->trans, dp); + if (error) + goto out; + } /* * If there was an out-of-line value, allocate the blocks we @@ -955,7 +988,7 @@ xfs_attr_node_addname( * maximum size of a transaction and/or hit a deadlock. */ if (args->rmtblkno > 0) { - error = xfs_attr_rmtval_set(args); + error = xfs_attr_rmtval_set(args, roll_trans); if (error) return error; } @@ -971,7 +1004,7 @@ xfs_attr_node_addname( * In a separate transaction, set the incomplete flag on the * "old" attr and clear the incomplete flag on the "new" attr. */ - error = xfs_attr3_leaf_flipflags(args); + error = xfs_attr3_leaf_flipflags(args, roll_trans); if (error) goto out; @@ -985,7 +1018,7 @@ xfs_attr_node_addname( args->rmtblkcnt = args->rmtblkcnt2; args->rmtvaluelen = args->rmtvaluelen2; if (args->rmtblkno) { - error = xfs_attr_rmtval_remove(args); + error = xfs_attr_rmtval_remove(args, roll_trans); if (error) return error; } @@ -1019,9 +1052,11 @@ xfs_attr_node_addname( error = xfs_da3_join(state); if (error) goto out; - error = xfs_defer_finish(&args->trans); - if (error) - goto out; + if (roll_trans) { + error = xfs_defer_finish(&args->trans); + if (error) + goto out; + } } /* @@ -1035,7 +1070,7 @@ xfs_attr_node_addname( /* * Added a "remote" value, just clear the incomplete flag. */ - error = xfs_attr3_leaf_clearflag(args); + error = xfs_attr3_leaf_clearflag(args, roll_trans); if (error) goto out; } @@ -1058,7 +1093,8 @@ xfs_attr_node_addname( */ STATIC int xfs_attr_node_removename( - struct xfs_da_args *args) + struct xfs_da_args *args, + bool roll_trans) { struct xfs_da_state *state; struct xfs_da_state_blk *blk; @@ -1108,10 +1144,10 @@ xfs_attr_node_removename( * Mark the attribute as INCOMPLETE, then bunmapi() the * remote value. */ - error = xfs_attr3_leaf_setflag(args); + error = xfs_attr3_leaf_setflag(args, roll_trans); if (error) goto out; - error = xfs_attr_rmtval_remove(args); + error = xfs_attr_rmtval_remove(args, roll_trans); if (error) goto out; @@ -1139,15 +1175,19 @@ xfs_attr_node_removename( error = xfs_da3_join(state); if (error) goto out; - error = xfs_defer_finish(&args->trans); - if (error) - goto out; - /* - * Commit the Btree join operation and start a new trans. - */ - error = xfs_trans_roll_inode(&args->trans, dp); - if (error) - goto out; + + if (roll_trans) { + error = xfs_defer_finish(&args->trans); + if (error) + goto out; + /* + * Commit the Btree join operation and start + * a new trans. + */ + error = xfs_trans_roll_inode(&args->trans, dp); + if (error) + goto out; + } } /* @@ -1170,9 +1210,12 @@ xfs_attr_node_removename( /* bp is gone due to xfs_da_shrink_inode */ if (error) goto out; - error = xfs_defer_finish(&args->trans); - if (error) - goto out; + + if (roll_trans) { + error = xfs_defer_finish(&args->trans); + if (error) + goto out; + } } else xfs_trans_brelse(args->trans, bp); } diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index 52f63dc..f0e91bf 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -142,10 +142,11 @@ int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name, int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name, size_t namelen, unsigned char *value, int valuelen, int flags); -int xfs_attr_set_args(struct xfs_da_args *args, struct xfs_buf **leaf_bp); +int xfs_attr_set_args(struct xfs_da_args *args, struct xfs_buf **leaf_bp, + bool roll_trans); int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, size_t namelen, int flags); -int xfs_attr_remove_args(struct xfs_da_args *args); +int xfs_attr_remove_args(struct xfs_da_args *args, bool roll_trans); int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize, int flags, struct attrlist_cursor_kern *cursor); bool xfs_attr_namecheck(const void *name, size_t length); diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 1f6e396..128bfe9 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -2637,7 +2637,8 @@ xfs_attr_leaf_newentsize( */ int xfs_attr3_leaf_clearflag( - struct xfs_da_args *args) + struct xfs_da_args *args, + bool roll_trans) { struct xfs_attr_leafblock *leaf; struct xfs_attr_leaf_entry *entry; @@ -2698,7 +2699,9 @@ xfs_attr3_leaf_clearflag( /* * Commit the flag value change and start the next trans in series. */ - return xfs_trans_roll_inode(&args->trans, args->dp); + if (roll_trans) + error = xfs_trans_roll_inode(&args->trans, args->dp); + return error; } /* @@ -2706,7 +2709,8 @@ xfs_attr3_leaf_clearflag( */ int xfs_attr3_leaf_setflag( - struct xfs_da_args *args) + struct xfs_da_args *args, + bool roll_trans) { struct xfs_attr_leafblock *leaf; struct xfs_attr_leaf_entry *entry; @@ -2749,7 +2753,9 @@ xfs_attr3_leaf_setflag( /* * Commit the flag value change and start the next trans in series. */ - return xfs_trans_roll_inode(&args->trans, args->dp); + if (roll_trans) + error = xfs_trans_roll_inode(&args->trans, args->dp); + return error; } /* @@ -2761,7 +2767,8 @@ xfs_attr3_leaf_setflag( */ int xfs_attr3_leaf_flipflags( - struct xfs_da_args *args) + struct xfs_da_args *args, + bool roll_trans) { struct xfs_attr_leafblock *leaf1; struct xfs_attr_leafblock *leaf2; @@ -2867,7 +2874,8 @@ xfs_attr3_leaf_flipflags( /* * Commit the flag value change and start the next trans in series. */ - error = xfs_trans_roll_inode(&args->trans, args->dp); + if (roll_trans) + error = xfs_trans_roll_inode(&args->trans, args->dp); return error; } diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h index 7b74e18..9d830ec 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.h +++ b/fs/xfs/libxfs/xfs_attr_leaf.h @@ -49,10 +49,10 @@ void xfs_attr_fork_remove(struct xfs_inode *ip, struct xfs_trans *tp); */ int xfs_attr3_leaf_to_node(struct xfs_da_args *args); int xfs_attr3_leaf_to_shortform(struct xfs_buf *bp, - struct xfs_da_args *args, int forkoff); -int xfs_attr3_leaf_clearflag(struct xfs_da_args *args); -int xfs_attr3_leaf_setflag(struct xfs_da_args *args); -int xfs_attr3_leaf_flipflags(struct xfs_da_args *args); + struct xfs_da_args *args, int forkoff); +int xfs_attr3_leaf_clearflag(struct xfs_da_args *args, bool roll_trans); +int xfs_attr3_leaf_setflag(struct xfs_da_args *args, bool roll_trans); +int xfs_attr3_leaf_flipflags(struct xfs_da_args *args, bool roll_trans); /* * Routines used for growing the Btree. diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 65ff600..18fbd22 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -435,7 +435,8 @@ xfs_attr_rmtval_get( */ int xfs_attr_rmtval_set( - struct xfs_da_args *args) + struct xfs_da_args *args, + bool roll_trans) { struct xfs_inode *dp = args->dp; struct xfs_mount *mp = dp->i_mount; @@ -488,9 +489,12 @@ xfs_attr_rmtval_set( &nmap); if (error) return error; - error = xfs_defer_finish(&args->trans); - if (error) - return error; + + if (roll_trans) { + error = xfs_defer_finish(&args->trans); + if (error) + return error; + } ASSERT(nmap == 1); ASSERT((map.br_startblock != DELAYSTARTBLOCK) && @@ -498,12 +502,14 @@ xfs_attr_rmtval_set( lblkno += map.br_blockcount; blkcnt -= map.br_blockcount; - /* - * Start the next trans in the chain. - */ - error = xfs_trans_roll_inode(&args->trans, dp); - if (error) - return error; + if (roll_trans) { + /* + * Start the next trans in the chain. + */ + error = xfs_trans_roll_inode(&args->trans, dp); + if (error) + return error; + } } /* @@ -563,7 +569,8 @@ xfs_attr_rmtval_set( */ int xfs_attr_rmtval_remove( - struct xfs_da_args *args) + struct xfs_da_args *args, + bool roll_trans) { struct xfs_mount *mp = args->dp->i_mount; xfs_dablk_t lblkno; @@ -625,16 +632,19 @@ xfs_attr_rmtval_remove( XFS_BMAPI_ATTRFORK, 1, &done); if (error) return error; - error = xfs_defer_finish(&args->trans); - if (error) - return error; - /* - * Close out trans and start the next one in the chain. - */ - error = xfs_trans_roll_inode(&args->trans, args->dp); - if (error) - return error; + if (roll_trans) { + error = xfs_defer_finish(&args->trans); + if (error) + return error; + + /* + * Close out trans and start the next one in the chain. + */ + error = xfs_trans_roll_inode(&args->trans, args->dp); + if (error) + return error; + } } return 0; } diff --git a/fs/xfs/libxfs/xfs_attr_remote.h b/fs/xfs/libxfs/xfs_attr_remote.h index 9d20b66..c7c073d 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.h +++ b/fs/xfs/libxfs/xfs_attr_remote.h @@ -9,7 +9,7 @@ int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen); int xfs_attr_rmtval_get(struct xfs_da_args *args); -int xfs_attr_rmtval_set(struct xfs_da_args *args); -int xfs_attr_rmtval_remove(struct xfs_da_args *args); +int xfs_attr_rmtval_set(struct xfs_da_args *args, bool roll_trans); +int xfs_attr_rmtval_remove(struct xfs_da_args *args, bool roll_trans); #endif /* __XFS_ATTR_REMOTE_H__ */ From patchwork Fri Apr 12 22:50:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Allison Henderson X-Patchwork-Id: 10899211 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4932213B5 for ; Fri, 12 Apr 2019 22:52:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2FA4B288BE for ; Fri, 12 Apr 2019 22:52:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 23BF328F21; Fri, 12 Apr 2019 22:52:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1F2FD288BE for ; Fri, 12 Apr 2019 22:52:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726983AbfDLWwx (ORCPT ); Fri, 12 Apr 2019 18:52:53 -0400 Received: from aserp2130.oracle.com ([141.146.126.79]:44194 "EHLO aserp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726936AbfDLWwx (ORCPT ); Fri, 12 Apr 2019 18:52:53 -0400 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMeEmZ015764 for ; Fri, 12 Apr 2019 22:52:47 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=TPRUsbHpufl5yAQD4pFnRf7Lyrxet3yyfad6psI8Fys=; b=tXaBud3gxXZ9ZCuoFaHFkkQLHRMiOVbQBEqC3MdIqRa9WtikSW4+qSQz5DMS35dAIqUm W6Mhv0A5aEwLqS9zh+TkC8wjIXfaYPN5hMV0dANlryo995EjvHH2p4ptPcRnVZjXO1pT C6+4VkC7WQh9EWdn29wFkVlrf3WWX81gi6ymS33gjJ+poLyUmmBy+zb+Fp7uEBY61u1/ h+rc7d78dExmYYOUvQ+8R6TCY85QIuX/Q5mhzS4eurU+PkY/yNf21q2nAm5UF3akVjhO OlJaCxgGBT/Ulfwr2+awuPlZlCOdyzqOKRnQ32js4wvxDQAY2imQQ14SK46C3YqjjZDE jA== Received: from aserp3030.oracle.com (aserp3030.oracle.com [141.146.126.71]) by aserp2130.oracle.com with ESMTP id 2rphmf0yp6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:47 +0000 Received: from pps.filterd (aserp3030.oracle.com [127.0.0.1]) by aserp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMphfW144278 for ; Fri, 12 Apr 2019 22:52:46 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserp3030.oracle.com with ESMTP id 2rt9uqcvkt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:46 +0000 Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x3CMqkC4002536 for ; Fri, 12 Apr 2019 22:52:46 GMT Received: from localhost.localdomain (/70.176.225.12) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 12 Apr 2019 15:52:45 -0700 From: Allison Henderson To: linux-xfs@vger.kernel.org Subject: [PATCH 4/9] xfs: Set up infastructure for deferred attribute operations Date: Fri, 12 Apr 2019 15:50:31 -0700 Message-Id: <20190412225036.22939-5-allison.henderson@oracle.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190412225036.22939-1-allison.henderson@oracle.com> References: <20190412225036.22939-1-allison.henderson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=4 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds two new log item types for setting or removing attributes as deferred operations. The xfs_attri_log_item logs an intent to set or remove an attribute. The corresponding xfs_attrd_log_item holds a reference to the xfs_attri_log_item and is freed once the transaction is done. Both log items use a generic xfs_attr_log_format structure that contains the attribute name, value, flags, inode, and an op_flag that indicates if the operations is a set or remove. Signed-off-by: Allison Henderson --- fs/xfs/Makefile | 2 + fs/xfs/libxfs/xfs_attr.c | 5 +- fs/xfs/libxfs/xfs_attr.h | 25 ++ fs/xfs/libxfs/xfs_defer.c | 1 + fs/xfs/libxfs/xfs_defer.h | 3 + fs/xfs/libxfs/xfs_log_format.h | 44 +++- fs/xfs/libxfs/xfs_types.h | 1 + fs/xfs/xfs_attr_item.c | 558 +++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_attr_item.h | 103 ++++++++ fs/xfs/xfs_log_recover.c | 172 +++++++++++++ fs/xfs/xfs_ondisk.h | 2 + fs/xfs/xfs_trans.h | 10 + fs/xfs/xfs_trans_attr.c | 240 ++++++++++++++++++ 13 files changed, 1162 insertions(+), 4 deletions(-) diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 7f96bda..022e0b4 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -97,6 +97,7 @@ xfs-y += xfs_log.o \ xfs_bmap_item.o \ xfs_buf_item.o \ xfs_extfree_item.o \ + xfs_attr_item.o \ xfs_icreate_item.o \ xfs_inode_item.o \ xfs_refcount_item.o \ @@ -106,6 +107,7 @@ xfs-y += xfs_log.o \ xfs_trans_bmap.o \ xfs_trans_buf.o \ xfs_trans_extfree.o \ + xfs_trans_attr.o \ xfs_trans_inode.o \ xfs_trans_refcount.o \ xfs_trans_rmap.o \ diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index c50bbf6..fadd485 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -29,6 +29,7 @@ #include "xfs_quota.h" #include "xfs_trans_space.h" #include "xfs_trace.h" +#include "xfs_attr_item.h" /* * xfs_attr.c @@ -62,7 +63,7 @@ STATIC int xfs_attr_fillstate(xfs_da_state_t *state); STATIC int xfs_attr_refillstate(xfs_da_state_t *state); -STATIC int +int xfs_attr_args_init( struct xfs_da_args *args, struct xfs_inode *dp, @@ -160,7 +161,7 @@ xfs_attr_get( /* * Calculate how many blocks we need for the new attribute, */ -STATIC int +int xfs_attr_calc_size( struct xfs_da_args *args, int *local) diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index f0e91bf..92d9a15 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -78,6 +78,28 @@ typedef struct attrlist_ent { /* data from attr_list() */ } attrlist_ent_t; /* + * List of attrs to commit later. + */ +struct xfs_attr_item { + struct xfs_inode *xattri_ip; + uint32_t xattri_op_flags; + void *xattri_value; /* attr value */ + uint32_t xattri_value_len; /* length of value */ + void *xattri_name; /* attr name */ + uint32_t xattri_name_len; /* length of name */ + uint32_t xattri_flags; /* attr flags */ + struct list_head xattri_list; + + /* + * A byte array follows the header containing the file name and + * attribute value. + */ +}; + +#define XFS_ATTR_ITEM_SIZEOF(namelen, valuelen) \ + (sizeof(struct xfs_attr_item) + (namelen) + (valuelen)) + +/* * Given a pointer to the (char*) buffer containing the attr_list() result, * and an index, return a pointer to the indicated attribute in the buffer. */ @@ -150,5 +172,8 @@ int xfs_attr_remove_args(struct xfs_da_args *args, bool roll_trans); int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize, int flags, struct attrlist_cursor_kern *cursor); bool xfs_attr_namecheck(const void *name, size_t length); +int xfs_attr_args_init(struct xfs_da_args *args, struct xfs_inode *dp, + const unsigned char *name, size_t namelen, int flags); +int xfs_attr_calc_size(struct xfs_da_args *args, int *local); #endif /* __XFS_ATTR_H__ */ diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index 94f0042..fb444bd 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -178,6 +178,7 @@ static const struct xfs_defer_op_type *defer_op_types[] = { [XFS_DEFER_OPS_TYPE_RMAP] = &xfs_rmap_update_defer_type, [XFS_DEFER_OPS_TYPE_FREE] = &xfs_extent_free_defer_type, [XFS_DEFER_OPS_TYPE_AGFL_FREE] = &xfs_agfl_free_defer_type, + [XFS_DEFER_OPS_TYPE_ATTR] = &xfs_attr_defer_type, }; /* diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index 7c28d76..b9ff7b9 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h @@ -17,6 +17,7 @@ enum xfs_defer_ops_type { XFS_DEFER_OPS_TYPE_RMAP, XFS_DEFER_OPS_TYPE_FREE, XFS_DEFER_OPS_TYPE_AGFL_FREE, + XFS_DEFER_OPS_TYPE_ATTR, XFS_DEFER_OPS_TYPE_MAX, }; @@ -60,5 +61,7 @@ extern const struct xfs_defer_op_type xfs_refcount_update_defer_type; extern const struct xfs_defer_op_type xfs_rmap_update_defer_type; extern const struct xfs_defer_op_type xfs_extent_free_defer_type; extern const struct xfs_defer_op_type xfs_agfl_free_defer_type; +extern const struct xfs_defer_op_type xfs_attr_defer_type; + #endif /* __XFS_DEFER_H__ */ diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h index e5f97c6..76d42e6 100644 --- a/fs/xfs/libxfs/xfs_log_format.h +++ b/fs/xfs/libxfs/xfs_log_format.h @@ -117,7 +117,12 @@ struct xfs_unmount_log_format { #define XLOG_REG_TYPE_CUD_FORMAT 24 #define XLOG_REG_TYPE_BUI_FORMAT 25 #define XLOG_REG_TYPE_BUD_FORMAT 26 -#define XLOG_REG_TYPE_MAX 26 +#define XLOG_REG_TYPE_ATTRI_FORMAT 27 +#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 31 + /* * Flags to log operation header @@ -240,6 +245,8 @@ typedef struct xfs_trans_header { #define XFS_LI_CUD 0x1243 #define XFS_LI_BUI 0x1244 /* bmbt update intent */ #define XFS_LI_BUD 0x1245 +#define XFS_LI_ATTRI 0x1246 /* attr set/remove intent*/ +#define XFS_LI_ATTRD 0x1247 /* attr set/remove done */ #define XFS_LI_TYPE_DESC \ { XFS_LI_EFI, "XFS_LI_EFI" }, \ @@ -255,7 +262,9 @@ typedef struct xfs_trans_header { { XFS_LI_CUI, "XFS_LI_CUI" }, \ { XFS_LI_CUD, "XFS_LI_CUD" }, \ { XFS_LI_BUI, "XFS_LI_BUI" }, \ - { XFS_LI_BUD, "XFS_LI_BUD" } + { XFS_LI_BUD, "XFS_LI_BUD" }, \ + { XFS_LI_ATTRI, "XFS_LI_ATTRI" }, \ + { XFS_LI_ATTRD, "XFS_LI_ATTRD" } /* * Inode Log Item Format definitions. @@ -853,4 +862,35 @@ struct xfs_icreate_log { __be32 icl_gen; /* inode generation number to use */ }; +/* + * Flags for deferred attribute operations. + * Upper bits are flags, lower byte is type code + */ +#define XFS_ATTR_OP_FLAGS_SET 1 /* Set the attribute */ +#define XFS_ATTR_OP_FLAGS_REMOVE 2 /* Remove the attribute */ +#define XFS_ATTR_OP_FLAGS_TYPE_MASK 0x0FF /* Flags type mask */ + +/* + * This is the structure used to lay out an attr log item in the + * 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 */ + uint64_t alfi_id; /* attri identifier */ + xfs_ino_t alfi_ino; /* the inode for this attr operation */ + uint32_t alfi_op_flags; /* marks the op as a set or remove */ + uint32_t alfi_name_len; /* attr name length */ + uint32_t alfi_value_len; /* attr value length */ + uint32_t alfi_attr_flags;/* attr flags */ +}; + +struct xfs_attrd_log_format { + uint16_t alfd_type; /* attrd log item type */ + uint16_t alfd_size; /* size of this item */ + uint32_t __pad; /* pad to 64 bit aligned */ + uint64_t alfd_alf_id; /* id of corresponding attrd */ +}; + #endif /* __XFS_LOG_FORMAT_H__ */ diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index c5a2540..15e928a 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h @@ -11,6 +11,7 @@ typedef uint32_t prid_t; /* project ID */ typedef uint32_t xfs_agblock_t; /* blockno in alloc. group */ typedef uint32_t xfs_agino_t; /* inode # within allocation grp */ typedef uint32_t xfs_extlen_t; /* extent length in blocks */ +typedef uint32_t xfs_attrlen_t; /* attr length */ typedef uint32_t xfs_agnumber_t; /* allocation group number */ typedef int32_t xfs_extnum_t; /* # of extents in a file */ typedef int16_t xfs_aextnum_t; /* # extents in an attribute fork */ diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c new file mode 100644 index 0000000..0ea19b4 --- /dev/null +++ b/fs/xfs/xfs_attr_item.c @@ -0,0 +1,558 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Oracle. All Rights Reserved. + * Author: Allison Henderson + */ +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_bit.h" +#include "xfs_mount.h" +#include "xfs_trans.h" +#include "xfs_trans_priv.h" +#include "xfs_buf_item.h" +#include "xfs_attr_item.h" +#include "xfs_log.h" +#include "xfs_btree.h" +#include "xfs_rmap.h" +#include "xfs_inode.h" +#include "xfs_icache.h" +#include "xfs_attr.h" +#include "xfs_shared.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" + +static inline struct xfs_attri_log_item *ATTRI_ITEM(struct xfs_log_item *lip) +{ + return container_of(lip, struct xfs_attri_log_item, item); +} + +void +xfs_attri_item_free( + struct xfs_attri_log_item *attrip) +{ + kmem_free(attrip->item.li_lv_shadow); + kmem_free(attrip); +} + +/* + * This returns the number of iovecs needed to log the given attri item. + * We only need 1 iovec for an attri item. It just logs the attr_log_format + * structure. + */ +static inline int +xfs_attri_item_sizeof( + struct xfs_attri_log_item *attrip) +{ + return sizeof(struct xfs_attri_log_format); +} + +STATIC void +xfs_attri_item_size( + struct xfs_log_item *lip, + int *nvecs, + int *nbytes) +{ + struct xfs_attri_log_item *attrip = ATTRI_ITEM(lip); + + *nvecs += 1; + *nbytes += xfs_attri_item_sizeof(attrip); + + if (attrip->name_len > 0) { + *nvecs += 1; + *nbytes += ATTR_NVEC_SIZE(attrip->name_len); + } + + if (attrip->value_len > 0) { + *nvecs += 1; + *nbytes += ATTR_NVEC_SIZE(attrip->value_len); + } +} + +/* + * This is called to fill in the vector of log iovecs for the + * given attri log item. We use only 1 iovec, and we point that + * at the attri_log_format structure embedded in the attri item. + * It is at this point that we assert that all of the attr + * slots in the attri item have been filled. + */ +STATIC void +xfs_attri_item_format( + struct xfs_log_item *lip, + struct xfs_log_vec *lv) +{ + struct xfs_attri_log_item *attrip = ATTRI_ITEM(lip); + struct xfs_log_iovec *vecp = NULL; + + attrip->format.alfi_type = XFS_LI_ATTRI; + attrip->format.alfi_size = 1; + if (attrip->name_len > 0) + attrip->format.alfi_size++; + if (attrip->value_len > 0) + attrip->format.alfi_size++; + + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTRI_FORMAT, + &attrip->format, + xfs_attri_item_sizeof(attrip)); + if (attrip->name_len > 0) + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTR_NAME, + attrip->name, ATTR_NVEC_SIZE(attrip->name_len)); + + if (attrip->value_len > 0) + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTR_VALUE, + attrip->value, + ATTR_NVEC_SIZE(attrip->value_len)); +} + + +/* + * Pinning has no meaning for an attri item, so just return. + */ +STATIC void +xfs_attri_item_pin( + struct xfs_log_item *lip) +{ +} + +/* + * The unpin operation is the last place an ATTRI is manipulated in the log. It + * is either inserted in the AIL or aborted in the event of a log I/O error. In + * either case, the ATTRI transaction has been successfully committed to make it + * this far. Therefore, we expect whoever committed the ATTRI to either + * construct and commit the ATTRD or drop the ATTRD's reference in the event of + * error. Simply drop the log's ATTRI reference now that the log is done with + * it. + */ +STATIC void +xfs_attri_item_unpin( + struct xfs_log_item *lip, + int remove) +{ + struct xfs_attri_log_item *attrip = ATTRI_ITEM(lip); + + xfs_attri_release(attrip); +} + +/* + * attri items have no locking or pushing. However, since ATTRIs are pulled + * from the AIL when their corresponding ATTRDs are committed to disk, their + * situation is very similar to being pinned. Return XFS_ITEM_PINNED so that + * the caller will eventually flush the log. This should help in getting the + * ATTRI out of the AIL. + */ +STATIC uint +xfs_attri_item_push( + struct xfs_log_item *lip, + struct list_head *buffer_list) +{ + return XFS_ITEM_PINNED; +} + +/* + * The ATTRI has been either committed or aborted if the transaction has been + * cancelled. If the transaction was cancelled, an ATTRD isn't going to be + * constructed and thus we free the ATTRI here directly. + */ +STATIC void +xfs_attri_item_unlock( + struct xfs_log_item *lip) +{ + if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) + xfs_attri_release(ATTRI_ITEM(lip)); +} + +/* + * The ATTRI is logged only once and cannot be moved in the log, so simply + * return the lsn at which it's been logged. + */ +STATIC xfs_lsn_t +xfs_attri_item_committed( + struct xfs_log_item *lip, + xfs_lsn_t lsn) +{ + return lsn; +} + +STATIC void +xfs_attri_item_committing( + struct xfs_log_item *lip, + xfs_lsn_t lsn) +{ +} + +/* + * This is the ops vector shared by all attri log items. + */ +static const struct xfs_item_ops xfs_attri_item_ops = { + .iop_size = xfs_attri_item_size, + .iop_format = xfs_attri_item_format, + .iop_pin = xfs_attri_item_pin, + .iop_unpin = xfs_attri_item_unpin, + .iop_unlock = xfs_attri_item_unlock, + .iop_committed = xfs_attri_item_committed, + .iop_push = xfs_attri_item_push, + .iop_committing = xfs_attri_item_committing +}; + + +/* + * Allocate and initialize an attri item + */ +struct xfs_attri_log_item * +xfs_attri_init( + struct xfs_mount *mp) + +{ + struct xfs_attri_log_item *attrip; + uint size; + + size = (uint)(sizeof(struct xfs_attri_log_item)); + attrip = kmem_zalloc(size, KM_SLEEP); + + xfs_log_item_init(mp, &(attrip->item), XFS_LI_ATTRI, + &xfs_attri_item_ops); + attrip->format.alfi_id = (uintptr_t)(void *)attrip; + atomic_set(&attrip->refcount, 2); + + return attrip; +} + +/* + * Copy an attr format buffer from the given buf, and into the destination + * attr format structure. + */ +int +xfs_attri_copy_format(struct xfs_log_iovec *buf, + struct xfs_attri_log_format *dst_attr_fmt) +{ + struct xfs_attri_log_format *src_attr_fmt = buf->i_addr; + uint len = sizeof(struct xfs_attri_log_format); + + if (buf->i_len == len) { + memcpy((char *)dst_attr_fmt, (char *)src_attr_fmt, len); + return 0; + } + return -EFSCORRUPTED; +} + +/* + * Copy an attr format buffer from the given buf, and into the destination + * attr format structure. + */ +int +xfs_attrd_copy_format(struct xfs_log_iovec *buf, + struct xfs_attrd_log_format *dst_attr_fmt) +{ + struct xfs_attrd_log_format *src_attr_fmt = buf->i_addr; + uint len = sizeof(struct xfs_attrd_log_format); + + if (buf->i_len == len) { + memcpy((char *)dst_attr_fmt, (char *)src_attr_fmt, len); + return 0; + } + return -EFSCORRUPTED; +} + +/* + * Freeing the attrip requires that we remove it from the AIL if it has already + * been placed there. However, the ATTRI may not yet have been placed in the + * AIL when called by xfs_attri_release() from ATTRD processing due to the + * ordering of committed vs unpin operations in bulk insert operations. Hence + * the reference count to ensure only the last caller frees the ATTRI. + */ +void +xfs_attri_release( + struct xfs_attri_log_item *attrip) +{ + ASSERT(atomic_read(&attrip->refcount) > 0); + if (atomic_dec_and_test(&attrip->refcount)) { + xfs_trans_ail_remove(&attrip->item, SHUTDOWN_LOG_IO_ERROR); + xfs_attri_item_free(attrip); + } +} + +static inline struct xfs_attrd_log_item *ATTRD_ITEM(struct xfs_log_item *lip) +{ + return container_of(lip, struct xfs_attrd_log_item, item); +} + +STATIC void +xfs_attrd_item_free(struct xfs_attrd_log_item *attrdp) +{ + kmem_free(attrdp->item.li_lv_shadow); + kmem_free(attrdp); +} + +/* + * This returns the number of iovecs needed to log the given attrd item. + * We only need 1 iovec for an attrd item. It just logs the attr_log_format + * structure. + */ +static inline int +xfs_attrd_item_sizeof( + struct xfs_attrd_log_item *attrdp) +{ + return sizeof(struct xfs_attrd_log_format); +} + +STATIC void +xfs_attrd_item_size( + struct xfs_log_item *lip, + int *nvecs, + int *nbytes) +{ + struct xfs_attrd_log_item *attrdp = ATTRD_ITEM(lip); + *nvecs += 1; + *nbytes += xfs_attrd_item_sizeof(attrdp); +} + +/* + * This is called to fill in the vector of log iovecs for the + * given attrd log item. We use only 1 iovec, and we point that + * at the attr_log_format structure embedded in the attrd item. + * It is at this point that we assert that all of the attr + * slots in the attrd item have been filled. + */ +STATIC void +xfs_attrd_item_format( + struct xfs_log_item *lip, + struct xfs_log_vec *lv) +{ + struct xfs_attrd_log_item *attrdp = ATTRD_ITEM(lip); + struct xfs_log_iovec *vecp = NULL; + + attrdp->format.alfd_type = XFS_LI_ATTRD; + attrdp->format.alfd_size = 1; + + xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTRD_FORMAT, + &attrdp->format, + xfs_attrd_item_sizeof(attrdp)); +} + +/* + * Pinning has no meaning for an attrd item, so just return. + */ +STATIC void +xfs_attrd_item_pin( + struct xfs_log_item *lip) +{ +} + +/* + * Since pinning has no meaning for an attrd item, unpinning does + * not either. + */ +STATIC void +xfs_attrd_item_unpin( + struct xfs_log_item *lip, + int remove) +{ +} + +/* + * There isn't much you can do to push on an attrd item. It is simply stuck + * waiting for the log to be flushed to disk. + */ +STATIC uint +xfs_attrd_item_push( + struct xfs_log_item *lip, + struct list_head *buffer_list) +{ + return XFS_ITEM_PINNED; +} + +/* + * The ATTRD is either committed or aborted if the transaction is cancelled. If + * the transaction is cancelled, drop our reference to the ATTRI and free the + * ATTRD. + */ +STATIC void +xfs_attrd_item_unlock( + struct xfs_log_item *lip) +{ + struct xfs_attrd_log_item *attrdp = ATTRD_ITEM(lip); + + if (test_bit(XFS_LI_ABORTED, &lip->li_flags)) { + xfs_attri_release(attrdp->attrip); + xfs_attrd_item_free(attrdp); + } +} + +/* + * When the attrd item is committed to disk, all we need to do is delete our + * reference to our partner attri item and then free ourselves. Since we're + * freeing ourselves we must return -1 to keep the transaction code from + * further referencing this item. + */ +STATIC xfs_lsn_t +xfs_attrd_item_committed( + struct xfs_log_item *lip, + xfs_lsn_t lsn) +{ + struct xfs_attrd_log_item *attrdp = ATTRD_ITEM(lip); + + /* + * Drop the ATTRI reference regardless of whether the ATTRD has been + * aborted. Once the ATTRD transaction is constructed, it is the sole + * responsibility of the ATTRD to release the ATTRI (even if the ATTRI + * is aborted due to log I/O error). + */ + xfs_attri_release(attrdp->attrip); + xfs_attrd_item_free(attrdp); + + return (xfs_lsn_t)-1; +} + +STATIC void +xfs_attrd_item_committing( + struct xfs_log_item *lip, + xfs_lsn_t lsn) +{ +} + +/* + * This is the ops vector shared by all attrd log items. + */ +static const struct xfs_item_ops xfs_attrd_item_ops = { + .iop_size = xfs_attrd_item_size, + .iop_format = xfs_attrd_item_format, + .iop_pin = xfs_attrd_item_pin, + .iop_unpin = xfs_attrd_item_unpin, + .iop_unlock = xfs_attrd_item_unlock, + .iop_committed = xfs_attrd_item_committed, + .iop_push = xfs_attrd_item_push, + .iop_committing = xfs_attrd_item_committing +}; + +/* + * Allocate and initialize an attrd item + */ +struct xfs_attrd_log_item * +xfs_attrd_init( + struct xfs_mount *mp, + struct xfs_attri_log_item *attrip) + +{ + struct xfs_attrd_log_item *attrdp; + uint size; + + size = (uint)(sizeof(struct xfs_attrd_log_item)); + attrdp = kmem_zalloc(size, KM_SLEEP); + + xfs_log_item_init(mp, &attrdp->item, XFS_LI_ATTRD, + &xfs_attrd_item_ops); + attrdp->attrip = attrip; + attrdp->format.alfd_alf_id = attrip->format.alfi_id; + + return attrdp; +} + +/* + * Process an attr intent item that was recovered from + * the log. We need to delete the attr that it describes. + */ +int +xfs_attri_recover( + struct xfs_mount *mp, + struct xfs_attri_log_item *attrip) +{ + struct xfs_inode *ip; + struct xfs_attrd_log_item *attrdp; + struct xfs_da_args args; + struct xfs_attri_log_format *attrp; + struct xfs_trans_res tres; + int local; + int error = 0; + int rsvd = 0; + + ASSERT(!test_bit(XFS_ATTRI_RECOVERED, &attrip->flags)); + + /* + * First check the validity of the attr described by the + * ATTRI. If any are bad, then assume that all are bad and + * just toss the ATTRI. + */ + attrp = &attrip->format; + if ( + /* + * Must have either XFS_ATTR_OP_FLAGS_SET or + * XFS_ATTR_OP_FLAGS_REMOVE set + */ + !(attrp->alfi_op_flags == XFS_ATTR_OP_FLAGS_SET || + attrp->alfi_op_flags == XFS_ATTR_OP_FLAGS_REMOVE) || + + /* Check size of value and name lengths */ + (attrp->alfi_value_len > XATTR_SIZE_MAX || + attrp->alfi_name_len > XATTR_NAME_MAX) || + + /* + * If the XFS_ATTR_OP_FLAGS_SET flag is set, + * there must also be a name and value + */ + (attrp->alfi_op_flags == XFS_ATTR_OP_FLAGS_SET && + (attrp->alfi_value_len == 0 || attrp->alfi_name_len == 0)) || + + /* + * If the XFS_ATTR_OP_FLAGS_REMOVE flag is set, + * there must also be a name + */ + (attrp->alfi_op_flags == XFS_ATTR_OP_FLAGS_REMOVE && + (attrp->alfi_name_len == 0)) + ) { + /* + * This will pull the ATTRI from the AIL and + * free the memory associated with it. + */ + set_bit(XFS_ATTRI_RECOVERED, &attrip->flags); + xfs_attri_release(attrip); + return -EIO; + } + + attrp = &attrip->format; + error = xfs_iget(mp, 0, attrp->alfi_ino, 0, 0, &ip); + if (error) + return error; + + error = xfs_attr_args_init(&args, ip, attrip->name, + attrp->alfi_name_len, attrp->alfi_attr_flags); + if (error) + return error; + + args.hashval = xfs_da_hashname(args.name, args.namelen); + args.value = attrip->value; + args.valuelen = attrp->alfi_value_len; + args.op_flags = XFS_DA_OP_OKNOENT; + args.total = xfs_attr_calc_size(&args, &local); + + tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres + + M_RES(mp)->tr_attrsetrt.tr_logres * args.total; + tres.tr_logcount = XFS_ATTRSET_LOG_COUNT; + tres.tr_logflags = XFS_TRANS_PERM_LOG_RES; + + error = xfs_trans_alloc(mp, &tres, args.total, 0, + rsvd ? XFS_TRANS_RESERVE : 0, &args.trans); + if (error) + return error; + attrdp = xfs_trans_get_attrd(args.trans, attrip); + + xfs_ilock(ip, XFS_ILOCK_EXCL); + + xfs_trans_ijoin(args.trans, ip, 0); + error = xfs_trans_attr(&args, attrdp, attrp->alfi_op_flags); + if (error) + goto abort_error; + + + set_bit(XFS_ATTRI_RECOVERED, &attrip->flags); + xfs_trans_log_inode(args.trans, ip, XFS_ILOG_CORE | XFS_ILOG_ADATA); + error = xfs_trans_commit(args.trans); + xfs_iunlock(ip, XFS_ILOCK_EXCL); + return error; + +abort_error: + xfs_trans_cancel(args.trans); + xfs_iunlock(ip, XFS_ILOCK_EXCL); + return error; +} diff --git a/fs/xfs/xfs_attr_item.h b/fs/xfs/xfs_attr_item.h new file mode 100644 index 0000000..fce7515 --- /dev/null +++ b/fs/xfs/xfs_attr_item.h @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Oracle. All Rights Reserved. + * Author: Allison Henderson + */ +#ifndef __XFS_ATTR_ITEM_H__ +#define __XFS_ATTR_ITEM_H__ + +/* kernel only ATTRI/ATTRD definitions */ + +struct xfs_mount; +struct kmem_zone; + +/* + * Max number of attrs in fast allocation path. + */ +#define XFS_ATTRI_MAX_FAST_ATTRS 1 + + +/* + * Define ATTR flag bits. Manipulated by set/clear/test_bit operators. + */ +#define XFS_ATTRI_RECOVERED 1 + + +/* nvecs must be in multiples of 4 */ +#define ATTR_NVEC_SIZE(size) (size == sizeof(int32_t) ? sizeof(int32_t) : \ + size + sizeof(int32_t) - \ + (size % sizeof(int32_t))) + +/* + * This is the "attr intention" log item. It is used to log the fact + * that some attrs need to be processed. It is used in conjunction with the + * "attr done" log item described below. + * + * The ATTRI is reference counted so that it is not freed prior to both the + * ATTRI and ATTRD being committed and unpinned. This ensures the ATTRI is + * inserted into the AIL even in the event of out of order ATTRI/ATTRD + * processing. In other words, an ATTRI is born with two references: + * + * 1.) an ATTRI held reference to track ATTRI AIL insertion + * 2.) an ATTRD held reference to track ATTRD commit + * + * On allocation, both references are the responsibility of the caller. Once + * the ATTRI is added to and dirtied in a transaction, ownership of reference + * one transfers to the transaction. The reference is dropped once the ATTRI is + * inserted to the AIL or in the event of failure along the way (e.g., commit + * failure, log I/O error, etc.). Note that the caller remains responsible for + * the ATTRD reference under all circumstances to this point. The caller has no + * means to detect failure once the transaction is committed, however. + * Therefore, an ATTRD is required after this point, even in the event of + * unrelated failure. + * + * Once an ATTRD is allocated and dirtied in a transaction, reference two + * transfers to the transaction. The ATTRD reference is dropped once it reaches + * the unpin handler. Similar to the ATTRI, the reference also drops in the + * event of commit failure or log I/O errors. Note that the ATTRD is not + * inserted in the AIL, so at this point both the ATTI and ATTRD are freed. + */ +struct xfs_attri_log_item { + xfs_log_item_t item; + atomic_t refcount; + unsigned long flags; /* misc flags */ + int name_len; + void *name; + int value_len; + void *value; + struct xfs_attri_log_format format; +}; + +/* + * This is the "attr done" log item. It is used to log + * the fact that some attrs earlier mentioned in an attri item + * have been freed. + */ +struct xfs_attrd_log_item { + struct xfs_log_item item; + struct xfs_attri_log_item *attrip; + struct xfs_attrd_log_format format; +}; + +/* + * Max number of attrs in fast allocation path. + */ +#define XFS_ATTRD_MAX_FAST_ATTRS 1 + +extern struct kmem_zone *xfs_attri_zone; +extern struct kmem_zone *xfs_attrd_zone; + +struct xfs_attri_log_item *xfs_attri_init(struct xfs_mount *mp); +struct xfs_attrd_log_item *xfs_attrd_init(struct xfs_mount *mp, + struct xfs_attri_log_item *attrip); +int xfs_attri_copy_format(struct xfs_log_iovec *buf, + struct xfs_attri_log_format *dst_attri_fmt); +int xfs_attrd_copy_format(struct xfs_log_iovec *buf, + struct xfs_attrd_log_format *dst_attrd_fmt); +void xfs_attri_item_free(struct xfs_attri_log_item *attrip); +void xfs_attri_release(struct xfs_attri_log_item *attrip); + +int xfs_attri_recover(struct xfs_mount *mp, + struct xfs_attri_log_item *attrip); + +#endif /* __XFS_ATTR_ITEM_H__ */ diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 3371d1f..101ab5e 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -22,6 +22,7 @@ #include "xfs_log_recover.h" #include "xfs_inode_item.h" #include "xfs_extfree_item.h" +#include "xfs_attr_item.h" #include "xfs_trans_priv.h" #include "xfs_alloc.h" #include "xfs_ialloc.h" @@ -1965,6 +1966,8 @@ xlog_recover_reorder_trans( case XFS_LI_CUD: case XFS_LI_BUI: case XFS_LI_BUD: + case XFS_LI_ATTRI: + case XFS_LI_ATTRD: trace_xfs_log_recover_item_reorder_tail(log, trans, item, pass); list_move_tail(&item->ri_list, &inode_list); @@ -3504,6 +3507,117 @@ xlog_recover_efd_pass2( return 0; } +STATIC int +xlog_recover_attri_pass2( + struct xlog *log, + struct xlog_recover_item *item, + xfs_lsn_t lsn) +{ + int error; + struct xfs_mount *mp = log->l_mp; + struct xfs_attri_log_item *attrip; + struct xfs_attri_log_format *attri_formatp; + char *name = NULL; + char *value = NULL; + int region = 0; + + attri_formatp = item->ri_buf[region].i_addr; + + attrip = xfs_attri_init(mp); + error = xfs_attri_copy_format(&item->ri_buf[region], &attrip->format); + if (error) { + xfs_attri_item_free(attrip); + return error; + } + + attrip->name_len = attri_formatp->alfi_name_len; + attrip->value_len = attri_formatp->alfi_value_len; + attrip = kmem_realloc(attrip, sizeof(struct xfs_attri_log_item) + + attrip->name_len + attrip->value_len, KM_SLEEP); + + if (attrip->name_len > 0) { + region++; + name = ((char *)attrip) + sizeof(struct xfs_attri_log_item); + memcpy(name, item->ri_buf[region].i_addr, + attrip->name_len); + attrip->name = name; + } + + if (attrip->value_len > 0) { + region++; + value = ((char *)attrip) + sizeof(struct xfs_attri_log_item) + + attrip->name_len; + memcpy(value, item->ri_buf[region].i_addr, + attrip->value_len); + attrip->value = value; + } + + spin_lock(&log->l_ailp->ail_lock); + /* + * The ATTRI has two references. One for the ATTRD and one for ATTRI to + * ensure it makes it into the AIL. Insert the ATTRI into the AIL + * directly and drop the ATTRI reference. Note that + * xfs_trans_ail_update() drops the AIL lock. + */ + xfs_trans_ail_update(log->l_ailp, &attrip->item, lsn); + xfs_attri_release(attrip); + return 0; +} + + +/* + * This routine is called when an ATTRD format structure is found in a committed + * transaction in the log. Its purpose is to cancel the corresponding ATTRI if + * it was still in the log. To do this it searches the AIL for the ATTRI with + * an id equal to that in the ATTRD format structure. If we find it we drop + * the ATTRD reference, which removes the ATTRI from the AIL and frees it. + */ +STATIC int +xlog_recover_attrd_pass2( + struct xlog *log, + struct xlog_recover_item *item) +{ + struct xfs_attrd_log_format *attrd_formatp; + struct xfs_attri_log_item *attrip = NULL; + struct xfs_log_item *lip; + uint64_t attri_id; + struct xfs_ail_cursor cur; + struct xfs_ail *ailp = log->l_ailp; + + attrd_formatp = item->ri_buf[0].i_addr; + ASSERT((item->ri_buf[0].i_len == + (sizeof(struct xfs_attrd_log_format)))); + attri_id = attrd_formatp->alfd_alf_id; + + /* + * Search for the ATTRI with the id in the ATTRD format structure in the + * AIL. + */ + spin_lock(&ailp->ail_lock); + lip = xfs_trans_ail_cursor_first(ailp, &cur, 0); + while (lip != NULL) { + if (lip->li_type == XFS_LI_ATTRI) { + attrip = (struct xfs_attri_log_item *)lip; + if (attrip->format.alfi_id == attri_id) { + /* + * Drop the ATTRD reference to the ATTRI. This + * removes the ATTRI from the AIL and frees it. + */ + spin_unlock(&ailp->ail_lock); + xfs_attri_release(attrip); + spin_lock(&ailp->ail_lock); + break; + } + } + lip = xfs_trans_ail_cursor_next(ailp, &cur); + } + + xfs_trans_ail_cursor_done(&cur); + spin_unlock(&ailp->ail_lock); + + return 0; +} + /* * This routine is called to create an in-core extent rmap update * item from the rui format structure which was logged on disk. @@ -4055,6 +4169,8 @@ xlog_recover_ra_pass2( break; case XFS_LI_EFI: case XFS_LI_EFD: + case XFS_LI_ATTRI: + case XFS_LI_ATTRD: case XFS_LI_QUOTAOFF: case XFS_LI_RUI: case XFS_LI_RUD: @@ -4083,6 +4199,8 @@ xlog_recover_commit_pass1( case XFS_LI_INODE: case XFS_LI_EFI: case XFS_LI_EFD: + case XFS_LI_ATTRI: + case XFS_LI_ATTRD: case XFS_LI_DQUOT: case XFS_LI_ICREATE: case XFS_LI_RUI: @@ -4121,6 +4239,10 @@ xlog_recover_commit_pass2( return xlog_recover_efi_pass2(log, item, trans->r_lsn); case XFS_LI_EFD: return xlog_recover_efd_pass2(log, item); + case XFS_LI_ATTRI: + return xlog_recover_attri_pass2(log, item, trans->r_lsn); + case XFS_LI_ATTRD: + return xlog_recover_attrd_pass2(log, item); case XFS_LI_RUI: return xlog_recover_rui_pass2(log, item, trans->r_lsn); case XFS_LI_RUD: @@ -4682,6 +4804,48 @@ xlog_recover_cancel_efi( spin_lock(&ailp->ail_lock); } +/* Release the ATTRI since we're cancelling everything. */ +STATIC void +xlog_recover_cancel_attri( + struct xfs_mount *mp, + struct xfs_ail *ailp, + struct xfs_log_item *lip) +{ + struct xfs_attri_log_item *attrip; + + attrip = container_of(lip, struct xfs_attri_log_item, item); + + spin_unlock(&ailp->ail_lock); + xfs_attri_release(attrip); + spin_lock(&ailp->ail_lock); +} + + +/* Recover the ATTRI if necessary. */ +STATIC int +xlog_recover_process_attri( + struct xfs_mount *mp, + struct xfs_ail *ailp, + struct xfs_log_item *lip) +{ + struct xfs_attri_log_item *attrip; + int error; + + /* + * Skip ATTRIs that we've already processed. + */ + attrip = container_of(lip, struct xfs_attri_log_item, item); + if (test_bit(XFS_ATTRI_RECOVERED, &attrip->flags)) + return 0; + + spin_unlock(&ailp->ail_lock); + error = xfs_attri_recover(mp, attrip); + spin_lock(&ailp->ail_lock); + + return error; +} + + /* Recover the RUI if necessary. */ STATIC int xlog_recover_process_rui( @@ -4810,6 +4974,7 @@ static inline bool xlog_item_is_intent(struct xfs_log_item *lip) case XFS_LI_RUI: case XFS_LI_CUI: case XFS_LI_BUI: + case XFS_LI_ATTRI: return true; default: return false; @@ -4928,6 +5093,10 @@ xlog_recover_process_intents( case XFS_LI_EFI: error = xlog_recover_process_efi(log->l_mp, ailp, lip); break; + case XFS_LI_ATTRI: + error = xlog_recover_process_attri(log->l_mp, + ailp, lip); + break; case XFS_LI_RUI: error = xlog_recover_process_rui(log->l_mp, ailp, lip); break; @@ -4994,6 +5163,9 @@ xlog_recover_cancel_intents( case XFS_LI_BUI: xlog_recover_cancel_bui(log->l_mp, ailp, lip); break; + case XFS_LI_ATTRI: + xlog_recover_cancel_attri(log->l_mp, ailp, lip); + break; } lip = xfs_trans_ail_cursor_next(ailp, &cur); diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h index c8ba98f..ddd04b5 100644 --- a/fs/xfs/xfs_ondisk.h +++ b/fs/xfs/xfs_ondisk.h @@ -125,6 +125,8 @@ xfs_check_ondisk_structs(void) XFS_CHECK_STRUCT_SIZE(struct xfs_inode_log_format, 56); XFS_CHECK_STRUCT_SIZE(struct xfs_qoff_logformat, 20); XFS_CHECK_STRUCT_SIZE(struct xfs_trans_header, 16); + XFS_CHECK_STRUCT_SIZE(struct xfs_attri_log_format, 40); + XFS_CHECK_STRUCT_SIZE(struct xfs_attrd_log_format, 16); /* * The v5 superblock format extended several v4 header structures with diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index c6e1c57..7bb9d8e 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -26,6 +26,9 @@ struct xfs_cui_log_item; struct xfs_cud_log_item; struct xfs_bui_log_item; struct xfs_bud_log_item; +struct xfs_attrd_log_item; +struct xfs_attri_log_item; +struct xfs_da_args; typedef struct xfs_log_item { struct list_head li_ail; /* AIL pointers */ @@ -231,6 +234,13 @@ int xfs_trans_free_extent(struct xfs_trans *, xfs_extlen_t, const struct xfs_owner_info *, bool); +struct xfs_attrd_log_item * +xfs_trans_get_attrd(struct xfs_trans *tp, + struct xfs_attri_log_item *attrip); +int xfs_trans_attr(struct xfs_da_args *args, + struct xfs_attrd_log_item *attrdp, + uint32_t attr_op_flags); + int xfs_trans_commit(struct xfs_trans *); int xfs_trans_roll(struct xfs_trans **); int xfs_trans_roll_inode(struct xfs_trans **, struct xfs_inode *); diff --git a/fs/xfs/xfs_trans_attr.c b/fs/xfs/xfs_trans_attr.c new file mode 100644 index 0000000..3679348 --- /dev/null +++ b/fs/xfs/xfs_trans_attr.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Oracle. All Rights Reserved. + * Author: Allison Henderson + */ +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_bit.h" +#include "xfs_mount.h" +#include "xfs_defer.h" +#include "xfs_trans.h" +#include "xfs_trans_priv.h" +#include "xfs_attr_item.h" +#include "xfs_alloc.h" +#include "xfs_bmap.h" +#include "xfs_trace.h" +#include "libxfs/xfs_da_format.h" +#include "xfs_da_btree.h" +#include "xfs_attr.h" +#include "xfs_inode.h" +#include "xfs_icache.h" +#include "xfs_quota.h" + +/* + * This routine is called to allocate an "attr free done" + * log item. + */ +struct xfs_attrd_log_item * +xfs_trans_get_attrd(struct xfs_trans *tp, + struct xfs_attri_log_item *attrip) +{ + struct xfs_attrd_log_item *attrdp; + + ASSERT(tp != NULL); + + attrdp = xfs_attrd_init(tp->t_mountp, attrip); + ASSERT(attrdp != NULL); + + /* + * Get a log_item_desc to point at the new item. + */ + xfs_trans_add_item(tp, &attrdp->item); + return attrdp; +} + +/* + * Delete an attr and log it to the ATTRD. Note that the transaction is marked + * dirty regardless of whether the attr delete succeeds or fails to support the + * ATTRI/ATTRD lifecycle rules. + */ +int +xfs_trans_attr( + struct xfs_da_args *args, + struct xfs_attrd_log_item *attrdp, + uint32_t op_flags) +{ + int error; + struct xfs_buf *leaf_bp = NULL; + + error = xfs_qm_dqattach_locked(args->dp, 0); + if (error) + return error; + + switch (op_flags) { + case XFS_ATTR_OP_FLAGS_SET: + args->op_flags |= XFS_DA_OP_ADDNAME; + error = xfs_attr_set_args(args, &leaf_bp, false); + break; + case XFS_ATTR_OP_FLAGS_REMOVE: + ASSERT(XFS_IFORK_Q((args->dp))); + error = xfs_attr_remove_args(args, false); + break; + default: + error = -EFSCORRUPTED; + } + + if (error) { + if (leaf_bp) + xfs_trans_brelse(args->trans, leaf_bp); + } + + /* + * Mark the transaction dirty, even on error. This ensures the + * transaction is aborted, which: + * + * 1.) releases the ATTRI and frees the ATTRD + * 2.) shuts down the filesystem + */ + args->trans->t_flags |= XFS_TRANS_DIRTY; + set_bit(XFS_LI_DIRTY, &attrdp->item.li_flags); + + attrdp->attrip->name = (void *)args->name; + attrdp->attrip->value = (void *)args->value; + attrdp->attrip->name_len = args->namelen; + attrdp->attrip->value_len = args->valuelen; + + return error; +} + +static int +xfs_attr_diff_items( + void *priv, + struct list_head *a, + struct list_head *b) +{ + return 0; +} + +/* Get an ATTRI. */ +STATIC void * +xfs_attr_create_intent( + struct xfs_trans *tp, + unsigned int count) +{ + struct xfs_attri_log_item *attrip; + + ASSERT(tp != NULL); + ASSERT(count == 1); + + attrip = xfs_attri_init(tp->t_mountp); + ASSERT(attrip != NULL); + + /* + * Get a log_item_desc to point at the new item. + */ + xfs_trans_add_item(tp, &attrip->item); + return attrip; +} + +/* Log an attr to the intent item. */ +STATIC void +xfs_attr_log_item( + struct xfs_trans *tp, + void *intent, + struct list_head *item) +{ + struct xfs_attri_log_item *attrip = intent; + struct xfs_attr_item *attr; + struct xfs_attri_log_format *attrp; + char *name_value; + + attr = container_of(item, struct xfs_attr_item, xattri_list); + name_value = ((char *)attr) + sizeof(struct xfs_attr_item); + + tp->t_flags |= XFS_TRANS_DIRTY; + set_bit(XFS_LI_DIRTY, &attrip->item.li_flags); + + attrp = &attrip->format; + attrp->alfi_ino = attr->xattri_ip->i_ino; + attrp->alfi_op_flags = attr->xattri_op_flags; + attrp->alfi_value_len = attr->xattri_value_len; + attrp->alfi_name_len = attr->xattri_name_len; + attrp->alfi_attr_flags = attr->xattri_flags; + + attrip->name = name_value; + attrip->value = &name_value[attr->xattri_name_len]; + attrip->name_len = attr->xattri_name_len; + attrip->value_len = attr->xattri_value_len; +} + +/* Get an ATTRD so we can process all the attrs. */ +STATIC void * +xfs_attr_create_done( + struct xfs_trans *tp, + void *intent, + unsigned int count) +{ + return xfs_trans_get_attrd(tp, intent); +} + +/* Process an attr. */ +STATIC int +xfs_attr_finish_item( + struct xfs_trans *tp, + struct list_head *item, + void *done_item, + void **state) +{ + struct xfs_attr_item *attr; + char *name_value; + int error; + int local; + struct xfs_da_args args; + + attr = container_of(item, struct xfs_attr_item, xattri_list); + name_value = ((char *)attr) + sizeof(struct xfs_attr_item); + + error = xfs_attr_args_init(&args, attr->xattri_ip, name_value, + attr->xattri_name_len, attr->xattri_flags); + if (error) + goto out; + + args.hashval = xfs_da_hashname(args.name, args.namelen); + args.value = &name_value[attr->xattri_name_len]; + args.valuelen = attr->xattri_value_len; + args.op_flags = XFS_DA_OP_OKNOENT; + args.total = xfs_attr_calc_size(&args, &local); + args.trans = tp; + + error = xfs_trans_attr(&args, done_item, + attr->xattri_op_flags); +out: + kmem_free(attr); + return error; +} + +/* Abort all pending ATTRs. */ +STATIC void +xfs_attr_abort_intent( + void *intent) +{ + xfs_attri_release(intent); +} + +/* Cancel an attr */ +STATIC void +xfs_attr_cancel_item( + struct list_head *item) +{ + struct xfs_attr_item *attr; + + attr = container_of(item, struct xfs_attr_item, xattri_list); + kmem_free(attr); +} + +const struct xfs_defer_op_type xfs_attr_defer_type = { + .max_items = XFS_ATTRI_MAX_FAST_ATTRS, + .diff_items = xfs_attr_diff_items, + .create_intent = xfs_attr_create_intent, + .abort_intent = xfs_attr_abort_intent, + .log_item = xfs_attr_log_item, + .create_done = xfs_attr_create_done, + .finish_item = xfs_attr_finish_item, + .cancel_item = xfs_attr_cancel_item, +}; + From patchwork Fri Apr 12 22:50:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Allison Henderson X-Patchwork-Id: 10899203 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 459151874 for ; Fri, 12 Apr 2019 22:52:51 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 23C9A28E0B for ; Fri, 12 Apr 2019 22:52:51 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 180B528F03; Fri, 12 Apr 2019 22:52:51 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 91FAB28EC2 for ; Fri, 12 Apr 2019 22:52:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726850AbfDLWwt (ORCPT ); Fri, 12 Apr 2019 18:52:49 -0400 Received: from userp2130.oracle.com ([156.151.31.86]:43610 "EHLO userp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726477AbfDLWwt (ORCPT ); Fri, 12 Apr 2019 18:52:49 -0400 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMeNAg010798 for ; Fri, 12 Apr 2019 22:52:47 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=+pBZL9gyDJX9JBEUxwzCx4eFOousgETakTc3eOwi8jo=; b=5h3jaN32X+lOe4vZtCHte6nDSzVhNJbmZOGzw2Js5IGgBn2HXOn2MTZ1yMuHu16ityPG Hqu1tc0uGzUD63wanFdHt8idv+87QtOGZ1iNISVSMAx7T7Ntc3kss4W4NHMRLKN9KLEC +6H0V5VDN+23OmYd1FJKRWO7lUJ/r0CUQHWflFA+szBs5CCCG08GvD6ji/q7DrOHGKi8 favU+0eoS76gWRhqYujubs4BkedHrrUmkhPKR2qzhOqawhq6VbwdB+KgoFZmP6lUZcsL FdKNDa5In4wm/DLttcpxpbxXwFyPoj+JCJVgDvz4wM8/vZwIQ8MIAANnyZ5KD0plU8SV ug== Received: from aserp3020.oracle.com (aserp3020.oracle.com [141.146.126.70]) by userp2130.oracle.com with ESMTP id 2rpkhtgtwp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:47 +0000 Received: from pps.filterd (aserp3020.oracle.com [127.0.0.1]) by aserp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMq6xZ172959 for ; Fri, 12 Apr 2019 22:52:46 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserp3020.oracle.com with ESMTP id 2rpytdhugu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:46 +0000 Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x3CMqkT8030865 for ; Fri, 12 Apr 2019 22:52:46 GMT Received: from localhost.localdomain (/70.176.225.12) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 12 Apr 2019 15:52:46 -0700 From: Allison Henderson To: linux-xfs@vger.kernel.org Subject: [PATCH 5/9] xfs: Add xfs_attr_set_deferred and xfs_attr_remove_deferred Date: Fri, 12 Apr 2019 15:50:32 -0700 Message-Id: <20190412225036.22939-6-allison.henderson@oracle.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190412225036.22939-1-allison.henderson@oracle.com> References: <20190412225036.22939-1-allison.henderson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP These routines set up set and start a new deferred attribute operation. These functions are meant to be called by other code needing to initiate a deferred attribute operation. We will use these routines later in the parent pointer patches. Signed-off-by: Allison Henderson --- fs/xfs/libxfs/xfs_attr.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_attr.h | 7 +++++ 2 files changed, 87 insertions(+) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index fadd485..c3477fa7 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -30,6 +30,7 @@ #include "xfs_trans_space.h" #include "xfs_trace.h" #include "xfs_attr_item.h" +#include "xfs_attr.h" /* * xfs_attr.c @@ -429,6 +430,52 @@ xfs_attr_set( goto out_unlock; } +/* Sets an attribute for an inode as a deferred operation */ +int +xfs_attr_set_deferred( + struct xfs_inode *dp, + struct xfs_trans *tp, + const unsigned char *name, + unsigned int namelen, + const unsigned char *value, + unsigned int valuelen, + int flags) +{ + + struct xfs_attr_item *new; + char *name_value; + + /* + * All set operations must have a name + * but not necessarily a value. + * Generic 062 + */ + if (!namelen) { + ASSERT(0); + return -EFSCORRUPTED; + } + + new = kmem_alloc(XFS_ATTR_ITEM_SIZEOF(namelen, valuelen), + KM_SLEEP|KM_NOFS); + name_value = ((char *)new) + sizeof(struct xfs_attr_item); + memset(new, 0, XFS_ATTR_ITEM_SIZEOF(namelen, valuelen)); + new->xattri_ip = dp; + new->xattri_op_flags = XFS_ATTR_OP_FLAGS_SET; + new->xattri_name_len = namelen; + new->xattri_value_len = valuelen; + new->xattri_flags = flags; + memcpy(&name_value[0], name, namelen); + new->xattri_name = name_value; + new->xattri_value = name_value + namelen; + + if (valuelen > 0) + memcpy(&name_value[namelen], value, valuelen); + + xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list); + + return 0; +} + /* * Generic handler routine to remove a name from an attribute list. * Transitions attribute list from Btree to shortform as necessary. @@ -513,6 +560,39 @@ xfs_attr_remove( return error; } +/* Removes an attribute for an inode as a deferred operation */ +int +xfs_attr_remove_deferred( + struct xfs_inode *dp, + struct xfs_trans *tp, + const unsigned char *name, + unsigned int namelen, + int flags) +{ + + struct xfs_attr_item *new; + char *name_value; + + if (!namelen) { + ASSERT(0); + return -EFSCORRUPTED; + } + + new = kmem_alloc(XFS_ATTR_ITEM_SIZEOF(namelen, 0), KM_SLEEP|KM_NOFS); + name_value = ((char *)new) + sizeof(struct xfs_attr_item); + memset(new, 0, XFS_ATTR_ITEM_SIZEOF(namelen, 0)); + new->xattri_ip = dp; + new->xattri_op_flags = XFS_ATTR_OP_FLAGS_REMOVE; + new->xattri_name_len = namelen; + new->xattri_value_len = 0; + new->xattri_flags = flags; + memcpy(name_value, name, namelen); + + xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_ATTR, &new->xattri_list); + + return 0; +} + /*======================================================================== * External routines when attribute list is inside the inode *========================================================================*/ diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index 92d9a15..83b3621 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -175,5 +175,12 @@ bool xfs_attr_namecheck(const void *name, size_t length); int xfs_attr_args_init(struct xfs_da_args *args, struct xfs_inode *dp, const unsigned char *name, size_t namelen, int flags); int xfs_attr_calc_size(struct xfs_da_args *args, int *local); +int xfs_attr_set_deferred(struct xfs_inode *dp, struct xfs_trans *tp, + const unsigned char *name, unsigned int name_len, + const unsigned char *value, unsigned int valuelen, + int flags); +int xfs_attr_remove_deferred(struct xfs_inode *dp, struct xfs_trans *tp, + const unsigned char *name, unsigned int namelen, + int flags); #endif /* __XFS_ATTR_H__ */ From patchwork Fri Apr 12 22:50:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Allison Henderson X-Patchwork-Id: 10899201 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AE33F13B5 for ; Fri, 12 Apr 2019 22:52:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 92A1728F21 for ; Fri, 12 Apr 2019 22:52:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 86E5D28F20; Fri, 12 Apr 2019 22:52:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E8B3228EC2 for ; Fri, 12 Apr 2019 22:52:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726902AbfDLWwt (ORCPT ); Fri, 12 Apr 2019 18:52:49 -0400 Received: from userp2120.oracle.com ([156.151.31.85]:35020 "EHLO userp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726983AbfDLWws (ORCPT ); Fri, 12 Apr 2019 18:52:48 -0400 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMdSNo021297 for ; Fri, 12 Apr 2019 22:52:48 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=AFkyVOx9FaOOdaTYQcJTBJhOW+aA/dEqXpjqodgLRMI=; b=qpS5FtrZMC1CrW4/4SzvFmp9xsTYyV1uz4GshPgYOjWhppaL8QJCSm96iIYP77/Y5NDl u9khQvSsa9K8OHHcc6DP7xNUdtcqsR815Ypp5W41+PP3w3d8u1EoUusIc502/56GYYCx PN8UVNDjHRSgCWrVVIOrw9JPZeNIpgkdCZG4Zb4fv+zRa5R7Hka3sl9iGpevMIxyK4PS OuEtYygTY2ziJ7aSPauKaTBRrrBZ/C/63sC0spUaaZFvbwACDnTVhm/FrnpfiiY1bTfd EJAk1X+bu0pDadru6YGgR9JQb2CRleg/zw5DTw5jKsvEU+SOvG8Akjx5Buqn01DErO8t cA== Received: from aserp3030.oracle.com (aserp3030.oracle.com [141.146.126.71]) by userp2120.oracle.com with ESMTP id 2rpmrqrs0q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:47 +0000 Received: from pps.filterd (aserp3030.oracle.com [127.0.0.1]) by aserp3030.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMphW4144285 for ; Fri, 12 Apr 2019 22:52:47 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserp3030.oracle.com with ESMTP id 2rt9uqcvm0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:47 +0000 Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x3CMqk0v030868 for ; Fri, 12 Apr 2019 22:52:46 GMT Received: from localhost.localdomain (/70.176.225.12) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 12 Apr 2019 15:52:46 -0700 From: Allison Henderson To: linux-xfs@vger.kernel.org Subject: [PATCH 6/9] xfs: Add xfs_has_attr and subroutines Date: Fri, 12 Apr 2019 15:50:33 -0700 Message-Id: <20190412225036.22939-7-allison.henderson@oracle.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190412225036.22939-1-allison.henderson@oracle.com> References: <20190412225036.22939-1-allison.henderson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds a new functions to check for the existence of an attribute. Subroutines are also added to handle the cases of leaf blocks, nodes or shortform. We will need this later for delayed attributes since delayed operations cannot return error codes. Signed-off-by: Allison Henderson --- fs/xfs/libxfs/xfs_attr.c | 78 +++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_attr.h | 1 + fs/xfs/libxfs/xfs_attr_leaf.c | 33 ++++++++++++++++++ fs/xfs/libxfs/xfs_attr_leaf.h | 1 + 4 files changed, 113 insertions(+) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index c3477fa7..0042708 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -53,6 +53,7 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args); STATIC int xfs_attr_leaf_get(xfs_da_args_t *args); STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args, bool roll_trans); STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args, bool roll_trans); +STATIC int xfs_leaf_has_attr(xfs_da_args_t *args); /* * Internal routines when attribute list is more than one block. @@ -60,6 +61,7 @@ STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args, bool roll_trans); STATIC int xfs_attr_node_get(xfs_da_args_t *args); STATIC int xfs_attr_node_addname(xfs_da_args_t *args, bool roll_trans); STATIC int xfs_attr_node_removename(xfs_da_args_t *args, bool roll_trans); +STATIC int xfs_attr_node_hasname(xfs_da_args_t *args); STATIC int xfs_attr_fillstate(xfs_da_state_t *state); STATIC int xfs_attr_refillstate(xfs_da_state_t *state); @@ -301,6 +303,29 @@ xfs_attr_set_args( } /* + * Return successful if attr is found, or ENOATTR if not + */ +int +xfs_has_attr( + struct xfs_da_args *args) +{ + struct xfs_inode *dp = args->dp; + int error; + + if (!xfs_inode_hasattr(dp)) + error = -ENOATTR; + else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) { + ASSERT(dp->i_afp->if_flags & XFS_IFINLINE); + error = xfs_shortform_has_attr(args); + } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) + error = xfs_leaf_has_attr(args); + else + error = xfs_attr_node_hasname(args); + + return error; +} + +/* * Remove the attribute specified in @args. */ int @@ -836,6 +861,29 @@ xfs_attr_leaf_addname( } /* + * Return successful if attr is found, or ENOATTR if not + */ +STATIC int +xfs_leaf_has_attr( + struct xfs_da_args *args) +{ + struct xfs_buf *bp; + int error = 0; + + args->blkno = 0; + error = xfs_attr3_leaf_read(args->trans, args->dp, + args->blkno, -1, &bp); + if (error) + return error; + + error = xfs_attr3_leaf_lookup_int(bp, args); + error = (error == -ENOATTR) ? -ENOATTR : 0; + xfs_trans_brelse(args->trans, bp); + + return error; +} + +/* * Remove a name from the leaf attribute list structure * * This leaf block cannot have a "remote" value, we only call this routine @@ -1166,6 +1214,36 @@ xfs_attr_node_addname( } /* + * Return successful if attr is found, or ENOATTR if not + */ +STATIC int +xfs_attr_node_hasname( + struct xfs_da_args *args) +{ + struct xfs_da_state *state; + struct xfs_inode *dp; + int retval, error; + + /* + * Tie a string around our finger to remind us where we are. + */ + dp = args->dp; + state = xfs_da_state_alloc(); + state->args = args; + state->mp = dp->i_mount; + + /* + * Search to see if name exists, and get back a pointer to it. + */ + error = xfs_da3_node_lookup_int(state, &retval); + if (error || (retval != -EEXIST)) { + if (error == 0) + error = retval; + } + return error; +} + +/* * Remove a name from a B-tree attribute list. * * This will involve walking down the Btree, and may involve joining diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index 83b3621..974c963 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -168,6 +168,7 @@ int xfs_attr_set_args(struct xfs_da_args *args, struct xfs_buf **leaf_bp, bool roll_trans); int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, size_t namelen, int flags); +int xfs_has_attr(struct xfs_da_args *args); int xfs_attr_remove_args(struct xfs_da_args *args, bool roll_trans); int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize, int flags, struct attrlist_cursor_kern *cursor); diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 128bfe9..e9f2f53 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -622,6 +622,39 @@ xfs_attr_fork_remove( } /* + * Return successful if attr is found, or ENOATTR if not + */ +int +xfs_shortform_has_attr( + struct xfs_da_args *args) +{ + struct xfs_attr_shortform *sf; + struct xfs_attr_sf_entry *sfe; + int base = sizeof(struct xfs_attr_sf_hdr); + int size = 0; + int end; + int i; + + sf = (struct xfs_attr_shortform *)args->dp->i_afp->if_u1.if_data; + sfe = &sf->list[0]; + end = sf->hdr.count; + for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), + base += size, i++) { + size = XFS_ATTR_SF_ENTSIZE(sfe); + if (sfe->namelen != args->namelen) + continue; + if (memcmp(sfe->nameval, args->name, args->namelen) != 0) + continue; + if (!xfs_attr_namesp_match(args->flags, sfe->flags)) + continue; + break; + } + if (i == end) + return -ENOATTR; + return 0; +} + +/* * Remove an attribute from the shortform attribute list structure. */ int diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h index 9d830ec..98dd169 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.h +++ b/fs/xfs/libxfs/xfs_attr_leaf.h @@ -39,6 +39,7 @@ int xfs_attr_shortform_getvalue(struct xfs_da_args *args); int xfs_attr_shortform_to_leaf(struct xfs_da_args *args, struct xfs_buf **leaf_bp); int xfs_attr_shortform_remove(struct xfs_da_args *args); +int xfs_shortform_has_attr(struct xfs_da_args *args); int xfs_attr_shortform_allfit(struct xfs_buf *bp, struct xfs_inode *dp); int xfs_attr_shortform_bytesfit(struct xfs_inode *dp, int bytes); xfs_failaddr_t xfs_attr_shortform_verify(struct xfs_inode *ip); From patchwork Fri Apr 12 22:50:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Allison Henderson X-Patchwork-Id: 10899197 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CC805186E for ; Fri, 12 Apr 2019 22:52:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B360928E0B for ; Fri, 12 Apr 2019 22:52:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A70C628F03; Fri, 12 Apr 2019 22:52:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2303228F03 for ; Fri, 12 Apr 2019 22:52:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727085AbfDLWwt (ORCPT ); Fri, 12 Apr 2019 18:52:49 -0400 Received: from userp2130.oracle.com ([156.151.31.86]:43624 "EHLO userp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726788AbfDLWwt (ORCPT ); Fri, 12 Apr 2019 18:52:49 -0400 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMe17M010456 for ; Fri, 12 Apr 2019 22:52:48 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=IOlDRoMY9zQSnkE24drSwZ/bkXTPvG3XEEMCxnWjKHQ=; b=NIuZ5EGtp1u2Y+eh8RPj4dPB4LwmYnMvCJ9vAi/wq5KgX4c18G2eLocV7TqRjn5ssKf6 Ru9MFkg9Jlfaveycclnz9tTQgc0AJYCaWqInNlpMBm2iIAIcXZjhpCGe6UHjhjh/u3qZ OHselKJIRCA3u8t9mblMr8Jr5G0vbsxLEShQ/X8HivErDDme2xMZO2/8R0F6RglMRv/0 6c4xay5syPA9MNVWW3Ia+QKoi+cLsgnjVXaKWnmn3r8cgRQffuAVKcZXJitvSMKN3avu KuQsuERFCNMFV9yYB5e0xVUKIAasY/Wq/hhNSw9Aepbc3PIl9qCoz2RBIT2EGqs2MPaW 5A== Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by userp2130.oracle.com with ESMTP id 2rpkhtgtwr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:48 +0000 Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMq7sF101125 for ; Fri, 12 Apr 2019 22:52:47 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userp3020.oracle.com with ESMTP id 2rtyj2ub7f-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:47 +0000 Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x3CMqkop030871 for ; Fri, 12 Apr 2019 22:52:46 GMT Received: from localhost.localdomain (/70.176.225.12) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 12 Apr 2019 15:52:46 -0700 From: Allison Henderson To: linux-xfs@vger.kernel.org Subject: [PATCH 7/9] xfs: Add attr context to log item Date: Fri, 12 Apr 2019 15:50:34 -0700 Message-Id: <20190412225036.22939-8-allison.henderson@oracle.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190412225036.22939-1-allison.henderson@oracle.com> References: <20190412225036.22939-1-allison.henderson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch modifies xfs_attr_item to store a xfs_da_args, a xfs_buf pointer and a new state type. We will use these in the next patch when we modify xfs_set_attr_args to roll transactions by returning EAGAIN. Because the subroutines of this function modify the contents of these structures, we need to find a place to store them where they remain instantiated across multiple calls to xfs_set_attr_args. Signed-off-by: Allison Henderson --- fs/xfs/libxfs/xfs_attr.h | 18 +++++++++++++++++- fs/xfs/scrub/common.c | 2 ++ fs/xfs/xfs_acl.c | 2 ++ fs/xfs/xfs_attr_item.c | 2 +- fs/xfs/xfs_ioctl.c | 2 ++ fs/xfs/xfs_ioctl32.c | 2 ++ fs/xfs/xfs_iops.c | 1 + fs/xfs/xfs_xattr.c | 1 + 8 files changed, 28 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index 974c963..4ce3b0a 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -77,6 +77,13 @@ typedef struct attrlist_ent { /* data from attr_list() */ char a_name[1]; /* attr name (NULL terminated) */ } attrlist_ent_t; +/* Attr state machine types */ +enum xfs_attr_state { + XFS_ATTR_STATE1 = 1, + XFS_ATTR_STATE2 = 2, + XFS_ATTR_STATE3 = 3, +}; + /* * List of attrs to commit later. */ @@ -88,7 +95,16 @@ struct xfs_attr_item { void *xattri_name; /* attr name */ uint32_t xattri_name_len; /* length of name */ uint32_t xattri_flags; /* attr flags */ - struct list_head xattri_list; + + /* + * Delayed attr parameters that need to remain instantiated + * across transaction rolls during the defer finish + */ + struct xfs_buf *xattri_leaf_bp; /* Leaf buf to release */ + enum xfs_attr_state xattri_state; /* state machine marker */ + struct xfs_da_args xattri_args; /* args context */ + + struct list_head xattri_list; /* * A byte array follows the header containing the file name and diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 0c54ff5..270c32e 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -30,6 +30,8 @@ #include "xfs_rmap_btree.h" #include "xfs_log.h" #include "xfs_trans_priv.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" #include "xfs_attr.h" #include "xfs_reflink.h" #include "scrub/xfs_scrub.h" diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 142de8d..9b1b93e 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -10,6 +10,8 @@ #include "xfs_mount.h" #include "xfs_inode.h" #include "xfs_acl.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" #include "xfs_attr.h" #include "xfs_trace.h" #include diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c index 0ea19b4..36e6d1e 100644 --- a/fs/xfs/xfs_attr_item.c +++ b/fs/xfs/xfs_attr_item.c @@ -19,10 +19,10 @@ #include "xfs_rmap.h" #include "xfs_inode.h" #include "xfs_icache.h" -#include "xfs_attr.h" #include "xfs_shared.h" #include "xfs_da_format.h" #include "xfs_da_btree.h" +#include "xfs_attr.h" static inline struct xfs_attri_log_item *ATTRI_ITEM(struct xfs_log_item *lip) { diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index ab341d6..c8728ca 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -16,6 +16,8 @@ #include "xfs_rtalloc.h" #include "xfs_itable.h" #include "xfs_error.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" #include "xfs_attr.h" #include "xfs_bmap.h" #include "xfs_bmap_util.h" diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c index 5001dca..23f6990 100644 --- a/fs/xfs/xfs_ioctl32.c +++ b/fs/xfs/xfs_ioctl32.c @@ -21,6 +21,8 @@ #include "xfs_fsops.h" #include "xfs_alloc.h" #include "xfs_rtalloc.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" #include "xfs_attr.h" #include "xfs_ioctl.h" #include "xfs_ioctl32.h" diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index e73c21a..561c467 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -17,6 +17,7 @@ #include "xfs_acl.h" #include "xfs_quota.h" #include "xfs_error.h" +#include "xfs_da_btree.h" #include "xfs_attr.h" #include "xfs_trans.h" #include "xfs_trace.h" diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 3013746..938e81d 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -11,6 +11,7 @@ #include "xfs_mount.h" #include "xfs_da_format.h" #include "xfs_inode.h" +#include "xfs_da_btree.h" #include "xfs_attr.h" #include "xfs_attr_leaf.h" #include "xfs_acl.h" From patchwork Fri Apr 12 22:50:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Allison Henderson X-Patchwork-Id: 10899207 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C86FD13B5 for ; Fri, 12 Apr 2019 22:52:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF10C28E0B for ; Fri, 12 Apr 2019 22:52:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A3A4F28EC4; Fri, 12 Apr 2019 22:52:52 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E505A28E0B for ; Fri, 12 Apr 2019 22:52:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726477AbfDLWwv (ORCPT ); Fri, 12 Apr 2019 18:52:51 -0400 Received: from aserp2130.oracle.com ([141.146.126.79]:44230 "EHLO aserp2130.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727050AbfDLWwu (ORCPT ); Fri, 12 Apr 2019 18:52:50 -0400 Received: from pps.filterd (aserp2130.oracle.com [127.0.0.1]) by aserp2130.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMdOvM015162 for ; Fri, 12 Apr 2019 22:52:49 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=mbJ00eI4zVD58vrk75peoy8kn0MVAxMsucqsoRDCItU=; b=WWgrXm5DAnzkEzF43RTlPBVMEAAU2KFCM20yzkujZyUg4QGaim3UEpXMuxtOWr2jsTTN amRYb5TuJOkZEJulhl+a53W7OV6NmAnx1cZE2rtKz41qloPjFOGbAmq+7df0hkHpRxRS N/bI9qNt0ac30oJtdvdhV+CSpDoYNy+jF4an8KBNetYy85WfsWXaKKFBCMG5iy8f83IT LlLG6r2Vf3WSECCjb6xpdsFW+IJAKNcFCuaD9cnmc9nRaU/vOUoGCL6mudKiwoZhssUq Zbgybem8kQ9yfW3tnX+cW/o72mAxVCjZPzDHWBVQmmnyUqsSJePezuHR9x7i+nmgxB4W vQ== Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by aserp2130.oracle.com with ESMTP id 2rphmf0ypa-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:48 +0000 Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMq43u101035 for ; Fri, 12 Apr 2019 22:52:48 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userp3020.oracle.com with ESMTP id 2rtyj2ub7g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:48 +0000 Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id x3CMqlXp030874 for ; Fri, 12 Apr 2019 22:52:47 GMT Received: from localhost.localdomain (/70.176.225.12) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 12 Apr 2019 15:52:47 -0700 From: Allison Henderson To: linux-xfs@vger.kernel.org Subject: [PATCH 8/9] xfs: Roll delayed attr operations by returning EAGAIN Date: Fri, 12 Apr 2019 15:50:35 -0700 Message-Id: <20190412225036.22939-9-allison.henderson@oracle.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190412225036.22939-1-allison.henderson@oracle.com> References: <20190412225036.22939-1-allison.henderson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=4 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=4 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch modifies xfs_attr_set_args to return -EAGAIN when a transaction needs to be rolled. All functions currently calling xfs_attr_set_args are modified to use the deferred attr operation, or handle the -EAGAIN return code Signed-off-by: Allison Henderson --- fs/xfs/libxfs/xfs_attr.c | 62 ++++++++++++++++++++++++++++++++++++++++-------- fs/xfs/libxfs/xfs_attr.h | 2 +- fs/xfs/xfs_attr_item.c | 41 +++++++++++++++++++++++++++----- fs/xfs/xfs_trans.h | 2 ++ fs/xfs/xfs_trans_attr.c | 56 +++++++++++++++++++++++++------------------ 5 files changed, 123 insertions(+), 40 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 0042708..4ddd86b 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -236,10 +236,37 @@ int xfs_attr_set_args( struct xfs_da_args *args, struct xfs_buf **leaf_bp, + enum xfs_attr_state *state, bool roll_trans) { struct xfs_inode *dp = args->dp; int error = 0; + int sf_size; + + switch (*state) { + case (XFS_ATTR_STATE1): + goto state1; + case (XFS_ATTR_STATE2): + goto state2; + case (XFS_ATTR_STATE3): + goto state3; + } + + /* + * New inodes may not have an attribute fork yet. So set the attribute + * fork appropriately + */ + if (XFS_IFORK_Q((args->dp)) == 0) { + sf_size = sizeof(struct xfs_attr_sf_hdr) + + XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen, args->valuelen); + xfs_bmap_set_attrforkoff(args->dp, sf_size, NULL); + args->dp->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); + args->dp->i_afp->if_flags = XFS_IFEXTENTS; + } + + *state = XFS_ATTR_STATE1; + return -EAGAIN; +state1: /* * If the attribute list is non-existent or a shortform list, @@ -248,7 +275,6 @@ xfs_attr_set_args( if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL || (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS && dp->i_d.di_anextents == 0)) { - /* * Build initial attribute list (if required). */ @@ -262,6 +288,9 @@ xfs_attr_set_args( if (error != -ENOSPC) return error; + *state = XFS_ATTR_STATE2; + return -EAGAIN; +state2: /* * It won't fit in the shortform, transform to a leaf block. * GROT: another possible req'mt for a double-split btree op. @@ -270,14 +299,14 @@ xfs_attr_set_args( if (error) return error; - if (roll_trans) { - /* - * Prevent the leaf buffer from being unlocked so that a - * concurrent AIL push cannot grab the half-baked leaf - * buffer and run into problems with the write verifier. - */ - xfs_trans_bhold(args->trans, *leaf_bp); + /* + * Prevent the leaf buffer from being unlocked so that a + * concurrent AIL push cannot grab the half-baked leaf + * buffer and run into problems with the write verifier. + */ + xfs_trans_bhold(args->trans, *leaf_bp); + if (roll_trans) { error = xfs_defer_finish(&args->trans); if (error) return error; @@ -293,6 +322,12 @@ xfs_attr_set_args( xfs_trans_bjoin(args->trans, *leaf_bp); *leaf_bp = NULL; } + + *state = XFS_ATTR_STATE3; + return -EAGAIN; +state3: + if (*leaf_bp != NULL) + xfs_trans_brelse(args->trans, *leaf_bp); } if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) @@ -419,7 +454,9 @@ xfs_attr_set( goto out_trans_cancel; xfs_trans_ijoin(args.trans, dp, 0); - error = xfs_attr_set_args(&args, &leaf_bp, true); + + error = xfs_attr_set_deferred(dp, args.trans, name, namelen, + value, valuelen, flags); if (error) goto out_release_leaf; if (!args.trans) { @@ -554,8 +591,13 @@ xfs_attr_remove( */ xfs_trans_ijoin(args.trans, dp, 0); - error = xfs_attr_remove_args(&args, true); + error = xfs_has_attr(&args); + if (error) + goto out; + + error = xfs_attr_remove_deferred(dp, args.trans, + name, namelen, flags); if (error) goto out; diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index 4ce3b0a..da95e69 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -181,7 +181,7 @@ int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name, size_t namelen, unsigned char *value, int valuelen, int flags); int xfs_attr_set_args(struct xfs_da_args *args, struct xfs_buf **leaf_bp, - bool roll_trans); + enum xfs_attr_state *state, bool roll_trans); int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, size_t namelen, int flags); int xfs_has_attr(struct xfs_da_args *args); diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c index 36e6d1e..292d608 100644 --- a/fs/xfs/xfs_attr_item.c +++ b/fs/xfs/xfs_attr_item.c @@ -464,8 +464,11 @@ xfs_attri_recover( struct xfs_attri_log_format *attrp; struct xfs_trans_res tres; int local; - int error = 0; + int error, err2 = 0; int rsvd = 0; + enum xfs_attr_state state = 0; + struct xfs_buf *leaf_bp = NULL; + ASSERT(!test_bit(XFS_ATTRI_RECOVERED, &attrip->flags)); @@ -540,14 +543,40 @@ xfs_attri_recover( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(args.trans, ip, 0); - error = xfs_trans_attr(&args, attrdp, attrp->alfi_op_flags); - if (error) - goto abort_error; + do { + leaf_bp = NULL; + + error = xfs_trans_attr(&args, attrdp, &leaf_bp, &state, + attrp->alfi_op_flags); + if (error && error != -EAGAIN) + goto abort_error; + + xfs_trans_log_inode(args.trans, ip, + XFS_ILOG_CORE | XFS_ILOG_ADATA); + + err2 = xfs_trans_commit(args.trans); + if (err2) { + error = err2; + goto abort_error; + } + + if (error == -EAGAIN) { + err2 = xfs_trans_alloc(mp, &tres, args.total, 0, + XFS_TRANS_PERM_LOG_RES, &args.trans); + if (err2) { + error = err2; + goto abort_error; + } + xfs_trans_ijoin(args.trans, ip, 0); + } + + } while (error == -EAGAIN); + + if (leaf_bp) + xfs_trans_brelse(args.trans, leaf_bp); set_bit(XFS_ATTRI_RECOVERED, &attrip->flags); - xfs_trans_log_inode(args.trans, ip, XFS_ILOG_CORE | XFS_ILOG_ADATA); - error = xfs_trans_commit(args.trans); xfs_iunlock(ip, XFS_ILOCK_EXCL); return error; diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 7bb9d8e..c785cd7 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -239,6 +239,8 @@ xfs_trans_get_attrd(struct xfs_trans *tp, struct xfs_attri_log_item *attrip); int xfs_trans_attr(struct xfs_da_args *args, struct xfs_attrd_log_item *attrdp, + struct xfs_buf **leaf_bp, + void *state, uint32_t attr_op_flags); int xfs_trans_commit(struct xfs_trans *); diff --git a/fs/xfs/xfs_trans_attr.c b/fs/xfs/xfs_trans_attr.c index 3679348..a3339ea 100644 --- a/fs/xfs/xfs_trans_attr.c +++ b/fs/xfs/xfs_trans_attr.c @@ -56,10 +56,11 @@ int xfs_trans_attr( struct xfs_da_args *args, struct xfs_attrd_log_item *attrdp, + struct xfs_buf **leaf_bp, + void *state, uint32_t op_flags) { int error; - struct xfs_buf *leaf_bp = NULL; error = xfs_qm_dqattach_locked(args->dp, 0); if (error) @@ -68,7 +69,8 @@ xfs_trans_attr( switch (op_flags) { case XFS_ATTR_OP_FLAGS_SET: args->op_flags |= XFS_DA_OP_ADDNAME; - error = xfs_attr_set_args(args, &leaf_bp, false); + error = xfs_attr_set_args(args, leaf_bp, + (enum xfs_attr_state *)state, false); break; case XFS_ATTR_OP_FLAGS_REMOVE: ASSERT(XFS_IFORK_Q((args->dp))); @@ -78,11 +80,6 @@ xfs_trans_attr( error = -EFSCORRUPTED; } - if (error) { - if (leaf_bp) - xfs_trans_brelse(args->trans, leaf_bp); - } - /* * Mark the transaction dirty, even on error. This ensures the * transaction is aborted, which: @@ -184,27 +181,40 @@ xfs_attr_finish_item( char *name_value; int error; int local; - struct xfs_da_args args; + struct xfs_da_args *args; attr = container_of(item, struct xfs_attr_item, xattri_list); - name_value = ((char *)attr) + sizeof(struct xfs_attr_item); - - error = xfs_attr_args_init(&args, attr->xattri_ip, name_value, - attr->xattri_name_len, attr->xattri_flags); - if (error) - goto out; + args = &attr->xattri_args; + + if (attr->xattri_state == 0) { + /* Only need to initialize args context once */ + name_value = ((char *)attr) + sizeof(struct xfs_attr_item); + error = xfs_attr_args_init(args, attr->xattri_ip, name_value, + attr->xattri_name_len, + attr->xattri_flags); + if (error) + goto out; + + args->hashval = xfs_da_hashname(args->name, args->namelen); + args->value = &name_value[attr->xattri_name_len]; + args->valuelen = attr->xattri_value_len; + args->op_flags = XFS_DA_OP_OKNOENT; + args->total = xfs_attr_calc_size(args, &local); + attr->xattri_leaf_bp = NULL; + } - args.hashval = xfs_da_hashname(args.name, args.namelen); - args.value = &name_value[attr->xattri_name_len]; - args.valuelen = attr->xattri_value_len; - args.op_flags = XFS_DA_OP_OKNOENT; - args.total = xfs_attr_calc_size(&args, &local); - args.trans = tp; + /* + * Always reset trans after EAGAIN cycle + * since the transaction is new + */ + args->trans = tp; - error = xfs_trans_attr(&args, done_item, - attr->xattri_op_flags); + error = xfs_trans_attr(args, done_item, &attr->xattri_leaf_bp, + &attr->xattri_state, attr->xattri_op_flags); out: - kmem_free(attr); + if (error != -EAGAIN) + kmem_free(attr); + return error; } From patchwork Fri Apr 12 22:50:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Allison Henderson X-Patchwork-Id: 10899209 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 330E713B5 for ; Fri, 12 Apr 2019 22:52:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 157EA28E0B for ; Fri, 12 Apr 2019 22:52:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0559828F23; Fri, 12 Apr 2019 22:52:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BE0E428E0B for ; Fri, 12 Apr 2019 22:52:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727041AbfDLWwx (ORCPT ); Fri, 12 Apr 2019 18:52:53 -0400 Received: from userp2120.oracle.com ([156.151.31.85]:35038 "EHLO userp2120.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726983AbfDLWww (ORCPT ); Fri, 12 Apr 2019 18:52:52 -0400 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMdpnE021387 for ; Fri, 12 Apr 2019 22:52:49 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : subject : date : message-id : in-reply-to : references; s=corp-2018-07-02; bh=N1ywFm3tAKIFq4VMDxOg0nl0Mo03pqZLV2xCTJcJbtc=; b=Tgq+u1QH/6KuZ2+KVduEFM7EsUCxzqy6wTpo3soSPhCJNRceVAGY6n/tKdHKBfK5+k6/ 8rWay8+a5F1qJdJlQB+RDHA+mvPq4qC4LbwvJw4MKEHf6LKjnnCsmU8ajWA6kM0TkOyo lh25gxO/d5ZyYzPildmxEAyKGVomKtCycV1hhIoto8r4ZOF+mvGklHyNktXol+rYXt9Q wToxp43Iqs/CsYc/MVtQeApRvYvsylz3DiZOnB2qlk/YpjO+eaArYzjLCLXfvWB4WZfg sjVFi8wQpb/5TqcVi4eBzug7XYLc7BY9UZhttjNDHrn2PpXUKloEDge9phGKuq6cRaAV hA== Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by userp2120.oracle.com with ESMTP id 2rpmrqrs0t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:48 +0000 Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id x3CMq0ds100896 for ; Fri, 12 Apr 2019 22:52:48 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userp3020.oracle.com with ESMTP id 2rtyj2ub7h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 12 Apr 2019 22:52:48 +0000 Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0121.oracle.com (8.14.4/8.13.8) with ESMTP id x3CMqlS4002548 for ; Fri, 12 Apr 2019 22:52:47 GMT Received: from localhost.localdomain (/70.176.225.12) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 12 Apr 2019 15:52:47 -0700 From: Allison Henderson To: linux-xfs@vger.kernel.org Subject: [PATCH 9/9] xfs: Remove roll_trans boolean Date: Fri, 12 Apr 2019 15:50:36 -0700 Message-Id: <20190412225036.22939-10-allison.henderson@oracle.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190412225036.22939-1-allison.henderson@oracle.com> References: <20190412225036.22939-1-allison.henderson@oracle.com> X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 suspectscore=1 malwarescore=0 phishscore=0 bulkscore=0 spamscore=0 mlxscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 X-Proofpoint-Virus-Version: vendor=nai engine=5900 definitions=9225 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1904120150 Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP All calls to functions using this parameter are now passing a false value. We can now remove the boolean and all affected code. Signed-off-by: Allison Henderson --- fs/xfs/libxfs/xfs_attr.c | 178 ++++++---------------------------------- fs/xfs/libxfs/xfs_attr.h | 4 +- fs/xfs/libxfs/xfs_attr_leaf.c | 25 +----- fs/xfs/libxfs/xfs_attr_leaf.h | 6 +- fs/xfs/libxfs/xfs_attr_remote.c | 34 +------- fs/xfs/libxfs/xfs_attr_remote.h | 4 +- fs/xfs/xfs_trans_attr.c | 4 +- 7 files changed, 41 insertions(+), 214 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 4ddd86b..bd8fd32 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -51,16 +51,16 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args); * Internal routines when attribute list is one block. */ STATIC int xfs_attr_leaf_get(xfs_da_args_t *args); -STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args, bool roll_trans); -STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args, bool roll_trans); +STATIC int xfs_attr_leaf_addname(xfs_da_args_t *args); +STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args); STATIC int xfs_leaf_has_attr(xfs_da_args_t *args); /* * Internal routines when attribute list is more than one block. */ STATIC int xfs_attr_node_get(xfs_da_args_t *args); -STATIC int xfs_attr_node_addname(xfs_da_args_t *args, bool roll_trans); -STATIC int xfs_attr_node_removename(xfs_da_args_t *args, bool roll_trans); +STATIC int xfs_attr_node_addname(xfs_da_args_t *args); +STATIC int xfs_attr_node_removename(xfs_da_args_t *args); STATIC int xfs_attr_node_hasname(xfs_da_args_t *args); STATIC int xfs_attr_fillstate(xfs_da_state_t *state); STATIC int xfs_attr_refillstate(xfs_da_state_t *state); @@ -200,8 +200,7 @@ xfs_attr_calc_size( STATIC int xfs_attr_try_sf_addname( struct xfs_inode *dp, - struct xfs_da_args *args, - bool roll_trans) + struct xfs_da_args *args) { struct xfs_mount *mp = dp->i_mount; @@ -221,11 +220,6 @@ xfs_attr_try_sf_addname( if (mp->m_flags & XFS_MOUNT_WSYNC) xfs_trans_set_sync(args->trans); - if (roll_trans) { - error2 = xfs_trans_commit(args->trans); - args->trans = NULL; - } - return error ? error : error2; } @@ -236,8 +230,7 @@ int xfs_attr_set_args( struct xfs_da_args *args, struct xfs_buf **leaf_bp, - enum xfs_attr_state *state, - bool roll_trans) + enum xfs_attr_state *state) { struct xfs_inode *dp = args->dp; int error = 0; @@ -284,7 +277,7 @@ xfs_attr_set_args( /* * Try to add the attr to the attribute list in the inode. */ - error = xfs_attr_try_sf_addname(dp, args, roll_trans); + error = xfs_attr_try_sf_addname(dp, args); if (error != -ENOSPC) return error; @@ -306,23 +299,6 @@ xfs_attr_set_args( */ xfs_trans_bhold(args->trans, *leaf_bp); - if (roll_trans) { - error = xfs_defer_finish(&args->trans); - if (error) - return error; - - /* - * Commit the leaf transformation. We'll need another - * (linked) transaction to add the new attribute to the - * leaf. - */ - error = xfs_trans_roll_inode(&args->trans, dp); - if (error) - return error; - xfs_trans_bjoin(args->trans, *leaf_bp); - *leaf_bp = NULL; - } - *state = XFS_ATTR_STATE3; return -EAGAIN; state3: @@ -331,9 +307,9 @@ xfs_attr_set_args( } if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) - error = xfs_attr_leaf_addname(args, roll_trans); + error = xfs_attr_leaf_addname(args); else - error = xfs_attr_node_addname(args, roll_trans); + error = xfs_attr_node_addname(args); return error; } @@ -365,8 +341,7 @@ xfs_has_attr( */ int xfs_attr_remove_args( - struct xfs_da_args *args, - bool roll_trans) + struct xfs_da_args *args) { struct xfs_inode *dp = args->dp; int error; @@ -377,9 +352,9 @@ xfs_attr_remove_args( ASSERT(dp->i_afp->if_flags & XFS_IFINLINE); error = xfs_attr_shortform_remove(args); } else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) { - error = xfs_attr_leaf_removename(args, roll_trans); + error = xfs_attr_leaf_removename(args); } else { - error = xfs_attr_node_removename(args, roll_trans); + error = xfs_attr_node_removename(args); } return error; @@ -720,8 +695,7 @@ xfs_attr_shortform_addname(xfs_da_args_t *args) */ STATIC int xfs_attr_leaf_addname( - struct xfs_da_args *args, - bool roll_trans) + struct xfs_da_args *args) { struct xfs_inode *dp; struct xfs_buf *bp; @@ -787,37 +761,13 @@ xfs_attr_leaf_addname( if (error) return error; - if (roll_trans) { - 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; - } - /* * Fob the whole rest of the problem off on the Btree code. */ - error = xfs_attr_node_addname(args, roll_trans); + error = xfs_attr_node_addname(args); return error; } - if (roll_trans) { - /* - * Commit the transaction that added the attr name so that - * later routines can manage their own transactions. - */ - error = xfs_trans_roll_inode(&args->trans, dp); - if (error) - return error; - } - /* * If there was an out-of-line value, allocate the blocks we * identified for its storage and copy the value. This is done @@ -825,7 +775,7 @@ xfs_attr_leaf_addname( * maximum size of a transaction and/or hit a deadlock. */ if (args->rmtblkno > 0) { - error = xfs_attr_rmtval_set(args, roll_trans); + error = xfs_attr_rmtval_set(args); if (error) return error; } @@ -841,7 +791,7 @@ xfs_attr_leaf_addname( * In a separate transaction, set the incomplete flag on the * "old" attr and clear the incomplete flag on the "new" attr. */ - error = xfs_attr3_leaf_flipflags(args, roll_trans); + error = xfs_attr3_leaf_flipflags(args); if (error) return error; @@ -855,7 +805,7 @@ xfs_attr_leaf_addname( args->rmtblkcnt = args->rmtblkcnt2; args->rmtvaluelen = args->rmtvaluelen2; if (args->rmtblkno) { - error = xfs_attr_rmtval_remove(args, roll_trans); + error = xfs_attr_rmtval_remove(args); if (error) return error; } @@ -879,25 +829,13 @@ xfs_attr_leaf_addname( /* bp is gone due to xfs_da_shrink_inode */ if (error) return error; - - if (roll_trans) { - error = xfs_defer_finish(&args->trans); - if (error) - return error; - } } - /* - * Commit the remove and start the next trans in series. - */ - if (roll_trans) - error = xfs_trans_roll_inode(&args->trans, dp); - } else if (args->rmtblkno > 0) { /* * Added a "remote" value, just clear the incomplete flag. */ - error = xfs_attr3_leaf_clearflag(args, roll_trans); + error = xfs_attr3_leaf_clearflag(args); } return error; } @@ -933,8 +871,7 @@ xfs_leaf_has_attr( */ STATIC int xfs_attr_leaf_removename( - struct xfs_da_args *args, - bool roll_trans) + struct xfs_da_args *args) { struct xfs_inode *dp; struct xfs_buf *bp; @@ -967,12 +904,6 @@ xfs_attr_leaf_removename( /* bp is gone due to xfs_da_shrink_inode */ if (error) return error; - - if (roll_trans) { - error = xfs_defer_finish(&args->trans); - if (error) - return error; - } } return 0; } @@ -1025,8 +956,7 @@ xfs_attr_leaf_get(xfs_da_args_t *args) */ STATIC int xfs_attr_node_addname( - struct xfs_da_args *args, - bool roll_trans) + struct xfs_da_args *args) { struct xfs_da_state *state; struct xfs_da_state_blk *blk; @@ -1095,20 +1025,6 @@ xfs_attr_node_addname( if (error) goto out; - if (roll_trans) { - error = xfs_defer_finish(&args->trans); - if (error) - goto out; - - /* - * Commit the node conversion and start the next - * trans in the chain. - */ - error = xfs_trans_roll_inode(&args->trans, dp); - if (error) - goto out; - } - goto restart; } @@ -1122,12 +1038,6 @@ xfs_attr_node_addname( if (error) goto out; - if (roll_trans) { - error = xfs_defer_finish(&args->trans); - if (error) - goto out; - } - } else { /* * Addition succeeded, update Btree hashvals. @@ -1143,23 +1053,13 @@ xfs_attr_node_addname( state = NULL; /* - * Commit the leaf addition or btree split and start the next - * trans in the chain. - */ - if (roll_trans) { - error = xfs_trans_roll_inode(&args->trans, dp); - if (error) - goto out; - } - - /* * If there was an out-of-line value, allocate the blocks we * identified for its storage and copy the value. This is done * after we create the attribute so that we don't overflow the * maximum size of a transaction and/or hit a deadlock. */ if (args->rmtblkno > 0) { - error = xfs_attr_rmtval_set(args, roll_trans); + error = xfs_attr_rmtval_set(args); if (error) return error; } @@ -1175,7 +1075,7 @@ xfs_attr_node_addname( * In a separate transaction, set the incomplete flag on the * "old" attr and clear the incomplete flag on the "new" attr. */ - error = xfs_attr3_leaf_flipflags(args, roll_trans); + error = xfs_attr3_leaf_flipflags(args); if (error) goto out; @@ -1189,7 +1089,7 @@ xfs_attr_node_addname( args->rmtblkcnt = args->rmtblkcnt2; args->rmtvaluelen = args->rmtvaluelen2; if (args->rmtblkno) { - error = xfs_attr_rmtval_remove(args, roll_trans); + error = xfs_attr_rmtval_remove(args); if (error) return error; } @@ -1223,11 +1123,6 @@ xfs_attr_node_addname( error = xfs_da3_join(state); if (error) goto out; - if (roll_trans) { - error = xfs_defer_finish(&args->trans); - if (error) - goto out; - } } /* @@ -1241,7 +1136,7 @@ xfs_attr_node_addname( /* * Added a "remote" value, just clear the incomplete flag. */ - error = xfs_attr3_leaf_clearflag(args, roll_trans); + error = xfs_attr3_leaf_clearflag(args); if (error) goto out; } @@ -1294,8 +1189,7 @@ xfs_attr_node_hasname( */ STATIC int xfs_attr_node_removename( - struct xfs_da_args *args, - bool roll_trans) + struct xfs_da_args *args) { struct xfs_da_state *state; struct xfs_da_state_blk *blk; @@ -1345,10 +1239,10 @@ xfs_attr_node_removename( * Mark the attribute as INCOMPLETE, then bunmapi() the * remote value. */ - error = xfs_attr3_leaf_setflag(args, roll_trans); + error = xfs_attr3_leaf_setflag(args); if (error) goto out; - error = xfs_attr_rmtval_remove(args, roll_trans); + error = xfs_attr_rmtval_remove(args); if (error) goto out; @@ -1376,19 +1270,6 @@ xfs_attr_node_removename( error = xfs_da3_join(state); if (error) goto out; - - if (roll_trans) { - error = xfs_defer_finish(&args->trans); - if (error) - goto out; - /* - * Commit the Btree join operation and start - * a new trans. - */ - error = xfs_trans_roll_inode(&args->trans, dp); - if (error) - goto out; - } } /* @@ -1412,11 +1293,6 @@ xfs_attr_node_removename( if (error) goto out; - if (roll_trans) { - error = xfs_defer_finish(&args->trans); - if (error) - goto out; - } } else xfs_trans_brelse(args->trans, bp); } diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index da95e69..f369895 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -181,11 +181,11 @@ int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name, size_t namelen, unsigned char *value, int valuelen, int flags); int xfs_attr_set_args(struct xfs_da_args *args, struct xfs_buf **leaf_bp, - enum xfs_attr_state *state, bool roll_trans); + enum xfs_attr_state *state); int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, size_t namelen, int flags); int xfs_has_attr(struct xfs_da_args *args); -int xfs_attr_remove_args(struct xfs_da_args *args, bool roll_trans); +int xfs_attr_remove_args(struct xfs_da_args *args); int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize, int flags, struct attrlist_cursor_kern *cursor); bool xfs_attr_namecheck(const void *name, size_t length); diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index e9f2f53..90dfa53 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -2670,8 +2670,7 @@ xfs_attr_leaf_newentsize( */ int xfs_attr3_leaf_clearflag( - struct xfs_da_args *args, - bool roll_trans) + struct xfs_da_args *args) { struct xfs_attr_leafblock *leaf; struct xfs_attr_leaf_entry *entry; @@ -2729,11 +2728,6 @@ xfs_attr3_leaf_clearflag( XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); } - /* - * Commit the flag value change and start the next trans in series. - */ - if (roll_trans) - error = xfs_trans_roll_inode(&args->trans, args->dp); return error; } @@ -2742,8 +2736,7 @@ xfs_attr3_leaf_clearflag( */ int xfs_attr3_leaf_setflag( - struct xfs_da_args *args, - bool roll_trans) + struct xfs_da_args *args) { struct xfs_attr_leafblock *leaf; struct xfs_attr_leaf_entry *entry; @@ -2783,11 +2776,6 @@ xfs_attr3_leaf_setflag( XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); } - /* - * Commit the flag value change and start the next trans in series. - */ - if (roll_trans) - error = xfs_trans_roll_inode(&args->trans, args->dp); return error; } @@ -2800,8 +2788,7 @@ xfs_attr3_leaf_setflag( */ int xfs_attr3_leaf_flipflags( - struct xfs_da_args *args, - bool roll_trans) + struct xfs_da_args *args) { struct xfs_attr_leafblock *leaf1; struct xfs_attr_leafblock *leaf2; @@ -2904,11 +2891,5 @@ xfs_attr3_leaf_flipflags( XFS_DA_LOGRANGE(leaf2, name_rmt, sizeof(*name_rmt))); } - /* - * Commit the flag value change and start the next trans in series. - */ - if (roll_trans) - error = xfs_trans_roll_inode(&args->trans, args->dp); - return error; } diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h index 98dd169..d38c558 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.h +++ b/fs/xfs/libxfs/xfs_attr_leaf.h @@ -51,9 +51,9 @@ void xfs_attr_fork_remove(struct xfs_inode *ip, struct xfs_trans *tp); int xfs_attr3_leaf_to_node(struct xfs_da_args *args); int xfs_attr3_leaf_to_shortform(struct xfs_buf *bp, struct xfs_da_args *args, int forkoff); -int xfs_attr3_leaf_clearflag(struct xfs_da_args *args, bool roll_trans); -int xfs_attr3_leaf_setflag(struct xfs_da_args *args, bool roll_trans); -int xfs_attr3_leaf_flipflags(struct xfs_da_args *args, bool roll_trans); +int xfs_attr3_leaf_clearflag(struct xfs_da_args *args); +int xfs_attr3_leaf_setflag(struct xfs_da_args *args); +int xfs_attr3_leaf_flipflags(struct xfs_da_args *args); /* * Routines used for growing the Btree. diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 18fbd22..9054f98 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -435,8 +435,7 @@ xfs_attr_rmtval_get( */ int xfs_attr_rmtval_set( - struct xfs_da_args *args, - bool roll_trans) + struct xfs_da_args *args) { struct xfs_inode *dp = args->dp; struct xfs_mount *mp = dp->i_mount; @@ -490,26 +489,11 @@ xfs_attr_rmtval_set( if (error) return error; - if (roll_trans) { - error = xfs_defer_finish(&args->trans); - if (error) - return error; - } - ASSERT(nmap == 1); ASSERT((map.br_startblock != DELAYSTARTBLOCK) && (map.br_startblock != HOLESTARTBLOCK)); lblkno += map.br_blockcount; blkcnt -= map.br_blockcount; - - if (roll_trans) { - /* - * Start the next trans in the chain. - */ - error = xfs_trans_roll_inode(&args->trans, dp); - if (error) - return error; - } } /* @@ -569,8 +553,7 @@ xfs_attr_rmtval_set( */ int xfs_attr_rmtval_remove( - struct xfs_da_args *args, - bool roll_trans) + struct xfs_da_args *args) { struct xfs_mount *mp = args->dp->i_mount; xfs_dablk_t lblkno; @@ -632,19 +615,6 @@ xfs_attr_rmtval_remove( XFS_BMAPI_ATTRFORK, 1, &done); if (error) return error; - - if (roll_trans) { - error = xfs_defer_finish(&args->trans); - if (error) - return error; - - /* - * Close out trans and start the next one in the chain. - */ - error = xfs_trans_roll_inode(&args->trans, args->dp); - if (error) - return error; - } } return 0; } diff --git a/fs/xfs/libxfs/xfs_attr_remote.h b/fs/xfs/libxfs/xfs_attr_remote.h index c7c073d..9d20b66 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.h +++ b/fs/xfs/libxfs/xfs_attr_remote.h @@ -9,7 +9,7 @@ int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen); int xfs_attr_rmtval_get(struct xfs_da_args *args); -int xfs_attr_rmtval_set(struct xfs_da_args *args, bool roll_trans); -int xfs_attr_rmtval_remove(struct xfs_da_args *args, bool roll_trans); +int xfs_attr_rmtval_set(struct xfs_da_args *args); +int xfs_attr_rmtval_remove(struct xfs_da_args *args); #endif /* __XFS_ATTR_REMOTE_H__ */ diff --git a/fs/xfs/xfs_trans_attr.c b/fs/xfs/xfs_trans_attr.c index a3339ea..4144ecf 100644 --- a/fs/xfs/xfs_trans_attr.c +++ b/fs/xfs/xfs_trans_attr.c @@ -70,11 +70,11 @@ xfs_trans_attr( case XFS_ATTR_OP_FLAGS_SET: args->op_flags |= XFS_DA_OP_ADDNAME; error = xfs_attr_set_args(args, leaf_bp, - (enum xfs_attr_state *)state, false); + (enum xfs_attr_state *)state); break; case XFS_ATTR_OP_FLAGS_REMOVE: ASSERT(XFS_IFORK_Q((args->dp))); - error = xfs_attr_remove_args(args, false); + error = xfs_attr_remove_args(args); break; default: error = -EFSCORRUPTED;