summaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2017-06-27 10:19:45 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2017-06-27 18:23:22 -0700
commit50e0bdbe9f48f98bb02eac7030d682f4716884ae (patch)
treea4f2d4b9cc5e1fad8be1f0ff3598d11a9864d326 /fs/xfs
parent244e3dea58818e9520bf3dbaf4404a60b105bfb1 (diff)
downloadlinux-50e0bdbe9f48f98bb02eac7030d682f4716884ae.tar.bz2
xfs: grab dquots without taking the ilock
Add a new dqget flag that grabs the dquot without taking the ilock. This will be used by the scrubber (which will have already grabbed the ilock) to perform basic sanity checking of the quota data. Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Brian Foster <bfoster@redhat.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/libxfs/xfs_quota_defs.h2
-rw-r--r--fs/xfs/xfs_dquot.c14
2 files changed, 12 insertions, 4 deletions
diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
index d69c772271cb..2834574cb6e7 100644
--- a/fs/xfs/libxfs/xfs_quota_defs.h
+++ b/fs/xfs/libxfs/xfs_quota_defs.h
@@ -136,6 +136,8 @@ typedef uint16_t xfs_qwarncnt_t;
*/
#define XFS_QMOPT_INHERIT 0x1000000
+#define XFS_QMOPT_NOLOCK 0x2000000 /* don't ilock during dqget */
+
/*
* flags to xfs_trans_mod_dquot.
*/
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index e57c6cce91aa..79668142afc1 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -472,18 +472,23 @@ xfs_qm_dqtobp(
struct xfs_mount *mp = dqp->q_mount;
xfs_dqid_t id = be32_to_cpu(dqp->q_core.d_id);
struct xfs_trans *tp = (tpp ? *tpp : NULL);
- uint lock_mode;
+ uint lock_mode = 0;
quotip = xfs_quota_inode(dqp->q_mount, dqp->dq_flags);
dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk;
- lock_mode = xfs_ilock_data_map_shared(quotip);
+ ASSERT(!(flags & XFS_QMOPT_NOLOCK) ||
+ xfs_isilocked(quotip, XFS_ILOCK_SHARED) ||
+ xfs_isilocked(quotip, XFS_ILOCK_EXCL));
+ if (!(flags & XFS_QMOPT_NOLOCK))
+ lock_mode = xfs_ilock_data_map_shared(quotip);
if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) {
/*
* Return if this type of quotas is turned off while we
* didn't have the quota inode lock.
*/
- xfs_iunlock(quotip, lock_mode);
+ if (lock_mode)
+ xfs_iunlock(quotip, lock_mode);
return -ESRCH;
}
@@ -493,7 +498,8 @@ xfs_qm_dqtobp(
error = xfs_bmapi_read(quotip, dqp->q_fileoffset,
XFS_DQUOT_CLUSTER_SIZE_FSB, &map, &nmaps, 0);
- xfs_iunlock(quotip, lock_mode);
+ if (lock_mode)
+ xfs_iunlock(quotip, lock_mode);
if (error)
return error;