diff options
Diffstat (limited to 'fs/quota/dquot.c')
-rw-r--r-- | fs/quota/dquot.c | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 53e377a59b05..efaeed35476f 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -267,7 +267,7 @@ hashfn(const struct super_block *sb, unsigned int id, int type) | |||
267 | static inline void insert_dquot_hash(struct dquot *dquot) | 267 | static inline void insert_dquot_hash(struct dquot *dquot) |
268 | { | 268 | { |
269 | struct hlist_head *head; | 269 | struct hlist_head *head; |
270 | head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type); | 270 | head = dquot_hash + hashfn(dquot->dq_sb, from_kqid(&init_user_ns, dquot->dq_id), dquot->dq_id.type); |
271 | hlist_add_head(&dquot->dq_hash, head); | 271 | hlist_add_head(&dquot->dq_hash, head); |
272 | } | 272 | } |
273 | 273 | ||
@@ -279,13 +279,13 @@ static inline void remove_dquot_hash(struct dquot *dquot) | |||
279 | static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, | 279 | static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, |
280 | unsigned int id, int type) | 280 | unsigned int id, int type) |
281 | { | 281 | { |
282 | struct kqid qid = make_kqid(&init_user_ns, type, id); | ||
282 | struct hlist_node *node; | 283 | struct hlist_node *node; |
283 | struct dquot *dquot; | 284 | struct dquot *dquot; |
284 | 285 | ||
285 | hlist_for_each (node, dquot_hash+hashent) { | 286 | hlist_for_each (node, dquot_hash+hashent) { |
286 | dquot = hlist_entry(node, struct dquot, dq_hash); | 287 | dquot = hlist_entry(node, struct dquot, dq_hash); |
287 | if (dquot->dq_sb == sb && dquot->dq_id == id && | 288 | if (dquot->dq_sb == sb && qid_eq(dquot->dq_id, qid)) |
288 | dquot->dq_type == type) | ||
289 | return dquot; | 289 | return dquot; |
290 | } | 290 | } |
291 | return NULL; | 291 | return NULL; |
@@ -351,7 +351,7 @@ int dquot_mark_dquot_dirty(struct dquot *dquot) | |||
351 | spin_lock(&dq_list_lock); | 351 | spin_lock(&dq_list_lock); |
352 | if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags)) { | 352 | if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags)) { |
353 | list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)-> | 353 | list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)-> |
354 | info[dquot->dq_type].dqi_dirty_list); | 354 | info[dquot->dq_id.type].dqi_dirty_list); |
355 | ret = 0; | 355 | ret = 0; |
356 | } | 356 | } |
357 | spin_unlock(&dq_list_lock); | 357 | spin_unlock(&dq_list_lock); |
@@ -410,17 +410,17 @@ int dquot_acquire(struct dquot *dquot) | |||
410 | mutex_lock(&dquot->dq_lock); | 410 | mutex_lock(&dquot->dq_lock); |
411 | mutex_lock(&dqopt->dqio_mutex); | 411 | mutex_lock(&dqopt->dqio_mutex); |
412 | if (!test_bit(DQ_READ_B, &dquot->dq_flags)) | 412 | if (!test_bit(DQ_READ_B, &dquot->dq_flags)) |
413 | ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot); | 413 | ret = dqopt->ops[dquot->dq_id.type]->read_dqblk(dquot); |
414 | if (ret < 0) | 414 | if (ret < 0) |
415 | goto out_iolock; | 415 | goto out_iolock; |
416 | set_bit(DQ_READ_B, &dquot->dq_flags); | 416 | set_bit(DQ_READ_B, &dquot->dq_flags); |
417 | /* Instantiate dquot if needed */ | 417 | /* Instantiate dquot if needed */ |
418 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) { | 418 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) { |
419 | ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); | 419 | ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot); |
420 | /* Write the info if needed */ | 420 | /* Write the info if needed */ |
421 | if (info_dirty(&dqopt->info[dquot->dq_type])) { | 421 | if (info_dirty(&dqopt->info[dquot->dq_id.type])) { |
422 | ret2 = dqopt->ops[dquot->dq_type]->write_file_info( | 422 | ret2 = dqopt->ops[dquot->dq_id.type]->write_file_info( |
423 | dquot->dq_sb, dquot->dq_type); | 423 | dquot->dq_sb, dquot->dq_id.type); |
424 | } | 424 | } |
425 | if (ret < 0) | 425 | if (ret < 0) |
426 | goto out_iolock; | 426 | goto out_iolock; |
@@ -455,7 +455,7 @@ int dquot_commit(struct dquot *dquot) | |||
455 | /* Inactive dquot can be only if there was error during read/init | 455 | /* Inactive dquot can be only if there was error during read/init |
456 | * => we have better not writing it */ | 456 | * => we have better not writing it */ |
457 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) | 457 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) |
458 | ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); | 458 | ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot); |
459 | else | 459 | else |
460 | ret = -EIO; | 460 | ret = -EIO; |
461 | out_sem: | 461 | out_sem: |
@@ -477,12 +477,12 @@ int dquot_release(struct dquot *dquot) | |||
477 | if (atomic_read(&dquot->dq_count) > 1) | 477 | if (atomic_read(&dquot->dq_count) > 1) |
478 | goto out_dqlock; | 478 | goto out_dqlock; |
479 | mutex_lock(&dqopt->dqio_mutex); | 479 | mutex_lock(&dqopt->dqio_mutex); |
480 | if (dqopt->ops[dquot->dq_type]->release_dqblk) { | 480 | if (dqopt->ops[dquot->dq_id.type]->release_dqblk) { |
481 | ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot); | 481 | ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot); |
482 | /* Write the info */ | 482 | /* Write the info */ |
483 | if (info_dirty(&dqopt->info[dquot->dq_type])) { | 483 | if (info_dirty(&dqopt->info[dquot->dq_id.type])) { |
484 | ret2 = dqopt->ops[dquot->dq_type]->write_file_info( | 484 | ret2 = dqopt->ops[dquot->dq_id.type]->write_file_info( |
485 | dquot->dq_sb, dquot->dq_type); | 485 | dquot->dq_sb, dquot->dq_id.type); |
486 | } | 486 | } |
487 | if (ret >= 0) | 487 | if (ret >= 0) |
488 | ret = ret2; | 488 | ret = ret2; |
@@ -521,7 +521,7 @@ restart: | |||
521 | list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) { | 521 | list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) { |
522 | if (dquot->dq_sb != sb) | 522 | if (dquot->dq_sb != sb) |
523 | continue; | 523 | continue; |
524 | if (dquot->dq_type != type) | 524 | if (dquot->dq_id.type != type) |
525 | continue; | 525 | continue; |
526 | /* Wait for dquot users */ | 526 | /* Wait for dquot users */ |
527 | if (atomic_read(&dquot->dq_count)) { | 527 | if (atomic_read(&dquot->dq_count)) { |
@@ -741,7 +741,8 @@ void dqput(struct dquot *dquot) | |||
741 | #ifdef CONFIG_QUOTA_DEBUG | 741 | #ifdef CONFIG_QUOTA_DEBUG |
742 | if (!atomic_read(&dquot->dq_count)) { | 742 | if (!atomic_read(&dquot->dq_count)) { |
743 | quota_error(dquot->dq_sb, "trying to free free dquot of %s %d", | 743 | quota_error(dquot->dq_sb, "trying to free free dquot of %s %d", |
744 | quotatypes[dquot->dq_type], dquot->dq_id); | 744 | quotatypes[dquot->dq_id.type], |
745 | from_kqid(&init_user_ns, dquot->dq_id)); | ||
745 | BUG(); | 746 | BUG(); |
746 | } | 747 | } |
747 | #endif | 748 | #endif |
@@ -752,7 +753,7 @@ we_slept: | |||
752 | /* We have more than one user... nothing to do */ | 753 | /* We have more than one user... nothing to do */ |
753 | atomic_dec(&dquot->dq_count); | 754 | atomic_dec(&dquot->dq_count); |
754 | /* Releasing dquot during quotaoff phase? */ | 755 | /* Releasing dquot during quotaoff phase? */ |
755 | if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_type) && | 756 | if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_id.type) && |
756 | atomic_read(&dquot->dq_count) == 1) | 757 | atomic_read(&dquot->dq_count) == 1) |
757 | wake_up(&dquot->dq_wait_unused); | 758 | wake_up(&dquot->dq_wait_unused); |
758 | spin_unlock(&dq_list_lock); | 759 | spin_unlock(&dq_list_lock); |
@@ -815,7 +816,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) | |||
815 | INIT_LIST_HEAD(&dquot->dq_dirty); | 816 | INIT_LIST_HEAD(&dquot->dq_dirty); |
816 | init_waitqueue_head(&dquot->dq_wait_unused); | 817 | init_waitqueue_head(&dquot->dq_wait_unused); |
817 | dquot->dq_sb = sb; | 818 | dquot->dq_sb = sb; |
818 | dquot->dq_type = type; | 819 | dquot->dq_id.type = type; |
819 | atomic_set(&dquot->dq_count, 1); | 820 | atomic_set(&dquot->dq_count, 1); |
820 | 821 | ||
821 | return dquot; | 822 | return dquot; |
@@ -859,7 +860,7 @@ we_slept: | |||
859 | } | 860 | } |
860 | dquot = empty; | 861 | dquot = empty; |
861 | empty = NULL; | 862 | empty = NULL; |
862 | dquot->dq_id = id; | 863 | dquot->dq_id = qid; |
863 | /* all dquots go on the inuse_list */ | 864 | /* all dquots go on the inuse_list */ |
864 | put_inuse(dquot); | 865 | put_inuse(dquot); |
865 | /* hash it first so it can be found */ | 866 | /* hash it first so it can be found */ |
@@ -1219,8 +1220,8 @@ static void prepare_warning(struct dquot_warn *warn, struct dquot *dquot, | |||
1219 | return; | 1220 | return; |
1220 | warn->w_type = warntype; | 1221 | warn->w_type = warntype; |
1221 | warn->w_sb = dquot->dq_sb; | 1222 | warn->w_sb = dquot->dq_sb; |
1222 | warn->w_dq_id = dquot->dq_id; | 1223 | warn->w_dq_id = from_kqid(&init_user_ns, dquot->dq_id); |
1223 | warn->w_dq_type = dquot->dq_type; | 1224 | warn->w_dq_type = dquot->dq_id.type; |
1224 | } | 1225 | } |
1225 | 1226 | ||
1226 | /* | 1227 | /* |
@@ -1245,7 +1246,7 @@ static void flush_warnings(struct dquot_warn *warn) | |||
1245 | 1246 | ||
1246 | static int ignore_hardlimit(struct dquot *dquot) | 1247 | static int ignore_hardlimit(struct dquot *dquot) |
1247 | { | 1248 | { |
1248 | struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; | 1249 | struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type]; |
1249 | 1250 | ||
1250 | return capable(CAP_SYS_RESOURCE) && | 1251 | return capable(CAP_SYS_RESOURCE) && |
1251 | (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || | 1252 | (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || |
@@ -1258,7 +1259,7 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, | |||
1258 | { | 1259 | { |
1259 | qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes; | 1260 | qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes; |
1260 | 1261 | ||
1261 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || | 1262 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_id.type) || |
1262 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1263 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) |
1263 | return 0; | 1264 | return 0; |
1264 | 1265 | ||
@@ -1283,7 +1284,7 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, | |||
1283 | dquot->dq_dqb.dqb_itime == 0) { | 1284 | dquot->dq_dqb.dqb_itime == 0) { |
1284 | prepare_warning(warn, dquot, QUOTA_NL_ISOFTWARN); | 1285 | prepare_warning(warn, dquot, QUOTA_NL_ISOFTWARN); |
1285 | dquot->dq_dqb.dqb_itime = get_seconds() + | 1286 | dquot->dq_dqb.dqb_itime = get_seconds() + |
1286 | sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; | 1287 | sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type].dqi_igrace; |
1287 | } | 1288 | } |
1288 | 1289 | ||
1289 | return 0; | 1290 | return 0; |
@@ -1296,7 +1297,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, | |||
1296 | qsize_t tspace; | 1297 | qsize_t tspace; |
1297 | struct super_block *sb = dquot->dq_sb; | 1298 | struct super_block *sb = dquot->dq_sb; |
1298 | 1299 | ||
1299 | if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) || | 1300 | if (!sb_has_quota_limits_enabled(sb, dquot->dq_id.type) || |
1300 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1301 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) |
1301 | return 0; | 1302 | return 0; |
1302 | 1303 | ||
@@ -1327,7 +1328,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, | |||
1327 | if (!prealloc) { | 1328 | if (!prealloc) { |
1328 | prepare_warning(warn, dquot, QUOTA_NL_BSOFTWARN); | 1329 | prepare_warning(warn, dquot, QUOTA_NL_BSOFTWARN); |
1329 | dquot->dq_dqb.dqb_btime = get_seconds() + | 1330 | dquot->dq_dqb.dqb_btime = get_seconds() + |
1330 | sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace; | 1331 | sb_dqopt(sb)->info[dquot->dq_id.type].dqi_bgrace; |
1331 | } | 1332 | } |
1332 | else | 1333 | else |
1333 | /* | 1334 | /* |
@@ -1346,7 +1347,7 @@ static int info_idq_free(struct dquot *dquot, qsize_t inodes) | |||
1346 | 1347 | ||
1347 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || | 1348 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || |
1348 | dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit || | 1349 | dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit || |
1349 | !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type)) | 1350 | !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_id.type)) |
1350 | return QUOTA_NL_NOWARN; | 1351 | return QUOTA_NL_NOWARN; |
1351 | 1352 | ||
1352 | newinodes = dquot->dq_dqb.dqb_curinodes - inodes; | 1353 | newinodes = dquot->dq_dqb.dqb_curinodes - inodes; |
@@ -2362,9 +2363,9 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2362 | 2363 | ||
2363 | memset(di, 0, sizeof(*di)); | 2364 | memset(di, 0, sizeof(*di)); |
2364 | di->d_version = FS_DQUOT_VERSION; | 2365 | di->d_version = FS_DQUOT_VERSION; |
2365 | di->d_flags = dquot->dq_type == USRQUOTA ? | 2366 | di->d_flags = dquot->dq_id.type == USRQUOTA ? |
2366 | FS_USER_QUOTA : FS_GROUP_QUOTA; | 2367 | FS_USER_QUOTA : FS_GROUP_QUOTA; |
2367 | di->d_id = dquot->dq_id; | 2368 | di->d_id = from_kqid_munged(current_user_ns(), dquot->dq_id); |
2368 | 2369 | ||
2369 | spin_lock(&dq_data_lock); | 2370 | spin_lock(&dq_data_lock); |
2370 | di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit); | 2371 | di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit); |
@@ -2403,7 +2404,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2403 | { | 2404 | { |
2404 | struct mem_dqblk *dm = &dquot->dq_dqb; | 2405 | struct mem_dqblk *dm = &dquot->dq_dqb; |
2405 | int check_blim = 0, check_ilim = 0; | 2406 | int check_blim = 0, check_ilim = 0; |
2406 | struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; | 2407 | struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type]; |
2407 | 2408 | ||
2408 | if (di->d_fieldmask & ~VFS_FS_DQ_MASK) | 2409 | if (di->d_fieldmask & ~VFS_FS_DQ_MASK) |
2409 | return -EINVAL; | 2410 | return -EINVAL; |