aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/quota.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-25 19:00:49 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-25 19:00:49 -0500
commit94f2f14234178f118545a0be60a6371ddeb229b7 (patch)
tree313af6e9e255e9060fc24c836cd71ce712502b17 /fs/gfs2/quota.c
parent8d168f71551ec2a6528d01d0389b7a73c091e3e7 (diff)
parent139321c65c0584cd65c4c87a5eb3fdb4fdbd0e19 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull user namespace and namespace infrastructure changes from Eric W Biederman: "This set of changes starts with a few small enhnacements to the user namespace. reboot support, allowing more arbitrary mappings, and support for mounting devpts, ramfs, tmpfs, and mqueuefs as just the user namespace root. I do my best to document that if you care about limiting your unprivileged users that when you have the user namespace support enabled you will need to enable memory control groups. There is a minor bug fix to prevent overflowing the stack if someone creates way too many user namespaces. The bulk of the changes are a continuation of the kuid/kgid push down work through the filesystems. These changes make using uids and gids typesafe which ensures that these filesystems are safe to use when multiple user namespaces are in use. The filesystems converted for 3.9 are ceph, 9p, afs, ocfs2, gfs2, ncpfs, nfs, nfsd, and cifs. The changes for these filesystems were a little more involved so I split the changes into smaller hopefully obviously correct changes. XFS is the only filesystem that remains. I was hoping I could get that in this release so that user namespace support would be enabled with an allyesconfig or an allmodconfig but it looks like the xfs changes need another couple of days before it they are ready." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (93 commits) cifs: Enable building with user namespaces enabled. cifs: Convert struct cifs_ses to use a kuid_t and a kgid_t cifs: Convert struct cifs_sb_info to use kuids and kgids cifs: Modify struct smb_vol to use kuids and kgids cifs: Convert struct cifsFileInfo to use a kuid cifs: Convert struct cifs_fattr to use kuid and kgids cifs: Convert struct tcon_link to use a kuid. cifs: Modify struct cifs_unix_set_info_args to hold a kuid_t and a kgid_t cifs: Convert from a kuid before printing current_fsuid cifs: Use kuids and kgids SID to uid/gid mapping cifs: Pass GLOBAL_ROOT_UID and GLOBAL_ROOT_GID to keyring_alloc cifs: Use BUILD_BUG_ON to validate uids and gids are the same size cifs: Override unmappable incoming uids and gids nfsd: Enable building with user namespaces enabled. nfsd: Properly compare and initialize kuids and kgids nfsd: Store ex_anon_uid and ex_anon_gid as kuids and kgids nfsd: Modify nfsd4_cb_sec to use kuids and kgids nfsd: Handle kuids and kgids in the nfs4acl to posix_acl conversion nfsd: Convert nfsxdr to use kuids and kgids nfsd: Convert nfs3xdr to use kuids and kgids ...
Diffstat (limited to 'fs/gfs2/quota.c')
-rw-r--r--fs/gfs2/quota.c138
1 files changed, 55 insertions, 83 deletions
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 06122d09c0d1..c7c840e916f8 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -65,13 +65,10 @@
65#include "inode.h" 65#include "inode.h"
66#include "util.h" 66#include "util.h"
67 67
68#define QUOTA_USER 1
69#define QUOTA_GROUP 0
70
71struct gfs2_quota_change_host { 68struct gfs2_quota_change_host {
72 u64 qc_change; 69 u64 qc_change;
73 u32 qc_flags; /* GFS2_QCF_... */ 70 u32 qc_flags; /* GFS2_QCF_... */
74 u32 qc_id; 71 struct kqid qc_id;
75}; 72};
76 73
77static LIST_HEAD(qd_lru_list); 74static LIST_HEAD(qd_lru_list);
@@ -120,17 +117,24 @@ out:
120 return (atomic_read(&qd_lru_count) * sysctl_vfs_cache_pressure) / 100; 117 return (atomic_read(&qd_lru_count) * sysctl_vfs_cache_pressure) / 100;
121} 118}
122 119
120static u64 qd2index(struct gfs2_quota_data *qd)
121{
122 struct kqid qid = qd->qd_id;
123 return (2 * (u64)from_kqid(&init_user_ns, qid)) +
124 (qid.type == USRQUOTA) ? 0 : 1;
125}
126
123static u64 qd2offset(struct gfs2_quota_data *qd) 127static u64 qd2offset(struct gfs2_quota_data *qd)
124{ 128{
125 u64 offset; 129 u64 offset;
126 130
127 offset = 2 * (u64)qd->qd_id + !test_bit(QDF_USER, &qd->qd_flags); 131 offset = qd2index(qd);
128 offset *= sizeof(struct gfs2_quota); 132 offset *= sizeof(struct gfs2_quota);
129 133
130 return offset; 134 return offset;
131} 135}
132 136
133static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id, 137static int qd_alloc(struct gfs2_sbd *sdp, struct kqid qid,
134 struct gfs2_quota_data **qdp) 138 struct gfs2_quota_data **qdp)
135{ 139{
136 struct gfs2_quota_data *qd; 140 struct gfs2_quota_data *qd;
@@ -141,13 +145,11 @@ static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id,
141 return -ENOMEM; 145 return -ENOMEM;
142 146
143 atomic_set(&qd->qd_count, 1); 147 atomic_set(&qd->qd_count, 1);
144 qd->qd_id = id; 148 qd->qd_id = qid;
145 if (user)
146 set_bit(QDF_USER, &qd->qd_flags);
147 qd->qd_slot = -1; 149 qd->qd_slot = -1;
148 INIT_LIST_HEAD(&qd->qd_reclaim); 150 INIT_LIST_HEAD(&qd->qd_reclaim);
149 151
150 error = gfs2_glock_get(sdp, 2 * (u64)id + !user, 152 error = gfs2_glock_get(sdp, qd2index(qd),
151 &gfs2_quota_glops, CREATE, &qd->qd_gl); 153 &gfs2_quota_glops, CREATE, &qd->qd_gl);
152 if (error) 154 if (error)
153 goto fail; 155 goto fail;
@@ -161,7 +163,7 @@ fail:
161 return error; 163 return error;
162} 164}
163 165
164static int qd_get(struct gfs2_sbd *sdp, int user, u32 id, 166static int qd_get(struct gfs2_sbd *sdp, struct kqid qid,
165 struct gfs2_quota_data **qdp) 167 struct gfs2_quota_data **qdp)
166{ 168{
167 struct gfs2_quota_data *qd = NULL, *new_qd = NULL; 169 struct gfs2_quota_data *qd = NULL, *new_qd = NULL;
@@ -173,8 +175,7 @@ static int qd_get(struct gfs2_sbd *sdp, int user, u32 id,
173 found = 0; 175 found = 0;
174 spin_lock(&qd_lru_lock); 176 spin_lock(&qd_lru_lock);
175 list_for_each_entry(qd, &sdp->sd_quota_list, qd_list) { 177 list_for_each_entry(qd, &sdp->sd_quota_list, qd_list) {
176 if (qd->qd_id == id && 178 if (qid_eq(qd->qd_id, qid)) {
177 !test_bit(QDF_USER, &qd->qd_flags) == !user) {
178 if (!atomic_read(&qd->qd_count) && 179 if (!atomic_read(&qd->qd_count) &&
179 !list_empty(&qd->qd_reclaim)) { 180 !list_empty(&qd->qd_reclaim)) {
180 /* Remove it from reclaim list */ 181 /* Remove it from reclaim list */
@@ -208,7 +209,7 @@ static int qd_get(struct gfs2_sbd *sdp, int user, u32 id,
208 return 0; 209 return 0;
209 } 210 }
210 211
211 error = qd_alloc(sdp, user, id, &new_qd); 212 error = qd_alloc(sdp, qid, &new_qd);
212 if (error) 213 if (error)
213 return error; 214 return error;
214 } 215 }
@@ -458,12 +459,12 @@ static void qd_unlock(struct gfs2_quota_data *qd)
458 qd_put(qd); 459 qd_put(qd);
459} 460}
460 461
461static int qdsb_get(struct gfs2_sbd *sdp, int user, u32 id, 462static int qdsb_get(struct gfs2_sbd *sdp, struct kqid qid,
462 struct gfs2_quota_data **qdp) 463 struct gfs2_quota_data **qdp)
463{ 464{
464 int error; 465 int error;
465 466
466 error = qd_get(sdp, user, id, qdp); 467 error = qd_get(sdp, qid, qdp);
467 if (error) 468 if (error)
468 return error; 469 return error;
469 470
@@ -491,7 +492,7 @@ static void qdsb_put(struct gfs2_quota_data *qd)
491 qd_put(qd); 492 qd_put(qd);
492} 493}
493 494
494int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) 495int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
495{ 496{
496 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 497 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
497 struct gfs2_quota_data **qd; 498 struct gfs2_quota_data **qd;
@@ -512,28 +513,30 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
512 if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) 513 if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
513 return 0; 514 return 0;
514 515
515 error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, qd); 516 error = qdsb_get(sdp, make_kqid_uid(ip->i_inode.i_uid), qd);
516 if (error) 517 if (error)
517 goto out; 518 goto out;
518 ip->i_res->rs_qa_qd_num++; 519 ip->i_res->rs_qa_qd_num++;
519 qd++; 520 qd++;
520 521
521 error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, qd); 522 error = qdsb_get(sdp, make_kqid_gid(ip->i_inode.i_gid), qd);
522 if (error) 523 if (error)
523 goto out; 524 goto out;
524 ip->i_res->rs_qa_qd_num++; 525 ip->i_res->rs_qa_qd_num++;
525 qd++; 526 qd++;
526 527
527 if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) { 528 if (!uid_eq(uid, NO_UID_QUOTA_CHANGE) &&
528 error = qdsb_get(sdp, QUOTA_USER, uid, qd); 529 !uid_eq(uid, ip->i_inode.i_uid)) {
530 error = qdsb_get(sdp, make_kqid_uid(uid), qd);
529 if (error) 531 if (error)
530 goto out; 532 goto out;
531 ip->i_res->rs_qa_qd_num++; 533 ip->i_res->rs_qa_qd_num++;
532 qd++; 534 qd++;
533 } 535 }
534 536
535 if (gid != NO_QUOTA_CHANGE && gid != ip->i_inode.i_gid) { 537 if (!gid_eq(gid, NO_GID_QUOTA_CHANGE) &&
536 error = qdsb_get(sdp, QUOTA_GROUP, gid, qd); 538 !gid_eq(gid, ip->i_inode.i_gid)) {
539 error = qdsb_get(sdp, make_kqid_gid(gid), qd);
537 if (error) 540 if (error)
538 goto out; 541 goto out;
539 ip->i_res->rs_qa_qd_num++; 542 ip->i_res->rs_qa_qd_num++;
@@ -567,18 +570,10 @@ static int sort_qd(const void *a, const void *b)
567 const struct gfs2_quota_data *qd_a = *(const struct gfs2_quota_data **)a; 570 const struct gfs2_quota_data *qd_a = *(const struct gfs2_quota_data **)a;
568 const struct gfs2_quota_data *qd_b = *(const struct gfs2_quota_data **)b; 571 const struct gfs2_quota_data *qd_b = *(const struct gfs2_quota_data **)b;
569 572
570 if (!test_bit(QDF_USER, &qd_a->qd_flags) != 573 if (qid_lt(qd_a->qd_id, qd_b->qd_id))
571 !test_bit(QDF_USER, &qd_b->qd_flags)) {
572 if (test_bit(QDF_USER, &qd_a->qd_flags))
573 return -1;
574 else
575 return 1;
576 }
577 if (qd_a->qd_id < qd_b->qd_id)
578 return -1; 574 return -1;
579 if (qd_a->qd_id > qd_b->qd_id) 575 if (qid_lt(qd_b->qd_id, qd_a->qd_id))
580 return 1; 576 return 1;
581
582 return 0; 577 return 0;
583} 578}
584 579
@@ -595,9 +590,9 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change)
595 if (!test_bit(QDF_CHANGE, &qd->qd_flags)) { 590 if (!test_bit(QDF_CHANGE, &qd->qd_flags)) {
596 qc->qc_change = 0; 591 qc->qc_change = 0;
597 qc->qc_flags = 0; 592 qc->qc_flags = 0;
598 if (test_bit(QDF_USER, &qd->qd_flags)) 593 if (qd->qd_id.type == USRQUOTA)
599 qc->qc_flags = cpu_to_be32(GFS2_QCF_USER); 594 qc->qc_flags = cpu_to_be32(GFS2_QCF_USER);
600 qc->qc_id = cpu_to_be32(qd->qd_id); 595 qc->qc_id = cpu_to_be32(from_kqid(&init_user_ns, qd->qd_id));
601 } 596 }
602 597
603 x = be64_to_cpu(qc->qc_change) + change; 598 x = be64_to_cpu(qc->qc_change) + change;
@@ -925,7 +920,7 @@ fail:
925 return error; 920 return error;
926} 921}
927 922
928int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid) 923int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
929{ 924{
930 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 925 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
931 struct gfs2_quota_data *qd; 926 struct gfs2_quota_data *qd;
@@ -1040,13 +1035,13 @@ static int print_message(struct gfs2_quota_data *qd, char *type)
1040 1035
1041 printk(KERN_INFO "GFS2: fsid=%s: quota %s for %s %u\n", 1036 printk(KERN_INFO "GFS2: fsid=%s: quota %s for %s %u\n",
1042 sdp->sd_fsname, type, 1037 sdp->sd_fsname, type,
1043 (test_bit(QDF_USER, &qd->qd_flags)) ? "user" : "group", 1038 (qd->qd_id.type == USRQUOTA) ? "user" : "group",
1044 qd->qd_id); 1039 from_kqid(&init_user_ns, qd->qd_id));
1045 1040
1046 return 0; 1041 return 0;
1047} 1042}
1048 1043
1049int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid) 1044int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
1050{ 1045{
1051 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1046 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1052 struct gfs2_quota_data *qd; 1047 struct gfs2_quota_data *qd;
@@ -1063,8 +1058,8 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
1063 for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { 1058 for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) {
1064 qd = ip->i_res->rs_qa_qd[x]; 1059 qd = ip->i_res->rs_qa_qd[x];
1065 1060
1066 if (!((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || 1061 if (!(qid_eq(qd->qd_id, make_kqid_uid(uid)) ||
1067 (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags)))) 1062 qid_eq(qd->qd_id, make_kqid_gid(gid))))
1068 continue; 1063 continue;
1069 1064
1070 value = (s64)be64_to_cpu(qd->qd_qb.qb_value); 1065 value = (s64)be64_to_cpu(qd->qd_qb.qb_value);
@@ -1074,10 +1069,7 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
1074 1069
1075 if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) { 1070 if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) {
1076 print_message(qd, "exceeded"); 1071 print_message(qd, "exceeded");
1077 quota_send_warning(make_kqid(&init_user_ns, 1072 quota_send_warning(qd->qd_id,
1078 test_bit(QDF_USER, &qd->qd_flags) ?
1079 USRQUOTA : GRPQUOTA,
1080 qd->qd_id),
1081 sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN); 1073 sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN);
1082 1074
1083 error = -EDQUOT; 1075 error = -EDQUOT;
@@ -1087,10 +1079,7 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
1087 time_after_eq(jiffies, qd->qd_last_warn + 1079 time_after_eq(jiffies, qd->qd_last_warn +
1088 gfs2_tune_get(sdp, 1080 gfs2_tune_get(sdp,
1089 gt_quota_warn_period) * HZ)) { 1081 gt_quota_warn_period) * HZ)) {
1090 quota_send_warning(make_kqid(&init_user_ns, 1082 quota_send_warning(qd->qd_id,
1091 test_bit(QDF_USER, &qd->qd_flags) ?
1092 USRQUOTA : GRPQUOTA,
1093 qd->qd_id),
1094 sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN); 1083 sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN);
1095 error = print_message(qd, "warning"); 1084 error = print_message(qd, "warning");
1096 qd->qd_last_warn = jiffies; 1085 qd->qd_last_warn = jiffies;
@@ -1101,7 +1090,7 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
1101} 1090}
1102 1091
1103void gfs2_quota_change(struct gfs2_inode *ip, s64 change, 1092void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
1104 u32 uid, u32 gid) 1093 kuid_t uid, kgid_t gid)
1105{ 1094{
1106 struct gfs2_quota_data *qd; 1095 struct gfs2_quota_data *qd;
1107 unsigned int x; 1096 unsigned int x;
@@ -1114,8 +1103,8 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
1114 for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { 1103 for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) {
1115 qd = ip->i_res->rs_qa_qd[x]; 1104 qd = ip->i_res->rs_qa_qd[x];
1116 1105
1117 if ((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || 1106 if (qid_eq(qd->qd_id, make_kqid_uid(uid)) ||
1118 (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags))) { 1107 qid_eq(qd->qd_id, make_kqid_gid(gid))) {
1119 do_qc(qd, change); 1108 do_qc(qd, change);
1120 } 1109 }
1121 } 1110 }
@@ -1170,13 +1159,13 @@ static int gfs2_quota_sync_timeo(struct super_block *sb, int type)
1170 return gfs2_quota_sync(sb, type); 1159 return gfs2_quota_sync(sb, type);
1171} 1160}
1172 1161
1173int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id) 1162int gfs2_quota_refresh(struct gfs2_sbd *sdp, struct kqid qid)
1174{ 1163{
1175 struct gfs2_quota_data *qd; 1164 struct gfs2_quota_data *qd;
1176 struct gfs2_holder q_gh; 1165 struct gfs2_holder q_gh;
1177 int error; 1166 int error;
1178 1167
1179 error = qd_get(sdp, user, id, &qd); 1168 error = qd_get(sdp, qid, &qd);
1180 if (error) 1169 if (error)
1181 return error; 1170 return error;
1182 1171
@@ -1194,7 +1183,9 @@ static void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *
1194 1183
1195 qc->qc_change = be64_to_cpu(str->qc_change); 1184 qc->qc_change = be64_to_cpu(str->qc_change);
1196 qc->qc_flags = be32_to_cpu(str->qc_flags); 1185 qc->qc_flags = be32_to_cpu(str->qc_flags);
1197 qc->qc_id = be32_to_cpu(str->qc_id); 1186 qc->qc_id = make_kqid(&init_user_ns,
1187 (qc->qc_flags & GFS2_QCF_USER)?USRQUOTA:GRPQUOTA,
1188 be32_to_cpu(str->qc_id));
1198} 1189}
1199 1190
1200int gfs2_quota_init(struct gfs2_sbd *sdp) 1191int gfs2_quota_init(struct gfs2_sbd *sdp)
@@ -1257,8 +1248,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp)
1257 if (!qc.qc_change) 1248 if (!qc.qc_change)
1258 continue; 1249 continue;
1259 1250
1260 error = qd_alloc(sdp, (qc.qc_flags & GFS2_QCF_USER), 1251 error = qd_alloc(sdp, qc.qc_id, &qd);
1261 qc.qc_id, &qd);
1262 if (error) { 1252 if (error) {
1263 brelse(bh); 1253 brelse(bh);
1264 goto fail; 1254 goto fail;
@@ -1485,21 +1475,17 @@ static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid,
1485 struct gfs2_quota_data *qd; 1475 struct gfs2_quota_data *qd;
1486 struct gfs2_holder q_gh; 1476 struct gfs2_holder q_gh;
1487 int error; 1477 int error;
1488 int type;
1489 1478
1490 memset(fdq, 0, sizeof(struct fs_disk_quota)); 1479 memset(fdq, 0, sizeof(struct fs_disk_quota));
1491 1480
1492 if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) 1481 if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
1493 return -ESRCH; /* Crazy XFS error code */ 1482 return -ESRCH; /* Crazy XFS error code */
1494 1483
1495 if (qid.type == USRQUOTA) 1484 if ((qid.type != USRQUOTA) &&
1496 type = QUOTA_USER; 1485 (qid.type != GRPQUOTA))
1497 else if (qid.type == GRPQUOTA)
1498 type = QUOTA_GROUP;
1499 else
1500 return -EINVAL; 1486 return -EINVAL;
1501 1487
1502 error = qd_get(sdp, type, from_kqid(&init_user_ns, qid), &qd); 1488 error = qd_get(sdp, qid, &qd);
1503 if (error) 1489 if (error)
1504 return error; 1490 return error;
1505 error = do_glock(qd, FORCE, &q_gh); 1491 error = do_glock(qd, FORCE, &q_gh);
@@ -1508,8 +1494,8 @@ static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid,
1508 1494
1509 qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lksb.sb_lvbptr; 1495 qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lksb.sb_lvbptr;
1510 fdq->d_version = FS_DQUOT_VERSION; 1496 fdq->d_version = FS_DQUOT_VERSION;
1511 fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA; 1497 fdq->d_flags = (qid.type == USRQUOTA) ? FS_USER_QUOTA : FS_GROUP_QUOTA;
1512 fdq->d_id = from_kqid(&init_user_ns, qid); 1498 fdq->d_id = from_kqid_munged(current_user_ns(), qid);
1513 fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift; 1499 fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift;
1514 fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift; 1500 fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift;
1515 fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift; 1501 fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift;
@@ -1535,32 +1521,18 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid,
1535 int alloc_required; 1521 int alloc_required;
1536 loff_t offset; 1522 loff_t offset;
1537 int error; 1523 int error;
1538 int type;
1539 1524
1540 if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) 1525 if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
1541 return -ESRCH; /* Crazy XFS error code */ 1526 return -ESRCH; /* Crazy XFS error code */
1542 1527
1543 switch(qid.type) { 1528 if ((qid.type != USRQUOTA) &&
1544 case USRQUOTA: 1529 (qid.type != GRPQUOTA))
1545 type = QUOTA_USER;
1546 if (fdq->d_flags != FS_USER_QUOTA)
1547 return -EINVAL;
1548 break;
1549 case GRPQUOTA:
1550 type = QUOTA_GROUP;
1551 if (fdq->d_flags != FS_GROUP_QUOTA)
1552 return -EINVAL;
1553 break;
1554 default:
1555 return -EINVAL; 1530 return -EINVAL;
1556 }
1557 1531
1558 if (fdq->d_fieldmask & ~GFS2_FIELDMASK) 1532 if (fdq->d_fieldmask & ~GFS2_FIELDMASK)
1559 return -EINVAL; 1533 return -EINVAL;
1560 if (fdq->d_id != from_kqid(&init_user_ns, qid))
1561 return -EINVAL;
1562 1534
1563 error = qd_get(sdp, type, from_kqid(&init_user_ns, qid), &qd); 1535 error = qd_get(sdp, qid, &qd);
1564 if (error) 1536 if (error)
1565 return error; 1537 return error;
1566 1538