diff options
Diffstat (limited to 'fs/gfs2/quota.c')
-rw-r--r-- | fs/gfs2/quota.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index a3bde91645c2..40c4b0d42fa8 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -765,6 +765,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) | |||
765 | struct gfs2_holder *ghs, i_gh; | 765 | struct gfs2_holder *ghs, i_gh; |
766 | unsigned int qx, x; | 766 | unsigned int qx, x; |
767 | struct gfs2_quota_data *qd; | 767 | struct gfs2_quota_data *qd; |
768 | unsigned reserved; | ||
768 | loff_t offset; | 769 | loff_t offset; |
769 | unsigned int nalloc = 0, blocks; | 770 | unsigned int nalloc = 0, blocks; |
770 | int error; | 771 | int error; |
@@ -781,7 +782,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) | |||
781 | return -ENOMEM; | 782 | return -ENOMEM; |
782 | 783 | ||
783 | sort(qda, num_qd, sizeof(struct gfs2_quota_data *), sort_qd, NULL); | 784 | sort(qda, num_qd, sizeof(struct gfs2_quota_data *), sort_qd, NULL); |
784 | mutex_lock_nested(&ip->i_inode.i_mutex, I_MUTEX_QUOTA); | 785 | mutex_lock(&ip->i_inode.i_mutex); |
785 | for (qx = 0; qx < num_qd; qx++) { | 786 | for (qx = 0; qx < num_qd; qx++) { |
786 | error = gfs2_glock_nq_init(qda[qx]->qd_gl, LM_ST_EXCLUSIVE, | 787 | error = gfs2_glock_nq_init(qda[qx]->qd_gl, LM_ST_EXCLUSIVE, |
787 | GL_NOCACHE, &ghs[qx]); | 788 | GL_NOCACHE, &ghs[qx]); |
@@ -811,13 +812,13 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) | |||
811 | * two blocks need to be updated instead of 1 */ | 812 | * two blocks need to be updated instead of 1 */ |
812 | blocks = num_qd * data_blocks + RES_DINODE + num_qd + 3; | 813 | blocks = num_qd * data_blocks + RES_DINODE + num_qd + 3; |
813 | 814 | ||
814 | error = gfs2_inplace_reserve(ip, 1 + | 815 | reserved = 1 + (nalloc * (data_blocks + ind_blocks)); |
815 | (nalloc * (data_blocks + ind_blocks))); | 816 | error = gfs2_inplace_reserve(ip, reserved); |
816 | if (error) | 817 | if (error) |
817 | goto out_alloc; | 818 | goto out_alloc; |
818 | 819 | ||
819 | if (nalloc) | 820 | if (nalloc) |
820 | blocks += gfs2_rg_blocks(ip) + nalloc * ind_blocks + RES_STATFS; | 821 | blocks += gfs2_rg_blocks(ip, reserved) + nalloc * ind_blocks + RES_STATFS; |
821 | 822 | ||
822 | error = gfs2_trans_begin(sdp, blocks, 0); | 823 | error = gfs2_trans_begin(sdp, blocks, 0); |
823 | if (error) | 824 | if (error) |
@@ -1070,8 +1071,10 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
1070 | 1071 | ||
1071 | if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) { | 1072 | if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) { |
1072 | print_message(qd, "exceeded"); | 1073 | print_message(qd, "exceeded"); |
1073 | quota_send_warning(test_bit(QDF_USER, &qd->qd_flags) ? | 1074 | quota_send_warning(make_kqid(&init_user_ns, |
1074 | USRQUOTA : GRPQUOTA, qd->qd_id, | 1075 | test_bit(QDF_USER, &qd->qd_flags) ? |
1076 | USRQUOTA : GRPQUOTA, | ||
1077 | qd->qd_id), | ||
1075 | sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN); | 1078 | sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN); |
1076 | 1079 | ||
1077 | error = -EDQUOT; | 1080 | error = -EDQUOT; |
@@ -1081,8 +1084,10 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
1081 | time_after_eq(jiffies, qd->qd_last_warn + | 1084 | time_after_eq(jiffies, qd->qd_last_warn + |
1082 | gfs2_tune_get(sdp, | 1085 | gfs2_tune_get(sdp, |
1083 | gt_quota_warn_period) * HZ)) { | 1086 | gt_quota_warn_period) * HZ)) { |
1084 | quota_send_warning(test_bit(QDF_USER, &qd->qd_flags) ? | 1087 | quota_send_warning(make_kqid(&init_user_ns, |
1085 | USRQUOTA : GRPQUOTA, qd->qd_id, | 1088 | test_bit(QDF_USER, &qd->qd_flags) ? |
1089 | USRQUOTA : GRPQUOTA, | ||
1090 | qd->qd_id), | ||
1086 | sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN); | 1091 | sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN); |
1087 | error = print_message(qd, "warning"); | 1092 | error = print_message(qd, "warning"); |
1088 | qd->qd_last_warn = jiffies; | 1093 | qd->qd_last_warn = jiffies; |
@@ -1469,7 +1474,7 @@ static int gfs2_quota_get_xstate(struct super_block *sb, | |||
1469 | return 0; | 1474 | return 0; |
1470 | } | 1475 | } |
1471 | 1476 | ||
1472 | static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id, | 1477 | static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid, |
1473 | struct fs_disk_quota *fdq) | 1478 | struct fs_disk_quota *fdq) |
1474 | { | 1479 | { |
1475 | struct gfs2_sbd *sdp = sb->s_fs_info; | 1480 | struct gfs2_sbd *sdp = sb->s_fs_info; |
@@ -1477,20 +1482,21 @@ static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id, | |||
1477 | struct gfs2_quota_data *qd; | 1482 | struct gfs2_quota_data *qd; |
1478 | struct gfs2_holder q_gh; | 1483 | struct gfs2_holder q_gh; |
1479 | int error; | 1484 | int error; |
1485 | int type; | ||
1480 | 1486 | ||
1481 | memset(fdq, 0, sizeof(struct fs_disk_quota)); | 1487 | memset(fdq, 0, sizeof(struct fs_disk_quota)); |
1482 | 1488 | ||
1483 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | 1489 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
1484 | return -ESRCH; /* Crazy XFS error code */ | 1490 | return -ESRCH; /* Crazy XFS error code */ |
1485 | 1491 | ||
1486 | if (type == USRQUOTA) | 1492 | if (qid.type == USRQUOTA) |
1487 | type = QUOTA_USER; | 1493 | type = QUOTA_USER; |
1488 | else if (type == GRPQUOTA) | 1494 | else if (qid.type == GRPQUOTA) |
1489 | type = QUOTA_GROUP; | 1495 | type = QUOTA_GROUP; |
1490 | else | 1496 | else |
1491 | return -EINVAL; | 1497 | return -EINVAL; |
1492 | 1498 | ||
1493 | error = qd_get(sdp, type, id, &qd); | 1499 | error = qd_get(sdp, type, from_kqid(&init_user_ns, qid), &qd); |
1494 | if (error) | 1500 | if (error) |
1495 | return error; | 1501 | return error; |
1496 | error = do_glock(qd, FORCE, &q_gh); | 1502 | error = do_glock(qd, FORCE, &q_gh); |
@@ -1500,7 +1506,7 @@ static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id, | |||
1500 | qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb; | 1506 | qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb; |
1501 | fdq->d_version = FS_DQUOT_VERSION; | 1507 | fdq->d_version = FS_DQUOT_VERSION; |
1502 | fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA; | 1508 | fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA; |
1503 | fdq->d_id = id; | 1509 | fdq->d_id = from_kqid(&init_user_ns, qid); |
1504 | fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift; | 1510 | fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift; |
1505 | fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift; | 1511 | fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift; |
1506 | fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift; | 1512 | fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift; |
@@ -1514,7 +1520,7 @@ out: | |||
1514 | /* GFS2 only supports a subset of the XFS fields */ | 1520 | /* GFS2 only supports a subset of the XFS fields */ |
1515 | #define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD|FS_DQ_BCOUNT) | 1521 | #define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD|FS_DQ_BCOUNT) |
1516 | 1522 | ||
1517 | static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | 1523 | static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid, |
1518 | struct fs_disk_quota *fdq) | 1524 | struct fs_disk_quota *fdq) |
1519 | { | 1525 | { |
1520 | struct gfs2_sbd *sdp = sb->s_fs_info; | 1526 | struct gfs2_sbd *sdp = sb->s_fs_info; |
@@ -1526,11 +1532,12 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
1526 | int alloc_required; | 1532 | int alloc_required; |
1527 | loff_t offset; | 1533 | loff_t offset; |
1528 | int error; | 1534 | int error; |
1535 | int type; | ||
1529 | 1536 | ||
1530 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | 1537 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
1531 | return -ESRCH; /* Crazy XFS error code */ | 1538 | return -ESRCH; /* Crazy XFS error code */ |
1532 | 1539 | ||
1533 | switch(type) { | 1540 | switch(qid.type) { |
1534 | case USRQUOTA: | 1541 | case USRQUOTA: |
1535 | type = QUOTA_USER; | 1542 | type = QUOTA_USER; |
1536 | if (fdq->d_flags != FS_USER_QUOTA) | 1543 | if (fdq->d_flags != FS_USER_QUOTA) |
@@ -1547,10 +1554,10 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
1547 | 1554 | ||
1548 | if (fdq->d_fieldmask & ~GFS2_FIELDMASK) | 1555 | if (fdq->d_fieldmask & ~GFS2_FIELDMASK) |
1549 | return -EINVAL; | 1556 | return -EINVAL; |
1550 | if (fdq->d_id != id) | 1557 | if (fdq->d_id != from_kqid(&init_user_ns, qid)) |
1551 | return -EINVAL; | 1558 | return -EINVAL; |
1552 | 1559 | ||
1553 | error = qd_get(sdp, type, id, &qd); | 1560 | error = qd_get(sdp, type, from_kqid(&init_user_ns, qid), &qd); |
1554 | if (error) | 1561 | if (error) |
1555 | return error; | 1562 | return error; |
1556 | 1563 | ||
@@ -1598,7 +1605,7 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
1598 | error = gfs2_inplace_reserve(ip, blocks); | 1605 | error = gfs2_inplace_reserve(ip, blocks); |
1599 | if (error) | 1606 | if (error) |
1600 | goto out_i; | 1607 | goto out_i; |
1601 | blocks += gfs2_rg_blocks(ip); | 1608 | blocks += gfs2_rg_blocks(ip, blocks); |
1602 | } | 1609 | } |
1603 | 1610 | ||
1604 | /* Some quotas span block boundaries and can update two blocks, | 1611 | /* Some quotas span block boundaries and can update two blocks, |