From 930e7071506f46a226164ddcc6a47b6d67f70fc8 Mon Sep 17 00:00:00 2001 From: Andrew Perepechko Date: Sat, 10 Apr 2010 00:31:44 +0400 Subject: [PATCH] b=22363 fix for a race condition in linux quotas implementation dq_flags(struct dquot) access is not properly locked which could lead to certain inconsistencies when accessing it using non-atomic bit operations like __set_bit in do_set_dqblk. This patch replaces non-atomic __set_bit calls with atomic set_bit calls. i=Johann Lombardi i=Dmitry Zogin --- .../quota-support-64-bit-quota-format.patch | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/lustre/kernel_patches/patches/quota-support-64-bit-quota-format.patch b/lustre/kernel_patches/patches/quota-support-64-bit-quota-format.patch index 14fe9a8..9b4cd58 100644 --- a/lustre/kernel_patches/patches/quota-support-64-bit-quota-format.patch +++ b/lustre/kernel_patches/patches/quota-support-64-bit-quota-format.patch @@ -280,3 +280,45 @@ diff -puN fs/quotaio_v2.h~quota-support-64-bit-quota-format fs/quotaio_v2.h struct v2_disk_dqinfo { __le32 dqi_bgrace; /* Time before block soft limit becomes hard limit */ _ +diff -puN fs/dquot.c fs/dquot.c +--- a/fs/dquot.c ++++ b/fs/dquot.c +@@ -2065,32 +2065,32 @@ static int do_set_dqblk(struct dquot *dq + if (di->dqb_valid & QIF_SPACE) { + dm->dqb_curspace = di->dqb_curspace; + check_blim = 1; +- __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); ++ set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); + } + if (di->dqb_valid & QIF_BLIMITS) { + dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); + dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); + check_blim = 1; +- __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); ++ set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); + } + if (di->dqb_valid & QIF_INODES) { + dm->dqb_curinodes = di->dqb_curinodes; + check_ilim = 1; +- __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); ++ set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); + } + if (di->dqb_valid & QIF_ILIMITS) { + dm->dqb_isoftlimit = di->dqb_isoftlimit; + dm->dqb_ihardlimit = di->dqb_ihardlimit; + check_ilim = 1; +- __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); ++ set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); + } + if (di->dqb_valid & QIF_BTIME) { + dm->dqb_btime = di->dqb_btime; +- __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); ++ set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); + } + if (di->dqb_valid & QIF_ITIME) { + dm->dqb_itime = di->dqb_itime; +- __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); ++ set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); + } + + if (check_blim) { -- 1.8.3.1