From patchwork Fri Aug 23 00:28:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774474 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4CA0A17997 for ; Fri, 23 Aug 2024 00:28:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372893; cv=none; b=QLpqTrkJnm4cVmMoxcaXcSN3tDk300jbRgNrdBv9NEOwgDWxilqeU2nl5YJGwXxrRollcnxpNd5HAN5nC2RiQQWBPCmDSIafAAUzNAfu+RAgcYL2KhW/wqBLtpu8mv04A0GCwcty4+0bJ3uqYQTDj4za3FdVSxGgkXMlq/0tQAQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372893; c=relaxed/simple; bh=ZdVutQB3GDrydhvI4zJjHcYQYmne8bVnBoc8GHCFfA4=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=L3dBtn00ODj2bsDukUqHsu6OgzW59Pps2F1wRFjAxCzFiRoUmFrA+ji9OqW4vt6t0Vshhl/aEBETWCtzdiHmAkgj/i8cla+7NE1hbccm222W5gMIR/akKz85QAwN+4K3JYDvy2C7oupnQCvObFCOCyu8wpiZfMbiwW14oaUdwLQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mg3Wgqzl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="mg3Wgqzl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 24AB1C32782; Fri, 23 Aug 2024 00:28:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372893; bh=ZdVutQB3GDrydhvI4zJjHcYQYmne8bVnBoc8GHCFfA4=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=mg3WgqzlPMNWVHHRh+qHOMCqiGfk6WgFSwQHfDNlUpNIZ4SYhHdR5F+O2CBBwq0Wz c0uwWvdGiy0EB+sxIVHLTC6hf/B++2CR0IMx0p3LDOD6pJUKQS8w41rP9eXrOM+J8O zvffij4IiswqcLV7abyrP02AQBxa8z0giRgwGpTzYTFgVrhj3sUVI/FRqyK8QBWUzs eUa1iNzuhe+vazkvgcv+wEW2esDANSmV0IlpgAZK/s+wFYFHUMNGfBuR7K4K2Jv9pJ qGW6oIgRJ3SGzi4LvPMSMXUgBH6H8I7y5QenlapoqIgkJT6Jwe4C2AP4XR/ofwpIMD 08Ka3yIGqSGeA== Date: Thu, 22 Aug 2024 17:28:12 -0700 Subject: [PATCH 1/6] xfs: refactor xfs_qm_destroy_quotainos From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437089380.61495.10149120499984603964.stgit@frogsfrogsfrogs> In-Reply-To: <172437089342.61495.12289421749855228771.stgit@frogsfrogsfrogs> References: <172437089342.61495.12289421749855228771.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Reuse this function instead of open-coding the logic. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_qm.c | 53 ++++++++++++++++++++--------------------------------- 1 file changed, 20 insertions(+), 33 deletions(-) diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index 28b1420bac1dd..b37e80fe7e86a 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -40,7 +40,6 @@ STATIC int xfs_qm_init_quotainos(struct xfs_mount *mp); STATIC int xfs_qm_init_quotainfo(struct xfs_mount *mp); -STATIC void xfs_qm_destroy_quotainos(struct xfs_quotainfo *qi); STATIC void xfs_qm_dqfree_one(struct xfs_dquot *dqp); /* * We use the batch lookup interface to iterate over the dquots as it @@ -226,6 +225,24 @@ xfs_qm_unmount_rt( xfs_rtgroup_rele(rtg); } +STATIC void +xfs_qm_destroy_quotainos( + struct xfs_quotainfo *qi) +{ + if (qi->qi_uquotaip) { + xfs_irele(qi->qi_uquotaip); + qi->qi_uquotaip = NULL; /* paranoia */ + } + if (qi->qi_gquotaip) { + xfs_irele(qi->qi_gquotaip); + qi->qi_gquotaip = NULL; + } + if (qi->qi_pquotaip) { + xfs_irele(qi->qi_pquotaip); + qi->qi_pquotaip = NULL; + } +} + /* * Called from the vfsops layer. */ @@ -250,20 +267,8 @@ xfs_qm_unmount_quotas( /* * Release the quota inodes. */ - if (mp->m_quotainfo) { - if (mp->m_quotainfo->qi_uquotaip) { - xfs_irele(mp->m_quotainfo->qi_uquotaip); - mp->m_quotainfo->qi_uquotaip = NULL; - } - if (mp->m_quotainfo->qi_gquotaip) { - xfs_irele(mp->m_quotainfo->qi_gquotaip); - mp->m_quotainfo->qi_gquotaip = NULL; - } - if (mp->m_quotainfo->qi_pquotaip) { - xfs_irele(mp->m_quotainfo->qi_pquotaip); - mp->m_quotainfo->qi_pquotaip = NULL; - } - } + if (mp->m_quotainfo) + xfs_qm_destroy_quotainos(mp->m_quotainfo); } STATIC int @@ -1712,24 +1717,6 @@ xfs_qm_init_quotainos( return error; } -STATIC void -xfs_qm_destroy_quotainos( - struct xfs_quotainfo *qi) -{ - if (qi->qi_uquotaip) { - xfs_irele(qi->qi_uquotaip); - qi->qi_uquotaip = NULL; /* paranoia */ - } - if (qi->qi_gquotaip) { - xfs_irele(qi->qi_gquotaip); - qi->qi_gquotaip = NULL; - } - if (qi->qi_pquotaip) { - xfs_irele(qi->qi_pquotaip); - qi->qi_pquotaip = NULL; - } -} - STATIC void xfs_qm_dqfree_one( struct xfs_dquot *dqp) From patchwork Fri Aug 23 00:28:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774475 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ECF6118026 for ; Fri, 23 Aug 2024 00:28:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372909; cv=none; b=aWai/b1pgO+inhMCZSrsbg9kXMcQet5O9dOsQ8juVErFSinsaJ0uRZGgBhcp+OV7UmBgr8aEGR4jKO5wQXrYZbpCzFm57UNhX/1jHevEqF8ekfdBdTNUhBv8nBxrxXCIKq+C6vY3lCZYf/bennwfSC9VduqdlixuytqtNSMSKxc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372909; c=relaxed/simple; bh=Kncep7ujPpTP/pckBa8JwRQvAHOouu97V9awC5cH4jQ=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XlkzEOu/AYmZoduCDhqOivwhamqW+D+q3DHbmQ7u8HCUQBLw5CdbahwAs9zOY8ROuON0pPHcrwXET2drulLozHJ9WWcw/PhibAs38cs37RvAmwGRbTsYLqvtOE83dJYbyjUCCAvmuXn7E61hfkh9iogYW11Bvvr+YNuk0B9Qnn8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VnIjkFku; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VnIjkFku" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C7232C32782; Fri, 23 Aug 2024 00:28:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372908; bh=Kncep7ujPpTP/pckBa8JwRQvAHOouu97V9awC5cH4jQ=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=VnIjkFkuDb+FjDkqkGN7Q7whjuOf3+Z8zDtEdChfw0bwKZLqPwkncs0eybFeTiUSY Nf3StmAg7+cihqrLxkgmWMSGye6uM8624Q0vWPm8kHCp9SyhhKHx/gyuS4UfNqd6Cv bEyKo3n/yksHiT2l2YPx+gX2IzrTcDgywhZ+6HUGA0cdlsg7ETN4tekjKk6KiUO3QS /TPSZu1lvTeqPI6pMkiHGpT3CCzl4emLD50S28YJZaH/4LT5533cMQMvsU9I9TbHil 6YQJtFOXQOhk/NMumXzi4yiM6L1JGPIPJDb0GgbHh1GP1Qi661EX2DOiEX3zxwU0wg a/qcaJuXytiPw== Date: Thu, 22 Aug 2024 17:28:28 -0700 Subject: [PATCH 2/6] xfs: use metadir for quota inodes From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437089397.61495.2669421430531282333.stgit@frogsfrogsfrogs> In-Reply-To: <172437089342.61495.12289421749855228771.stgit@frogsfrogsfrogs> References: <172437089342.61495.12289421749855228771.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Store the quota inodes in a metadata directory if metadir is enabled. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_dquot_buf.c | 190 +++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_quota_defs.h | 43 +++++++++ fs/xfs/libxfs/xfs_sb.c | 1 fs/xfs/xfs_qm.c | 197 +++++++++++++++++++++++++++++++++++----- 4 files changed, 407 insertions(+), 24 deletions(-) diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c index 15a362e2f5ea7..dceef2abd4e2a 100644 --- a/fs/xfs/libxfs/xfs_dquot_buf.c +++ b/fs/xfs/libxfs/xfs_dquot_buf.c @@ -16,6 +16,9 @@ #include "xfs_trans.h" #include "xfs_qm.h" #include "xfs_error.h" +#include "xfs_health.h" +#include "xfs_metadir.h" +#include "xfs_metafile.h" int xfs_calc_dquots_per_chunk( @@ -323,3 +326,190 @@ xfs_dquot_to_disk_ts( return cpu_to_be32(t); } + +inline unsigned int +xfs_dqinode_sick_mask(xfs_dqtype_t type) +{ + switch (type) { + case XFS_DQTYPE_USER: + return XFS_SICK_FS_UQUOTA; + case XFS_DQTYPE_GROUP: + return XFS_SICK_FS_GQUOTA; + case XFS_DQTYPE_PROJ: + return XFS_SICK_FS_PQUOTA; + } + + ASSERT(0); + return 0; +} + +/* + * Load the inode for a given type of quota, assuming that the sb fields have + * been sorted out. This is not true when switching quota types on a V4 + * filesystem, so do not use this function for that. If metadir is enabled, + * @dp must be the /quota metadir. + * + * Returns -ENOENT if the quota inode field is NULLFSINO; 0 and an inode on + * success; or a negative errno. + */ +int +xfs_dqinode_load( + struct xfs_trans *tp, + struct xfs_inode *dp, + xfs_dqtype_t type, + struct xfs_inode **ipp) +{ + struct xfs_mount *mp = tp->t_mountp; + struct xfs_inode *ip; + enum xfs_metafile_type metafile_type = xfs_dqinode_metafile_type(type); + int error; + + if (!xfs_has_metadir(mp)) { + xfs_ino_t ino; + + switch (type) { + case XFS_DQTYPE_USER: + ino = mp->m_sb.sb_uquotino; + break; + case XFS_DQTYPE_GROUP: + ino = mp->m_sb.sb_gquotino; + break; + case XFS_DQTYPE_PROJ: + ino = mp->m_sb.sb_pquotino; + break; + default: + ASSERT(0); + return -EFSCORRUPTED; + } + + /* Should have set 0 to NULLFSINO when loading superblock */ + if (ino == NULLFSINO) + return -ENOENT; + + error = xfs_trans_metafile_iget(tp, ino, metafile_type, &ip); + } else { + error = xfs_metadir_load(tp, dp, xfs_dqinode_path(type), + metafile_type, &ip); + if (error == -ENOENT) + return error; + } + if (error) { + if (xfs_metadata_is_sick(error)) + xfs_fs_mark_sick(mp, xfs_dqinode_sick_mask(type)); + return error; + } + + if (XFS_IS_CORRUPT(mp, ip->i_df.if_format != XFS_DINODE_FMT_EXTENTS && + ip->i_df.if_format != XFS_DINODE_FMT_BTREE)) { + xfs_irele(ip); + xfs_fs_mark_sick(mp, xfs_dqinode_sick_mask(type)); + return -EFSCORRUPTED; + } + + if (XFS_IS_CORRUPT(mp, ip->i_projid != 0)) { + xfs_irele(ip); + xfs_fs_mark_sick(mp, xfs_dqinode_sick_mask(type)); + return -EFSCORRUPTED; + } + + *ipp = ip; + return 0; +} + +/* Create a metadata directory quota inode. */ +int +xfs_dqinode_metadir_create( + struct xfs_inode *dp, + xfs_dqtype_t type, + struct xfs_inode **ipp) +{ + struct xfs_metadir_update upd = { + .dp = dp, + .metafile_type = xfs_dqinode_metafile_type(type), + .path = xfs_dqinode_path(type), + }; + int error; + + error = xfs_metadir_start_create(&upd); + if (error) + return error; + + error = xfs_metadir_create(&upd, S_IFREG); + if (error) + return error; + + xfs_trans_log_inode(upd.tp, upd.ip, XFS_ILOG_CORE); + + error = xfs_metadir_commit(&upd); + if (error) + return error; + + xfs_finish_inode_setup(upd.ip); + *ipp = upd.ip; + return 0; +} + +#ifndef __KERNEL__ +/* Link a metadata directory quota inode. */ +int +xfs_dqinode_metadir_link( + struct xfs_inode *dp, + xfs_dqtype_t type, + struct xfs_inode *ip) +{ + struct xfs_metadir_update upd = { + .dp = dp, + .metafile_type = xfs_dqinode_metafile_type(type), + .path = xfs_dqinode_path(type), + .ip = ip, + }; + int error; + + error = xfs_metadir_start_link(&upd); + if (error) + return error; + + error = xfs_metadir_link(&upd); + if (error) + return error; + + xfs_trans_log_inode(upd.tp, upd.ip, XFS_ILOG_CORE); + + return xfs_metadir_commit(&upd); +} +#endif /* __KERNEL__ */ + +/* Create the parent directory for all quota inodes and load it. */ +int +xfs_dqinode_mkdir_parent( + struct xfs_mount *mp, + struct xfs_inode **dpp) +{ + if (!mp->m_metadirip) { + xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR); + return -EFSCORRUPTED; + } + + return xfs_metadir_mkdir(mp->m_metadirip, "quota", dpp); +} + +/* + * Load the parent directory of all quota inodes. Pass the inode to the caller + * because quota functions (e.g. QUOTARM) can be called on the quota files even + * if quotas are not enabled. + */ +int +xfs_dqinode_load_parent( + struct xfs_trans *tp, + struct xfs_inode **dpp) +{ + struct xfs_mount *mp = tp->t_mountp; + + if (!mp->m_metadirip) { + xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR); + return -EFSCORRUPTED; + } + + return xfs_metadir_load(tp, mp->m_metadirip, "quota", XFS_METAFILE_DIR, + dpp); +} diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h index fb05f44f6c754..763d941a8420c 100644 --- a/fs/xfs/libxfs/xfs_quota_defs.h +++ b/fs/xfs/libxfs/xfs_quota_defs.h @@ -143,4 +143,47 @@ time64_t xfs_dquot_from_disk_ts(struct xfs_disk_dquot *ddq, __be32 dtimer); __be32 xfs_dquot_to_disk_ts(struct xfs_dquot *ddq, time64_t timer); +static inline const char * +xfs_dqinode_path(xfs_dqtype_t type) +{ + switch (type) { + case XFS_DQTYPE_USER: + return "user"; + case XFS_DQTYPE_GROUP: + return "group"; + case XFS_DQTYPE_PROJ: + return "project"; + } + + ASSERT(0); + return NULL; +} + +static inline enum xfs_metafile_type +xfs_dqinode_metafile_type(xfs_dqtype_t type) +{ + switch (type) { + case XFS_DQTYPE_USER: + return XFS_METAFILE_USRQUOTA; + case XFS_DQTYPE_GROUP: + return XFS_METAFILE_GRPQUOTA; + case XFS_DQTYPE_PROJ: + return XFS_METAFILE_PRJQUOTA; + } + + ASSERT(0); + return XFS_METAFILE_UNKNOWN; +} + +unsigned int xfs_dqinode_sick_mask(xfs_dqtype_t type); + +int xfs_dqinode_load(struct xfs_trans *tp, struct xfs_inode *dp, + xfs_dqtype_t type, struct xfs_inode **ipp); +int xfs_dqinode_metadir_create(struct xfs_inode *dp, xfs_dqtype_t type, + struct xfs_inode **ipp); +int xfs_dqinode_metadir_link(struct xfs_inode *dp, xfs_dqtype_t type, + struct xfs_inode *ip); +int xfs_dqinode_mkdir_parent(struct xfs_mount *mp, struct xfs_inode **dpp); +int xfs_dqinode_load_parent(struct xfs_trans *tp, struct xfs_inode **dpp); + #endif /* __XFS_QUOTA_H__ */ diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 3dc6d272519ba..2f5ccd6e7a662 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -816,6 +816,7 @@ xfs_sb_quota_to_disk( uint16_t qflags = from->sb_qflags; if (xfs_sb_version_hasmetadir(from)) { + to->sb_qflags = cpu_to_be16(from->sb_qflags); to->sb_uquotino = cpu_to_be64(0); to->sb_gquotino = cpu_to_be64(0); to->sb_pquotino = cpu_to_be64(0); diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index b37e80fe7e86a..d9d09195eabb0 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -645,6 +645,157 @@ xfs_qm_init_timelimits( xfs_qm_dqdestroy(dqp); } +static int +xfs_qm_load_metadir_qinos( + struct xfs_mount *mp, + struct xfs_quotainfo *qi, + struct xfs_inode **dpp) +{ + struct xfs_trans *tp; + int error; + + error = xfs_trans_alloc_empty(mp, &tp); + if (error) + return error; + + error = xfs_dqinode_load_parent(tp, dpp); + if (error == -ENOENT) { + /* no quota dir directory, but we'll create one later */ + error = 0; + goto out_trans; + } + if (error) + goto out_trans; + + if (XFS_IS_UQUOTA_ON(mp)) { + error = xfs_dqinode_load(tp, *dpp, XFS_DQTYPE_USER, + &qi->qi_uquotaip); + if (error && error != -ENOENT) + goto out_trans; + } + + if (XFS_IS_GQUOTA_ON(mp)) { + error = xfs_dqinode_load(tp, *dpp, XFS_DQTYPE_GROUP, + &qi->qi_gquotaip); + if (error && error != -ENOENT) + goto out_trans; + } + + if (XFS_IS_PQUOTA_ON(mp)) { + error = xfs_dqinode_load(tp, *dpp, XFS_DQTYPE_PROJ, + &qi->qi_pquotaip); + if (error && error != -ENOENT) + goto out_trans; + } + + error = 0; +out_trans: + xfs_trans_cancel(tp); + return error; +} + +/* Create quota inodes in the metadata directory tree. */ +STATIC int +xfs_qm_create_metadir_qinos( + struct xfs_mount *mp, + struct xfs_quotainfo *qi, + struct xfs_inode **dpp) +{ + int error; + + if (!*dpp) { + error = xfs_dqinode_mkdir_parent(mp, dpp); + if (error && error != -EEXIST) + return error; + } + + if (XFS_IS_UQUOTA_ON(mp) && !qi->qi_uquotaip) { + error = xfs_dqinode_metadir_create(*dpp, XFS_DQTYPE_USER, + &qi->qi_uquotaip); + if (error) + return error; + } + + if (XFS_IS_GQUOTA_ON(mp) && !qi->qi_gquotaip) { + error = xfs_dqinode_metadir_create(*dpp, XFS_DQTYPE_GROUP, + &qi->qi_gquotaip); + if (error) + return error; + } + + if (XFS_IS_PQUOTA_ON(mp) && !qi->qi_pquotaip) { + error = xfs_dqinode_metadir_create(*dpp, XFS_DQTYPE_PROJ, + &qi->qi_pquotaip); + if (error) + return error; + } + + return 0; +} + +/* + * Add QUOTABIT to sb_versionnum and initialize qflags in preparation for + * creating quota files on a metadir filesystem. + */ +STATIC int +xfs_qm_prep_metadir_sb( + struct xfs_mount *mp) +{ + struct xfs_trans *tp; + int error; + + error = xfs_trans_alloc(mp, &M_RES(mp)->tr_sb, 0, 0, 0, &tp); + if (error) + return error; + + spin_lock(&mp->m_sb_lock); + + xfs_add_quota(mp); + + /* qflags will get updated fully _after_ quotacheck */ + mp->m_sb.sb_qflags = mp->m_qflags & XFS_ALL_QUOTA_ACCT; + + spin_unlock(&mp->m_sb_lock); + xfs_log_sb(tp); + + return xfs_trans_commit(tp); +} + +/* + * Load existing quota inodes or create them. Since this is a V5 filesystem, + * we don't have to deal with the grp/prjquota switcheroo thing from V4. + */ +STATIC int +xfs_qm_init_metadir_qinos( + struct xfs_mount *mp) +{ + struct xfs_quotainfo *qi = mp->m_quotainfo; + struct xfs_inode *dp = NULL; + int error; + + if (!xfs_has_quota(mp)) { + error = xfs_qm_prep_metadir_sb(mp); + if (error) + return error; + } + + error = xfs_qm_load_metadir_qinos(mp, qi, &dp); + if (error) + goto out_err; + + error = xfs_qm_create_metadir_qinos(mp, qi, &dp); + if (error) + goto out_err; + + xfs_irele(dp); + return 0; +out_err: + xfs_qm_destroy_quotainos(mp->m_quotainfo); + if (dp) + xfs_irele(dp); + return error; +} + /* * This initializes all the quota information that's kept in the * mount structure @@ -669,7 +820,10 @@ xfs_qm_init_quotainfo( * See if quotainodes are setup, and if not, allocate them, * and change the superblock accordingly. */ - error = xfs_qm_init_quotainos(mp); + if (xfs_has_metadir(mp)) + error = xfs_qm_init_metadir_qinos(mp); + else + error = xfs_qm_init_quotainos(mp); if (error) goto out_free_lru; @@ -1581,7 +1735,7 @@ xfs_qm_mount_quotas( } if (error) { - xfs_warn(mp, "Failed to initialize disk quotas."); + xfs_warn(mp, "Failed to initialize disk quotas, err %d.", error); return; } } @@ -1600,31 +1754,26 @@ xfs_qm_qino_load( xfs_dqtype_t type, struct xfs_inode **ipp) { - xfs_ino_t ino = NULLFSINO; - enum xfs_metafile_type metafile_type = XFS_METAFILE_UNKNOWN; + struct xfs_trans *tp; + struct xfs_inode *dp = NULL; + int error; - switch (type) { - case XFS_DQTYPE_USER: - ino = mp->m_sb.sb_uquotino; - metafile_type = XFS_METAFILE_USRQUOTA; - break; - case XFS_DQTYPE_GROUP: - ino = mp->m_sb.sb_gquotino; - metafile_type = XFS_METAFILE_GRPQUOTA; - break; - case XFS_DQTYPE_PROJ: - ino = mp->m_sb.sb_pquotino; - metafile_type = XFS_METAFILE_PRJQUOTA; - break; - default: - ASSERT(0); - return -EFSCORRUPTED; + error = xfs_trans_alloc_empty(mp, &tp); + if (error) + return error; + + if (xfs_has_metadir(mp)) { + error = xfs_dqinode_load_parent(tp, &dp); + if (error) + goto out_cancel; } - if (ino == NULLFSINO) - return -ENOENT; - - return xfs_metafile_iget(mp, ino, metafile_type, ipp); + error = xfs_dqinode_load(tp, dp, type, ipp); + if (dp) + xfs_irele(dp); +out_cancel: + xfs_trans_cancel(tp); + return error; } /* From patchwork Fri Aug 23 00:28:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774476 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 91CE018B14 for ; Fri, 23 Aug 2024 00:28:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372924; cv=none; b=AgU6CKCD0LWoMYR2Vbi0mXL9QjTsgOTcTytK/Y30tE5Hyg3NH0Q/CoM9I+uOdYnbM3kyJgGDyFTs6EFPeCGDScDYluOT4PMXl2QGLPTs7Zspdq6Ot+T1sISGnC3htLLUUcBzuSTd1VeKW/3Tni0viDvW0w6pGDgJJxAFpV2qXE4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372924; c=relaxed/simple; bh=MGnuWMDxrgZ8AwSNoFf+NAnsIndXpzU6mJYcDrYV67g=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CKoJEMveWJRUxwHW6FvELksKW+zKcdg8tb4bHfM11NAbdnpfxRA+LDmudRqKU1nxoKBYXBxrKUoPp/M6Zy7kyhtB3iCh/O/0V38I4y/wMPQQ2OkcjHhOPSE9Gjix6uc432fqMDyBRP9+Nvn+XxC/inBJ94/3jxQcLenedQ4TB90= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=UX9z+f/O; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="UX9z+f/O" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 69A7DC32782; Fri, 23 Aug 2024 00:28:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372924; bh=MGnuWMDxrgZ8AwSNoFf+NAnsIndXpzU6mJYcDrYV67g=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=UX9z+f/O4kctNfmkRZ/iG40fTYuWpJ4QbUEB6JwsGeLKfcx8S+N35aSTMRBD4ltF3 DtHNbM9WRVxU0s3eq8tXfsw/twWYgkJk/wf2mpepd/4C8EEpPqmHed6lQve0Zq6rNf HhRKhpS8bx7hMM/Nwyay+9aAMdfCxjGyszBTKNPT/uDAAK8zD7u2ALbyWOKpY31huR N5uZyvBsxlAumh02acaqx1VmWYJG+1pBSLhI1mLblPCY9HL8NE7ZAjf7z9zBJdacW/ iMgtke4OzkH3YLJ/JEXk2YuJK8LF3KOrK8/1m8ceg9zmKeYMry5jf/AS1W7M98Neym oN56WuJFa4Ctg== Date: Thu, 22 Aug 2024 17:28:43 -0700 Subject: [PATCH 3/6] xfs: scrub quota file metapaths From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437089414.61495.2473580313151427630.stgit@frogsfrogsfrogs> In-Reply-To: <172437089342.61495.12289421749855228771.stgit@frogsfrogsfrogs> References: <172437089342.61495.12289421749855228771.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Enable online fsck for quota file metadata directory paths. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_fs.h | 6 +++- fs/xfs/scrub/metapath.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index 11fa3d0c38086..d460946cae8f1 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -825,9 +825,13 @@ struct xfs_scrub_vec_head { #define XFS_SCRUB_METAPATH_RTDIR (1) /* rtrgroups metadir */ #define XFS_SCRUB_METAPATH_RTBITMAP (2) /* per-rtg bitmap */ #define XFS_SCRUB_METAPATH_RTSUMMARY (3) /* per-rtg summary */ +#define XFS_SCRUB_METAPATH_QUOTADIR (4) /* quota metadir */ +#define XFS_SCRUB_METAPATH_USRQUOTA (5) /* user quota */ +#define XFS_SCRUB_METAPATH_GRPQUOTA (6) /* group quota */ +#define XFS_SCRUB_METAPATH_PRJQUOTA (7) /* project quota */ /* Number of metapath sm_ino values */ -#define XFS_SCRUB_METAPATH_NR (4) +#define XFS_SCRUB_METAPATH_NR (8) /* * ioctl limits diff --git a/fs/xfs/scrub/metapath.c b/fs/xfs/scrub/metapath.c index e5714655152db..49ea19edc1492 100644 --- a/fs/xfs/scrub/metapath.c +++ b/fs/xfs/scrub/metapath.c @@ -165,6 +165,74 @@ xchk_setup_metapath_rtginode( # define xchk_setup_metapath_rtginode(...) (-ENOENT) #endif /* CONFIG_XFS_RT */ +#ifdef CONFIG_XFS_QUOTA +/* Scan the /quota directory itself. */ +static int +xchk_setup_metapath_quotadir( + struct xfs_scrub *sc) +{ + struct xfs_trans *tp; + struct xfs_inode *dp = NULL; + int error; + + error = xfs_trans_alloc_empty(sc->mp, &tp); + if (error) + return error; + + error = xfs_dqinode_load_parent(tp, &dp); + xfs_trans_cancel(tp); + if (error) + return error; + + error = xchk_setup_metapath_scan(sc, sc->mp->m_metadirip, + kasprintf(GFP_KERNEL, "quota"), dp); + xfs_irele(dp); + return error; +} + +/* Scan a quota inode under the /quota directory. */ +static int +xchk_setup_metapath_dqinode( + struct xfs_scrub *sc, + xfs_dqtype_t type) +{ + struct xfs_trans *tp = NULL; + struct xfs_inode *dp = NULL; + struct xfs_inode *ip = NULL; + const char *path; + int error; + + error = xfs_trans_alloc_empty(sc->mp, &tp); + if (error) + return error; + + error = xfs_dqinode_load_parent(tp, &dp); + if (error) + goto out_cancel; + + error = xfs_dqinode_load(tp, dp, type, &ip); + if (error) + goto out_dp; + + xfs_trans_cancel(tp); + tp = NULL; + + path = kasprintf(GFP_KERNEL, "%s", xfs_dqinode_path(type)); + error = xchk_setup_metapath_scan(sc, dp, path, ip); + + xfs_irele(ip); +out_dp: + xfs_irele(dp); +out_cancel: + if (tp) + xfs_trans_cancel(tp); + return error; +} +#else +# define xchk_setup_metapath_quotadir(...) (-ENOENT) +# define xchk_setup_metapath_dqinode(...) (-ENOENT) +#endif /* CONFIG_XFS_QUOTA */ + int xchk_setup_metapath( struct xfs_scrub *sc) @@ -186,6 +254,14 @@ xchk_setup_metapath( return xchk_setup_metapath_rtginode(sc, XFS_RTGI_BITMAP); case XFS_SCRUB_METAPATH_RTSUMMARY: return xchk_setup_metapath_rtginode(sc, XFS_RTGI_SUMMARY); + case XFS_SCRUB_METAPATH_QUOTADIR: + return xchk_setup_metapath_quotadir(sc); + case XFS_SCRUB_METAPATH_USRQUOTA: + return xchk_setup_metapath_dqinode(sc, XFS_DQTYPE_USER); + case XFS_SCRUB_METAPATH_GRPQUOTA: + return xchk_setup_metapath_dqinode(sc, XFS_DQTYPE_GROUP); + case XFS_SCRUB_METAPATH_PRJQUOTA: + return xchk_setup_metapath_dqinode(sc, XFS_DQTYPE_PROJ); default: return -ENOENT; } From patchwork Fri Aug 23 00:28:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774477 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3F20BB653 for ; Fri, 23 Aug 2024 00:29:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372940; cv=none; b=p+Zf3IoUzg3gTRUthapEOK0F26J+AtV8nBwUtvgLD3Mkaq7mELeqfm7vGIUV/mFuA4BZ3ztQH2CkmVUyqonKU3fHMFNCjWkfSNyKhcbk3oP+EM/6LsK2NEYlUEM8/QlifdWXKNmAZWiR3dp1Y1NtiTL9NcYOI5x5LemLtoSbruI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372940; c=relaxed/simple; bh=G0RHyyVoWqK0I9L730r1frFQT7tlsaPmsaiAm7md5qc=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=h9RqmqEqgDWRuQJqEO96eaFMxJkhQBKyNjr9CTOSlcKU/DtKsNLSkkrASv+1MY2KaY2Do9sjlzZlw8Ro/0uecMs40oGP4j2twN9e0G5d/JwoEyMcBnV8O0oGZciDODo9xa9TgB6gFl1jfHoMrzG6UJOmf+YUjyMnANZkdxwS3n8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aBWxH3Ts; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="aBWxH3Ts" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 192CBC32782; Fri, 23 Aug 2024 00:29:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372940; bh=G0RHyyVoWqK0I9L730r1frFQT7tlsaPmsaiAm7md5qc=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=aBWxH3Tsv80o02JUNZTopkAlXsDn8v41x1ONuW5uDXERq75+SDkQFONg1IDQCKOA4 +L2Nf62aNsVxQwxRSJGtsBaUlfvX86L5r58+20tior7AfbMl7Bh5N7+qu6EZ9f/D/y ACzeQRx5ONfk0G1fjt23cIzNLFfFonbBnjMWxBP70QTQC4j0r9fPNH5QTrEgy4krx5 TZVjQmXEX3RtakgfV7z2bo2Gi6FvwL3HVf53BI4ItmFTlCrDF/aUlPzCkc8bQdWmWx vuQYnLezz+PhG6js9/1d6yBWdOeaQkj/OFGxDFWm+wdbpaAQdI7b91ZtEsgMkL1cHx NuQ+0iJI2QQEg== Date: Thu, 22 Aug 2024 17:28:59 -0700 Subject: [PATCH 4/6] xfs: persist quota flags with metadir From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437089432.61495.8117184114353548540.stgit@frogsfrogsfrogs> In-Reply-To: <172437089342.61495.12289421749855228771.stgit@frogsfrogsfrogs> References: <172437089342.61495.12289421749855228771.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong It's annoying that one has to keep reminding XFS about what quota options it should mount with, since the quota flags recording the previous state are sitting right there in the primary superblock. Even more strangely, there exists a noquota option to disable quotas completely, so it's odder still that providing no options is the same as noquota. Starting with metadir, let's change the behavior so that if the user does not specify any quota-related mount options at all, the ondisk quota flags will be used to bring up quota. In other words, the filesystem will mount in the same state and with the same functionality as it had during the last mount. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_mount.c | 15 +++++++++++++++ fs/xfs/xfs_mount.h | 6 ++++++ fs/xfs/xfs_qm_bhv.c | 18 ++++++++++++++++++ fs/xfs/xfs_quota.h | 2 ++ fs/xfs/xfs_super.c | 22 ++++++++++++++++++++++ 5 files changed, 63 insertions(+) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 5726ea597f5a2..cbf47354561c1 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -850,6 +850,13 @@ xfs_mountfs( if (error) goto out_fail_wait; + /* + * If we're resuming quota status, pick up the preliminary qflags from + * the ondisk superblock so that we know if we should recover dquots. + */ + if (xfs_is_resuming_quotaon(mp)) + xfs_qm_resume_quotaon(mp); + /* * Log's mount-time initialization. The first part of recovery can place * some items on the AIL, to be handled when recovery is finished or @@ -863,6 +870,14 @@ xfs_mountfs( goto out_inodegc_shrinker; } + /* + * If we're resuming quota status and recovered the log, re-sample the + * qflags from the ondisk superblock now that we've recovered it, just + * in case someone shut down enforcement just before a crash. + */ + if (xfs_clear_resuming_quotaon(mp) && xlog_recovery_needed(mp->m_log)) + xfs_qm_resume_quotaon(mp); + /* * If logged xattrs are still enabled after log recovery finishes, then * they'll be available until unmount. Otherwise, turn them off. diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 7e68812db1be7..ba9af63aec143 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -459,6 +459,8 @@ __XFS_HAS_FEAT(nouuid, NOUUID) #define XFS_OPSTATE_UNSET_LOG_INCOMPAT 11 /* Filesystem can use logged extended attributes */ #define XFS_OPSTATE_USE_LARP 12 +/* Filesystem should use qflags to determine quotaon status */ +#define XFS_OPSTATE_RESUMING_QUOTAON 13 #define __XFS_IS_OPSTATE(name, NAME) \ static inline bool xfs_is_ ## name (struct xfs_mount *mp) \ @@ -483,8 +485,12 @@ __XFS_IS_OPSTATE(inodegc_enabled, INODEGC_ENABLED) __XFS_IS_OPSTATE(blockgc_enabled, BLOCKGC_ENABLED) #ifdef CONFIG_XFS_QUOTA __XFS_IS_OPSTATE(quotacheck_running, QUOTACHECK_RUNNING) +__XFS_IS_OPSTATE(resuming_quotaon, RESUMING_QUOTAON) #else # define xfs_is_quotacheck_running(mp) (false) +# define xfs_is_resuming_quotaon(mp) (false) +# define xfs_set_resuming_quotaon(mp) (false) +# define xfs_clear_resuming_quotaon(mp) (false) #endif __XFS_IS_OPSTATE(done_with_log_incompat, UNSET_LOG_INCOMPAT) __XFS_IS_OPSTATE(using_logged_xattrs, USE_LARP) diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c index a11436579877d..79a96558f739e 100644 --- a/fs/xfs/xfs_qm_bhv.c +++ b/fs/xfs/xfs_qm_bhv.c @@ -135,3 +135,21 @@ xfs_qm_newmount( return 0; } + +/* + * If the sysadmin didn't provide any quota mount options, restore the quota + * accounting and enforcement state from the ondisk superblock. Only do this + * for metadir filesystems because this is a behavior change. + */ +void +xfs_qm_resume_quotaon( + struct xfs_mount *mp) +{ + if (!xfs_has_metadir(mp)) + return; + if (xfs_has_norecovery(mp)) + return; + + mp->m_qflags = mp->m_sb.sb_qflags & (XFS_ALL_QUOTA_ACCT | + XFS_ALL_QUOTA_ENFD); +} diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h index 645761997bf2d..2d36d967380e7 100644 --- a/fs/xfs/xfs_quota.h +++ b/fs/xfs/xfs_quota.h @@ -125,6 +125,7 @@ extern void xfs_qm_dqdetach(struct xfs_inode *); extern void xfs_qm_dqrele(struct xfs_dquot *); extern void xfs_qm_statvfs(struct xfs_inode *, struct kstatfs *); extern int xfs_qm_newmount(struct xfs_mount *, uint *, uint *); +void xfs_qm_resume_quotaon(struct xfs_mount *mp); extern void xfs_qm_mount_quotas(struct xfs_mount *); extern void xfs_qm_unmount(struct xfs_mount *); extern void xfs_qm_unmount_quotas(struct xfs_mount *); @@ -202,6 +203,7 @@ xfs_trans_reserve_quota_icreate(struct xfs_trans *tp, struct xfs_dquot *udqp, #define xfs_qm_dqrele(d) do { (d) = (d); } while(0) #define xfs_qm_statvfs(ip, s) do { } while(0) #define xfs_qm_newmount(mp, a, b) (0) +#define xfs_qm_resume_quotaon(mp) ((void)0) #define xfs_qm_mount_quotas(mp) #define xfs_qm_unmount(mp) #define xfs_qm_unmount_quotas(mp) diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 835886c322a83..d02bfe9ddfe58 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -67,6 +67,9 @@ enum xfs_dax_mode { XFS_DAX_NEVER = 2, }; +/* Were quota mount options provided? Must use the upper 16 bits of qflags. */ +#define XFS_QFLAGS_MNTOPTS (1U << 31) + static void xfs_mount_set_dax_mode( struct xfs_mount *mp, @@ -1264,6 +1267,8 @@ xfs_fs_parse_param( int size = 0; int opt; + BUILD_BUG_ON(XFS_QFLAGS_MNTOPTS & XFS_MOUNT_QUOTA_ALL); + opt = fs_parse(fc, xfs_fs_parameters, param, &result); if (opt < 0) return opt; @@ -1341,32 +1346,39 @@ xfs_fs_parse_param( case Opt_noquota: parsing_mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT; parsing_mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD; + parsing_mp->m_qflags |= XFS_QFLAGS_MNTOPTS; return 0; case Opt_quota: case Opt_uquota: case Opt_usrquota: parsing_mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ENFD); + parsing_mp->m_qflags |= XFS_QFLAGS_MNTOPTS; return 0; case Opt_qnoenforce: case Opt_uqnoenforce: parsing_mp->m_qflags |= XFS_UQUOTA_ACCT; parsing_mp->m_qflags &= ~XFS_UQUOTA_ENFD; + parsing_mp->m_qflags |= XFS_QFLAGS_MNTOPTS; return 0; case Opt_pquota: case Opt_prjquota: parsing_mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ENFD); + parsing_mp->m_qflags |= XFS_QFLAGS_MNTOPTS; return 0; case Opt_pqnoenforce: parsing_mp->m_qflags |= XFS_PQUOTA_ACCT; parsing_mp->m_qflags &= ~XFS_PQUOTA_ENFD; + parsing_mp->m_qflags |= XFS_QFLAGS_MNTOPTS; return 0; case Opt_gquota: case Opt_grpquota: parsing_mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ENFD); + parsing_mp->m_qflags |= XFS_QFLAGS_MNTOPTS; return 0; case Opt_gqnoenforce: parsing_mp->m_qflags |= XFS_GQUOTA_ACCT; parsing_mp->m_qflags &= ~XFS_GQUOTA_ENFD; + parsing_mp->m_qflags |= XFS_QFLAGS_MNTOPTS; return 0; case Opt_discard: parsing_mp->m_features |= XFS_FEAT_DISCARD; @@ -1761,6 +1773,14 @@ xfs_fs_fill_super( xfs_warn(mp, "EXPERIMENTAL parent pointer feature enabled. Use at your own risk!"); + /* + * If no quota mount options were provided, maybe we'll try to pick + * up the quota accounting and enforcement flags from the ondisk sb. + */ + if (!(mp->m_qflags & XFS_QFLAGS_MNTOPTS)) + xfs_set_resuming_quotaon(mp); + mp->m_qflags &= ~XFS_QFLAGS_MNTOPTS; + error = xfs_mountfs(mp); if (error) goto out_filestream_unmount; @@ -1947,6 +1967,8 @@ xfs_fs_reconfigure( int flags = fc->sb_flags; int error; + new_mp->m_qflags &= ~XFS_QFLAGS_MNTOPTS; + /* version 5 superblocks always support version counters. */ if (xfs_has_crc(mp)) fc->sb_flags |= SB_I_VERSION; From patchwork Fri Aug 23 00:29:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774478 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 36970AD4C for ; Fri, 23 Aug 2024 00:29:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372956; cv=none; b=O16kW2+fdCEC+KQpel7c4LXkxa9GQJ14Ma613FVBjq/C7WgVMR5mR/4Zyv+b65f1G/IeX/ucpOKHvqZq7q7PsGpaQ+kAodRrRNkYgL9GA/UHaE9xN27HjAxZ+TIvrtrW+uy7hKCycgWoZ0phy4X0E5aFpp22BvnjU2KTiEt6AYs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372956; c=relaxed/simple; bh=J5hgRtUl0ujTW+M/sIs0vKlCiL8Pm/Qw0VQe0k90DQ0=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Y0UyRk405FjAgA1st3ZXp2Zd98u5Ruy83kAJdfGPsGZPqKWdz0BssclHpryjnJfKYA36/3W6Foyvs+CxkIHs57mcZshExG4aqzk2tie9zmV1BMOs14x4GFV4JodDNfbGVzXcOL/ot2pStwR0WIOqwO0yiAgZwQ7BMpF6Ef/tokw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=e5E5p3XM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="e5E5p3XM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BB708C32782; Fri, 23 Aug 2024 00:29:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372955; bh=J5hgRtUl0ujTW+M/sIs0vKlCiL8Pm/Qw0VQe0k90DQ0=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=e5E5p3XMjlCFdmNoybDf8w6dm7IjPMyxQwnMnbRx8tzhyO2wAbkkXwKGbwlhCp+yd NFht37IJJX5dZDkhst0ZeqA9odvqe3IvaLzQJDzvmoQCfhnoII6JssvmRvpoy/U1KZ V7IZx9S+wzPvSr9fj/FcwplBjt739n1dE7sUuY4SYLhTcgARBtRmuazMCHlnCuLiS/ 7/rMdMKeUzFpG9VKZo7AVNKmEm+d9WdkBb04txYI0bsU8A/xTIu/P3+FyDn2bRnFER spOYrooGzf13yT9yf4aGMggdOU9cR+TdE4Ku+wCTwm0SrbTwk96XwY4zfuoSQ5V0iE TRgc4IrvIx3uw== Date: Thu, 22 Aug 2024 17:29:15 -0700 Subject: [PATCH 5/6] xfs: update sb field checks when metadir is turned on From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437089450.61495.17228908896759675474.stgit@frogsfrogsfrogs> In-Reply-To: <172437089342.61495.12289421749855228771.stgit@frogsfrogsfrogs> References: <172437089342.61495.12289421749855228771.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong When metadir is enabled, we want to check the two new rtgroups fields, and we don't want to check the old inumbers that are now in the metadir. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/scrub/agheader.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c index cad997f38a424..0d22d70950a5c 100644 --- a/fs/xfs/scrub/agheader.c +++ b/fs/xfs/scrub/agheader.c @@ -147,14 +147,14 @@ xchk_superblock( if (xfs_has_metadir(sc->mp)) { if (sb->sb_metadirino != cpu_to_be64(mp->m_sb.sb_metadirino)) xchk_block_set_preen(sc, bp); + } else { + if (sb->sb_rbmino != cpu_to_be64(mp->m_sb.sb_rbmino)) + xchk_block_set_preen(sc, bp); + + if (sb->sb_rsumino != cpu_to_be64(mp->m_sb.sb_rsumino)) + xchk_block_set_preen(sc, bp); } - if (sb->sb_rbmino != cpu_to_be64(mp->m_sb.sb_rbmino)) - xchk_block_set_preen(sc, bp); - - if (sb->sb_rsumino != cpu_to_be64(mp->m_sb.sb_rsumino)) - xchk_block_set_preen(sc, bp); - if (sb->sb_rextsize != cpu_to_be32(mp->m_sb.sb_rextsize)) xchk_block_set_corrupt(sc, bp); @@ -229,11 +229,13 @@ xchk_superblock( * sb_icount, sb_ifree, sb_fdblocks, sb_frexents */ - if (sb->sb_uquotino != cpu_to_be64(mp->m_sb.sb_uquotino)) - xchk_block_set_preen(sc, bp); + if (!xfs_has_metadir(mp)) { + if (sb->sb_uquotino != cpu_to_be64(mp->m_sb.sb_uquotino)) + xchk_block_set_preen(sc, bp); - if (sb->sb_gquotino != cpu_to_be64(mp->m_sb.sb_gquotino)) - xchk_block_set_preen(sc, bp); + if (sb->sb_gquotino != cpu_to_be64(mp->m_sb.sb_gquotino)) + xchk_block_set_preen(sc, bp); + } /* * Skip the quota flags since repair will force quotacheck. @@ -342,8 +344,10 @@ xchk_superblock( if (sb->sb_spino_align != cpu_to_be32(mp->m_sb.sb_spino_align)) xchk_block_set_corrupt(sc, bp); - if (sb->sb_pquotino != cpu_to_be64(mp->m_sb.sb_pquotino)) - xchk_block_set_preen(sc, bp); + if (!xfs_has_metadir(mp)) { + if (sb->sb_pquotino != cpu_to_be64(mp->m_sb.sb_pquotino)) + xchk_block_set_preen(sc, bp); + } /* Don't care about sb_lsn */ } @@ -354,6 +358,14 @@ xchk_superblock( xchk_block_set_corrupt(sc, bp); } + if (xfs_has_metadir(mp)) { + if (sb->sb_rgcount != cpu_to_be32(mp->m_sb.sb_rgcount)) + xchk_block_set_corrupt(sc, bp); + + if (sb->sb_rgextents != cpu_to_be32(mp->m_sb.sb_rgextents)) + xchk_block_set_corrupt(sc, bp); + } + /* Everything else must be zero. */ if (memchr_inv(sb + 1, 0, BBTOB(bp->b_length) - sizeof(struct xfs_dsb))) From patchwork Fri Aug 23 00:29:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Darrick J. Wong" X-Patchwork-Id: 13774479 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E8C08B653 for ; Fri, 23 Aug 2024 00:29:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372972; cv=none; b=Xk4vvMzxskSXmBVujK+yhYwadMoK3k+MuxrYDfA+8wEw/tG7QOcjXWlumpXPhCUD0fZ0jXmvMGiT2O9leQD9hsdCnht00M64orkyu+RGg7iEgnZdhExiedC6iB/m+v0nMlb6sjLpnVeY1eTa1Pq63rPR84CrhZ3+p6Euyfp/kuE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724372972; c=relaxed/simple; bh=2gytWVOiq+JtZGdu5+Qfx0RkYIMu8RJm/mX4h3NjZXE=; h=Date:Subject:From:To:Cc:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=sSp8E6BWTtEh2krEVITC77vaOoj/jtNOXUWqictynnJ4w1ylKtJKovjMt075Tmx8eX5Oxo081/dgs3zg1kaTScm44seWowGy9iJ3VqzAfPNEnia27U/OtIyleh4oPLLSOBLalls+4GCmrDODe2OvS8xeweJ2RnCjHinyJhBhyKw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HRduX30u; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HRduX30u" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6493FC32782; Fri, 23 Aug 2024 00:29:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724372971; bh=2gytWVOiq+JtZGdu5+Qfx0RkYIMu8RJm/mX4h3NjZXE=; h=Date:Subject:From:To:Cc:In-Reply-To:References:From; b=HRduX30u0yWm8U2Vv7qYVuRope3xZvjcaPRbyuH5wRC3LLTh2QkHS2EO1ZE1Qbcfb cFA/WqKxbYLjNDfy+bEYrrxAh8eeY5APKs8ca8nf4AsUxR8QuYv4v/GEpSyea0QsYX Wu0DoeVcNkMdeZza3dSx5cYVaiSQDyMFD9sXMWKIRiDWZiYGwvMCZZ18p0sn/NO0PH sqmV3RtgA6Co5UwePOETngxoi35IOXzbDzYqxjXBR4nWF841DX3Hfdk7v6I5F4W89z 1Mu+rMPJ0cUwS8gAhszcNOgVkVX1ydXodL0B7+hLxAd4+POFpurNgp/+50Sfbc6k1i T2aIKDDxnQJaA== Date: Thu, 22 Aug 2024 17:29:30 -0700 Subject: [PATCH 6/6] xfs: enable metadata directory feature From: "Darrick J. Wong" To: djwong@kernel.org Cc: hch@lst.de, linux-xfs@vger.kernel.org Message-ID: <172437089467.61495.6398228533025859603.stgit@frogsfrogsfrogs> In-Reply-To: <172437089342.61495.12289421749855228771.stgit@frogsfrogsfrogs> References: <172437089342.61495.12289421749855228771.stgit@frogsfrogsfrogs> User-Agent: StGit/0.19 Precedence: bulk X-Mailing-List: linux-xfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Darrick J. Wong Enable the metadata directory feature. Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/libxfs/xfs_format.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index cafac42cd51ad..6aa141c99e808 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -397,7 +397,8 @@ xfs_sb_has_ro_compat_feature( XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | \ XFS_SB_FEAT_INCOMPAT_NREXT64 | \ XFS_SB_FEAT_INCOMPAT_EXCHRANGE | \ - XFS_SB_FEAT_INCOMPAT_PARENT) + XFS_SB_FEAT_INCOMPAT_PARENT | \ + XFS_SB_FEAT_INCOMPAT_METADIR) #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool