aboutsummaryrefslogtreecommitdiffstats
path: root/fs/quota
diff options
context:
space:
mode:
Diffstat (limited to 'fs/quota')
-rw-r--r--fs/quota/dquot.c67
-rw-r--r--fs/quota/quota.c36
2 files changed, 74 insertions, 29 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 6aed77fc99c7..b1a5036560a9 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2338,51 +2338,70 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id,
2338} 2338}
2339EXPORT_SYMBOL(vfs_get_dqblk); 2339EXPORT_SYMBOL(vfs_get_dqblk);
2340 2340
2341#define VFS_FS_DQ_MASK \
2342 (FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \
2343 FS_DQ_ICOUNT | FS_DQ_ISOFT | FS_DQ_IHARD | \
2344 FS_DQ_BTIMER | FS_DQ_ITIMER)
2345
2341/* Generic routine for setting common part of quota structure */ 2346/* Generic routine for setting common part of quota structure */
2342static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) 2347static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
2343{ 2348{
2344 struct mem_dqblk *dm = &dquot->dq_dqb; 2349 struct mem_dqblk *dm = &dquot->dq_dqb;
2345 int check_blim = 0, check_ilim = 0; 2350 int check_blim = 0, check_ilim = 0;
2346 struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; 2351 struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
2347 2352
2348 if ((di->dqb_valid & QIF_BLIMITS && 2353 if (di->d_fieldmask & ~VFS_FS_DQ_MASK)
2349 (di->dqb_bhardlimit > dqi->dqi_maxblimit || 2354 return -EINVAL;
2350 di->dqb_bsoftlimit > dqi->dqi_maxblimit)) || 2355
2351 (di->dqb_valid & QIF_ILIMITS && 2356 if (((di->d_fieldmask & FS_DQ_BSOFT) &&
2352 (di->dqb_ihardlimit > dqi->dqi_maxilimit || 2357 (di->d_blk_softlimit > dqi->dqi_maxblimit)) ||
2353 di->dqb_isoftlimit > dqi->dqi_maxilimit))) 2358 ((di->d_fieldmask & FS_DQ_BHARD) &&
2359 (di->d_blk_hardlimit > dqi->dqi_maxblimit)) ||
2360 ((di->d_fieldmask & FS_DQ_ISOFT) &&
2361 (di->d_ino_softlimit > dqi->dqi_maxilimit)) ||
2362 ((di->d_fieldmask & FS_DQ_IHARD) &&
2363 (di->d_ino_hardlimit > dqi->dqi_maxilimit)))
2354 return -ERANGE; 2364 return -ERANGE;
2355 2365
2356 spin_lock(&dq_data_lock); 2366 spin_lock(&dq_data_lock);
2357 if (di->dqb_valid & QIF_SPACE) { 2367 if (di->d_fieldmask & FS_DQ_BCOUNT) {
2358 dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace; 2368 dm->dqb_curspace = di->d_bcount - dm->dqb_rsvspace;
2359 check_blim = 1; 2369 check_blim = 1;
2360 set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); 2370 set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
2361 } 2371 }
2362 if (di->dqb_valid & QIF_BLIMITS) { 2372
2363 dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); 2373 if (di->d_fieldmask & FS_DQ_BSOFT)
2364 dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); 2374 dm->dqb_bsoftlimit = qbtos(di->d_blk_softlimit);
2375 if (di->d_fieldmask & FS_DQ_BHARD)
2376 dm->dqb_bhardlimit = qbtos(di->d_blk_hardlimit);
2377 if (di->d_fieldmask & (FS_DQ_BSOFT | FS_DQ_BHARD)) {
2365 check_blim = 1; 2378 check_blim = 1;
2366 set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); 2379 set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
2367 } 2380 }
2368 if (di->dqb_valid & QIF_INODES) { 2381
2369 dm->dqb_curinodes = di->dqb_curinodes; 2382 if (di->d_fieldmask & FS_DQ_ICOUNT) {
2383 dm->dqb_curinodes = di->d_icount;
2370 check_ilim = 1; 2384 check_ilim = 1;
2371 set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); 2385 set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
2372 } 2386 }
2373 if (di->dqb_valid & QIF_ILIMITS) { 2387
2374 dm->dqb_isoftlimit = di->dqb_isoftlimit; 2388 if (di->d_fieldmask & FS_DQ_ISOFT)
2375 dm->dqb_ihardlimit = di->dqb_ihardlimit; 2389 dm->dqb_isoftlimit = di->d_ino_softlimit;
2390 if (di->d_fieldmask & FS_DQ_IHARD)
2391 dm->dqb_ihardlimit = di->d_ino_hardlimit;
2392 if (di->d_fieldmask & (FS_DQ_ISOFT | FS_DQ_IHARD)) {
2376 check_ilim = 1; 2393 check_ilim = 1;
2377 set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); 2394 set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
2378 } 2395 }
2379 if (di->dqb_valid & QIF_BTIME) { 2396
2380 dm->dqb_btime = di->dqb_btime; 2397 if (di->d_fieldmask & FS_DQ_BTIMER) {
2398 dm->dqb_btime = di->d_btimer;
2381 check_blim = 1; 2399 check_blim = 1;
2382 set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); 2400 set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
2383 } 2401 }
2384 if (di->dqb_valid & QIF_ITIME) { 2402
2385 dm->dqb_itime = di->dqb_itime; 2403 if (di->d_fieldmask & FS_DQ_ITIMER) {
2404 dm->dqb_itime = di->d_itimer;
2386 check_ilim = 1; 2405 check_ilim = 1;
2387 set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); 2406 set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
2388 } 2407 }
@@ -2392,7 +2411,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
2392 dm->dqb_curspace < dm->dqb_bsoftlimit) { 2411 dm->dqb_curspace < dm->dqb_bsoftlimit) {
2393 dm->dqb_btime = 0; 2412 dm->dqb_btime = 0;
2394 clear_bit(DQ_BLKS_B, &dquot->dq_flags); 2413 clear_bit(DQ_BLKS_B, &dquot->dq_flags);
2395 } else if (!(di->dqb_valid & QIF_BTIME)) 2414 } else if (!(di->d_fieldmask & FS_DQ_BTIMER))
2396 /* Set grace only if user hasn't provided his own... */ 2415 /* Set grace only if user hasn't provided his own... */
2397 dm->dqb_btime = get_seconds() + dqi->dqi_bgrace; 2416 dm->dqb_btime = get_seconds() + dqi->dqi_bgrace;
2398 } 2417 }
@@ -2401,7 +2420,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
2401 dm->dqb_curinodes < dm->dqb_isoftlimit) { 2420 dm->dqb_curinodes < dm->dqb_isoftlimit) {
2402 dm->dqb_itime = 0; 2421 dm->dqb_itime = 0;
2403 clear_bit(DQ_INODES_B, &dquot->dq_flags); 2422 clear_bit(DQ_INODES_B, &dquot->dq_flags);
2404 } else if (!(di->dqb_valid & QIF_ITIME)) 2423 } else if (!(di->d_fieldmask & FS_DQ_ITIMER))
2405 /* Set grace only if user hasn't provided his own... */ 2424 /* Set grace only if user hasn't provided his own... */
2406 dm->dqb_itime = get_seconds() + dqi->dqi_igrace; 2425 dm->dqb_itime = get_seconds() + dqi->dqi_igrace;
2407 } 2426 }
@@ -2417,7 +2436,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
2417} 2436}
2418 2437
2419int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, 2438int vfs_set_dqblk(struct super_block *sb, int type, qid_t id,
2420 struct if_dqblk *di) 2439 struct fs_disk_quota *di)
2421{ 2440{
2422 struct dquot *dquot; 2441 struct dquot *dquot;
2423 int rc; 2442 int rc;
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 8680e257c2bd..d6ee49dda4fd 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -167,18 +167,44 @@ static int quota_getquota(struct super_block *sb, int type, qid_t id,
167 return 0; 167 return 0;
168} 168}
169 169
170static void copy_from_if_dqblk(struct fs_disk_quota *dst, struct if_dqblk *src)
171{
172 dst->d_blk_hardlimit = src->dqb_bhardlimit;
173 dst->d_blk_softlimit = src->dqb_bsoftlimit;
174 dst->d_bcount = src->dqb_curspace;
175 dst->d_ino_hardlimit = src->dqb_ihardlimit;
176 dst->d_ino_softlimit = src->dqb_isoftlimit;
177 dst->d_icount = src->dqb_curinodes;
178 dst->d_btimer = src->dqb_btime;
179 dst->d_itimer = src->dqb_itime;
180
181 dst->d_fieldmask = 0;
182 if (src->dqb_valid & QIF_BLIMITS)
183 dst->d_fieldmask |= FS_DQ_BSOFT | FS_DQ_BHARD;
184 if (src->dqb_valid & QIF_SPACE)
185 dst->d_fieldmask |= FS_DQ_BCOUNT;
186 if (src->dqb_valid & QIF_ILIMITS)
187 dst->d_fieldmask |= FS_DQ_ISOFT | FS_DQ_IHARD;
188 if (src->dqb_valid & QIF_INODES)
189 dst->d_fieldmask |= FS_DQ_ICOUNT;
190 if (src->dqb_valid & QIF_BTIME)
191 dst->d_fieldmask |= FS_DQ_BTIMER;
192 if (src->dqb_valid & QIF_ITIME)
193 dst->d_fieldmask |= FS_DQ_ITIMER;
194}
195
170static int quota_setquota(struct super_block *sb, int type, qid_t id, 196static int quota_setquota(struct super_block *sb, int type, qid_t id,
171 void __user *addr) 197 void __user *addr)
172{ 198{
199 struct fs_disk_quota fdq;
173 struct if_dqblk idq; 200 struct if_dqblk idq;
174 201
175 if (copy_from_user(&idq, addr, sizeof(idq))) 202 if (copy_from_user(&idq, addr, sizeof(idq)))
176 return -EFAULT; 203 return -EFAULT;
177 if (!sb_has_quota_active(sb, type))
178 return -ESRCH;
179 if (!sb->s_qcop->set_dqblk) 204 if (!sb->s_qcop->set_dqblk)
180 return -ENOSYS; 205 return -ENOSYS;
181 return sb->s_qcop->set_dqblk(sb, type, id, &idq); 206 copy_from_if_dqblk(&fdq, &idq);
207 return sb->s_qcop->set_dqblk(sb, type, id, &fdq);
182} 208}
183 209
184static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr) 210static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
@@ -212,9 +238,9 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id,
212 238
213 if (copy_from_user(&fdq, addr, sizeof(fdq))) 239 if (copy_from_user(&fdq, addr, sizeof(fdq)))
214 return -EFAULT; 240 return -EFAULT;
215 if (!sb->s_qcop->set_xquota) 241 if (!sb->s_qcop->set_dqblk)
216 return -ENOSYS; 242 return -ENOSYS;
217 return sb->s_qcop->set_xquota(sb, type, id, &fdq); 243 return sb->s_qcop->set_dqblk(sb, type, id, &fdq);
218} 244}
219 245
220static int quota_getxquota(struct super_block *sb, int type, qid_t id, 246static int quota_getxquota(struct super_block *sb, int type, qid_t id,