]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/gfs2/quota.c
GFS2: Extract quota data from reservations structure (revert 5407e24)
[linux.git] / fs / gfs2 / quota.c
index e01298d922c09d9f4ad0e8b2f96fdc0e41cab134..b845efdb5e3a485af11aaaa10cf0de6ddf838a51 100644 (file)
@@ -527,37 +527,70 @@ static void qdsb_put(struct gfs2_quota_data *qd)
        qd_put(qd);
 }
 
+/**
+ * gfs2_qa_alloc - make sure we have a quota allocations data structure,
+ *                 if necessary
+ * @ip: the inode for this reservation
+ */
+int gfs2_qa_alloc(struct gfs2_inode *ip)
+{
+       int error = 0;
+       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
+
+       if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
+               return 0;
+
+       down_write(&ip->i_rw_mutex);
+       if (ip->i_qadata == NULL) {
+               ip->i_qadata = kmem_cache_zalloc(gfs2_qadata_cachep, GFP_NOFS);
+               if (!ip->i_qadata)
+                       error = -ENOMEM;
+       }
+       up_write(&ip->i_rw_mutex);
+       return error;
+}
+
+void gfs2_qa_delete(struct gfs2_inode *ip)
+{
+       down_write(&ip->i_rw_mutex);
+       if (ip->i_qadata) {
+               kmem_cache_free(gfs2_qadata_cachep, ip->i_qadata);
+               ip->i_qadata = NULL;
+       }
+       up_write(&ip->i_rw_mutex);
+}
+
 int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        struct gfs2_quota_data **qd;
        int error;
 
-       if (ip->i_res == NULL) {
-               error = gfs2_rs_alloc(ip);
+       if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
+               return 0;
+
+       if (ip->i_qadata == NULL) {
+               error = gfs2_rsqa_alloc(ip);
                if (error)
                        return error;
        }
 
-       qd = ip->i_res->rs_qa_qd;
+       qd = ip->i_qadata->qa_qd;
 
-       if (gfs2_assert_warn(sdp, !ip->i_res->rs_qa_qd_num) ||
+       if (gfs2_assert_warn(sdp, !ip->i_qadata->qa_qd_num) ||
            gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)))
                return -EIO;
 
-       if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
-               return 0;
-
        error = qdsb_get(sdp, make_kqid_uid(ip->i_inode.i_uid), qd);
        if (error)
                goto out;
-       ip->i_res->rs_qa_qd_num++;
+       ip->i_qadata->qa_qd_num++;
        qd++;
 
        error = qdsb_get(sdp, make_kqid_gid(ip->i_inode.i_gid), qd);
        if (error)
                goto out;
-       ip->i_res->rs_qa_qd_num++;
+       ip->i_qadata->qa_qd_num++;
        qd++;
 
        if (!uid_eq(uid, NO_UID_QUOTA_CHANGE) &&
@@ -565,7 +598,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
                error = qdsb_get(sdp, make_kqid_uid(uid), qd);
                if (error)
                        goto out;
-               ip->i_res->rs_qa_qd_num++;
+               ip->i_qadata->qa_qd_num++;
                qd++;
        }
 
@@ -574,7 +607,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
                error = qdsb_get(sdp, make_kqid_gid(gid), qd);
                if (error)
                        goto out;
-               ip->i_res->rs_qa_qd_num++;
+               ip->i_qadata->qa_qd_num++;
                qd++;
        }
 
@@ -589,15 +622,15 @@ void gfs2_quota_unhold(struct gfs2_inode *ip)
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
        unsigned int x;
 
-       if (ip->i_res == NULL)
+       if (ip->i_qadata == NULL)
                return;
        gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags));
 
-       for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) {
-               qdsb_put(ip->i_res->rs_qa_qd[x]);
-               ip->i_res->rs_qa_qd[x] = NULL;
+       for (x = 0; x < ip->i_qadata->qa_qd_num; x++) {
+               qdsb_put(ip->i_qadata->qa_qd[x]);
+               ip->i_qadata->qa_qd[x] = NULL;
        }
-       ip->i_res->rs_qa_qd_num = 0;
+       ip->i_qadata->qa_qd_num = 0;
 }
 
 static int sort_qd(const void *a, const void *b)
@@ -843,7 +876,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
        unsigned int nalloc = 0, blocks;
        int error;
 
-       error = gfs2_rs_alloc(ip);
+       error = gfs2_rsqa_alloc(ip);
        if (error)
                return error;
 
@@ -1006,20 +1039,20 @@ int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
        unsigned int x;
        int error = 0;
 
-       error = gfs2_quota_hold(ip, uid, gid);
-       if (error)
-               return error;
-
        if (capable(CAP_SYS_RESOURCE) ||
            sdp->sd_args.ar_quota != GFS2_QUOTA_ON)
                return 0;
 
-       sort(ip->i_res->rs_qa_qd, ip->i_res->rs_qa_qd_num,
+       error = gfs2_quota_hold(ip, uid, gid);
+       if (error)
+               return error;
+
+       sort(ip->i_qadata->qa_qd, ip->i_qadata->qa_qd_num,
             sizeof(struct gfs2_quota_data *), sort_qd, NULL);
 
-       for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) {
-               qd = ip->i_res->rs_qa_qd[x];
-               error = do_glock(qd, NO_FORCE, &ip->i_res->rs_qa_qd_ghs[x]);
+       for (x = 0; x < ip->i_qadata->qa_qd_num; x++) {
+               qd = ip->i_qadata->qa_qd[x];
+               error = do_glock(qd, NO_FORCE, &ip->i_qadata->qa_qd_ghs[x]);
                if (error)
                        break;
        }
@@ -1028,7 +1061,7 @@ int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid)
                set_bit(GIF_QD_LOCKED, &ip->i_flags);
        else {
                while (x--)
-                       gfs2_glock_dq_uninit(&ip->i_res->rs_qa_qd_ghs[x]);
+                       gfs2_glock_dq_uninit(&ip->i_qadata->qa_qd_ghs[x]);
                gfs2_quota_unhold(ip);
        }
 
@@ -1082,14 +1115,14 @@ void gfs2_quota_unlock(struct gfs2_inode *ip)
        if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags))
                goto out;
 
-       for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) {
+       for (x = 0; x < ip->i_qadata->qa_qd_num; x++) {
                struct gfs2_quota_data *qd;
                int sync;
 
-               qd = ip->i_res->rs_qa_qd[x];
+               qd = ip->i_qadata->qa_qd[x];
                sync = need_sync(qd);
 
-               gfs2_glock_dq_uninit(&ip->i_res->rs_qa_qd_ghs[x]);
+               gfs2_glock_dq_uninit(&ip->i_qadata->qa_qd_ghs[x]);
                if (!sync)
                        continue;
 
@@ -1168,8 +1201,8 @@ int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid,
         if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON)
                 return 0;
 
-       for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) {
-               qd = ip->i_res->rs_qa_qd[x];
+       for (x = 0; x < ip->i_qadata->qa_qd_num; x++) {
+               qd = ip->i_qadata->qa_qd[x];
 
                if (!(qid_eq(qd->qd_id, make_kqid_uid(uid)) ||
                      qid_eq(qd->qd_id, make_kqid_gid(gid))))
@@ -1217,14 +1250,16 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
 {
        struct gfs2_quota_data *qd;
        unsigned int x;
+       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
 
-       if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), change))
+       if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON ||
+           gfs2_assert_warn(sdp, change))
                return;
        if (ip->i_diskflags & GFS2_DIF_SYSTEM)
                return;
 
-       for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) {
-               qd = ip->i_res->rs_qa_qd[x];
+       for (x = 0; x < ip->i_qadata->qa_qd_num; x++) {
+               qd = ip->i_qadata->qa_qd[x];
 
                if (qid_eq(qd->qd_id, make_kqid_uid(uid)) ||
                    qid_eq(qd->qd_id, make_kqid_gid(gid))) {
@@ -1635,7 +1670,7 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid,
        if (error)
                return error;
 
-       error = gfs2_rs_alloc(ip);
+       error = gfs2_rsqa_alloc(ip);
        if (error)
                goto out_put;