diff options
author | Abhi Das <adas@redhat.com> | 2015-03-18 13:03:41 -0400 |
---|---|---|
committer | Bob Peterson <rpeterso@redhat.com> | 2015-03-18 13:46:54 -0400 |
commit | b8fbf471edb3dbf441716fd2a52a7ca76c381381 (patch) | |
tree | a5a2132cc29397dd1f1d8892497dbf18b2fb125f /fs/gfs2/quota.c | |
parent | f1ea6f4ec0a48d7b6bbf4d380a0ac14d69fadb44 (diff) |
gfs2: perform quota checks against allocation parameters
Use struct gfs2_alloc_parms as an argument to gfs2_quota_check()
and gfs2_quota_lock_check() to check for quota violations while
accounting for the new blocks requested by the current operation
in ap->target.
Previously, the number of new blocks requested during an operation
were not accounted for during quota_check and would allow these
operations to exceed quota. This was not very apparent since most
operations allocated only 1 block at a time and quotas would get
violated in the next operation. i.e. quota excess would only be by
1 block or so. With fallocate, (where we allocate a bunch of blocks
at once) the quota excess is non-trivial and is addressed by this
patch.
Signed-off-by: Abhi Das <adas@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Acked-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/quota.c')
-rw-r--r-- | fs/gfs2/quota.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 3aa17d4d1cfc..964a769a7a86 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -1094,7 +1094,8 @@ static int print_message(struct gfs2_quota_data *qd, char *type) | |||
1094 | return 0; | 1094 | return 0; |
1095 | } | 1095 | } |
1096 | 1096 | ||
1097 | int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | 1097 | int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid, |
1098 | struct gfs2_alloc_parms *ap) | ||
1098 | { | 1099 | { |
1099 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1100 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1100 | struct gfs2_quota_data *qd; | 1101 | struct gfs2_quota_data *qd; |
@@ -1117,14 +1118,13 @@ int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | |||
1117 | 1118 | ||
1118 | value = (s64)be64_to_cpu(qd->qd_qb.qb_value); | 1119 | value = (s64)be64_to_cpu(qd->qd_qb.qb_value); |
1119 | spin_lock(&qd_lock); | 1120 | spin_lock(&qd_lock); |
1120 | value += qd->qd_change; | 1121 | value += qd->qd_change + ap->target; |
1121 | spin_unlock(&qd_lock); | 1122 | spin_unlock(&qd_lock); |
1122 | 1123 | ||
1123 | if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) { | 1124 | if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) { |
1124 | print_message(qd, "exceeded"); | 1125 | print_message(qd, "exceeded"); |
1125 | quota_send_warning(qd->qd_id, | 1126 | quota_send_warning(qd->qd_id, |
1126 | sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN); | 1127 | sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN); |
1127 | |||
1128 | error = -EDQUOT; | 1128 | error = -EDQUOT; |
1129 | break; | 1129 | break; |
1130 | } else if (be64_to_cpu(qd->qd_qb.qb_warn) && | 1130 | } else if (be64_to_cpu(qd->qd_qb.qb_warn) && |