Whamcloud - gitweb
Branch HEAD
authortianzy <tianzy>
Fri, 24 Aug 2007 12:39:50 +0000 (12:39 +0000)
committertianzy <tianzy>
Fri, 24 Aug 2007 12:39:50 +0000 (12:39 +0000)
fix the bug of "mds_obd_create error creating tmp object"
b=12223
i=green
i=wangdi

lustre/ChangeLog
lustre/include/lustre_log.h
lustre/mds/mds_fs.c
lustre/obdclass/llog_obd.c
lustre/quota/quota_context.c
lustre/quota/quota_ctl.c
lustre/quota/quota_master.c
lustre/tests/sanity-quota.sh

index cd2acd2..6d7c580 100644 (file)
@@ -144,6 +144,12 @@ Bugzilla   : 13362
 Description: Sanity.sh test_65k failed: setstripe should have succeeded
 Details    : execute lfs setstripe on client
 
+Severity   : major
+Bugzilla   : 12223
+Description: mds_obd_create error creating tmp object
+Details    : When the user sets quota on root, llog will be affected and can't 
+             create files and write files.
+
 --------------------------------------------------------------------------------
 
 2007-08-10         Cluster File Systems, Inc. <info@clusterfs.com>
index 9f6725f..e32a840 100644 (file)
@@ -217,6 +217,14 @@ struct llog_ctxt {
         void                    *llog_proc_cb;
 };
 
+#ifndef __KERNEL__
+
+#define cap_raise(c, flag) do {} while(0)
+
+#define CAP_SYS_RESOURCE 24
+
+#endif   /* !__KERNEL__ */
+
 static inline void llog_gen_init(struct llog_ctxt *ctxt)
 {
         struct obd_device *obd = ctxt->loc_exp->exp_obd;
@@ -292,6 +300,7 @@ static inline int llog_write_rec(struct llog_handle *handle,
                                  int numcookies, void *buf, int idx)
 {
         struct llog_operations *lop;
+        __u32 cap;
         int rc, buflen;
         ENTRY;
 
@@ -309,7 +318,10 @@ static inline int llog_write_rec(struct llog_handle *handle,
                 buflen = rec->lrh_len;
         LASSERT(size_round(buflen) == buflen);
 
+        cap = current->cap_effective;             
+        cap_raise(current->cap_effective, CAP_SYS_RESOURCE); 
         rc = lop->lop_write_rec(handle, rec, logcookies, numcookies, buf, idx);
+        current->cap_effective = cap; 
         RETURN(rc);
 }
 
@@ -405,6 +417,7 @@ static inline int llog_create(struct llog_ctxt *ctxt, struct llog_handle **res,
                               struct llog_logid *logid, char *name)
 {
         struct llog_operations *lop;
+        __u32 cap;
         int rc;
         ENTRY;
 
@@ -414,7 +427,10 @@ static inline int llog_create(struct llog_ctxt *ctxt, struct llog_handle **res,
         if (lop->lop_create == NULL)
                 RETURN(-EOPNOTSUPP);
 
+        cap = current->cap_effective;             
+        cap_raise(current->cap_effective, CAP_SYS_RESOURCE);
         rc = lop->lop_create(ctxt, res, logid, name);
+        current->cap_effective = cap; 
         RETURN(rc);
 }
 
index b1e80ec..c62dd11 100644 (file)
@@ -708,7 +708,7 @@ int mds_obd_create(struct obd_export *exp, struct obdo *oa,
         ENTRY;
 
         /* the owner of object file should always be root */
-        ucred.luc_cap = current->cap_effective | CAP_SYS_RESOURCE;
+        cap_raise(ucred.luc_cap, CAP_SYS_RESOURCE);
 
         if (strncmp(exp->exp_obd->obd_name, MDD_OBD_NAME,
                                    strlen(MDD_OBD_NAME))) {
@@ -800,7 +800,7 @@ int mds_obd_destroy(struct obd_export *exp, struct obdo *oa,
         int err, namelen, rc = 0;
         ENTRY;
 
-        ucred.luc_cap = current->cap_effective | CAP_SYS_RESOURCE;
+        cap_raise(ucred.luc_cap, CAP_SYS_RESOURCE);
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, &ucred);
 
         namelen = ll_fid2str(fidname, oa->o_id, oa->o_generation);
index f8c875b..f2cd312 100644 (file)
@@ -136,6 +136,7 @@ int llog_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec,
                 struct lov_stripe_md *lsm, struct llog_cookie *logcookies,
                 int numcookies)
 {
+        __u32 cap;
         int rc;
         ENTRY;
 
@@ -145,8 +146,10 @@ int llog_add(struct llog_ctxt *ctxt, struct llog_rec_hdr *rec,
         }
         
         CTXT_CHECK_OP(ctxt, add, -EOPNOTSUPP);
-
+       cap = current->cap_effective;             
+        cap_raise(current->cap_effective, CAP_SYS_RESOURCE);
         rc = CTXTP(ctxt, add)(ctxt, rec, lsm, logcookies, numcookies);
+       current->cap_effective = cap; 
         RETURN(rc);
 }
 EXPORT_SYMBOL(llog_add);
index 595f5e4..65c727e 100644 (file)
@@ -210,10 +210,6 @@ check_cur_qunit(struct obd_device *obd,
         if (!sb_any_quota_enabled(sb))
                 RETURN(0);
 
-        /* ignore root user */
-        if (qdata->qd_id == 0 && qdata_type == USRQUOTA)
-                RETURN(0);
-
         OBD_ALLOC_PTR(qctl);
         if (qctl == NULL)
                 RETURN(-ENOMEM);
index c056048..4f50f7d 100644 (file)
@@ -128,6 +128,20 @@ int filter_quota_ctl(struct obd_export *exp, struct obd_quotactl *oqctl)
                         atomic_inc(&obt->obt_quotachecking);
                 }
                 break;
+        case Q_SETQUOTA:
+                qctxt_wait_pending_dqacq(&obd->u.obt.obt_qctxt, 
+                                         oqctl->qc_id, oqctl->qc_type, 1);
+
+                push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+                rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl);
+
+                if (!rc) {
+                        oqctl->qc_cmd = Q_SYNC;
+                        fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl);
+                        oqctl->qc_cmd = Q_SETQUOTA;
+                }
+                pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+                break;
         case Q_INITQUOTA:
                 {
                 unsigned int uid = 0, gid = 0;
@@ -234,7 +248,8 @@ int lov_quota_ctl(struct obd_export *exp, struct obd_quotactl *oqctl)
         ENTRY;
 
         if (oqctl->qc_cmd != Q_QUOTAON && oqctl->qc_cmd != Q_QUOTAOFF &&
-            oqctl->qc_cmd != Q_GETOQUOTA && oqctl->qc_cmd != Q_INITQUOTA) {
+            oqctl->qc_cmd != Q_GETOQUOTA && oqctl->qc_cmd != Q_INITQUOTA &&
+            oqctl->qc_cmd != Q_SETQUOTA) {
                 CERROR("bad quota opc %x for lov obd", oqctl->qc_cmd);
                 RETURN(-EFAULT);
         }
index 216f2c2..f007b68 100644 (file)
@@ -214,9 +214,6 @@ int dqacq_handler(struct obd_device *obd, struct qunit_data *qdata, int opc)
 
         OBD_FAIL_RETURN(OBD_FAIL_OBD_DQACQ, -EIO);
 
-        /* slaves never acquires qunit for user root */
-        LASSERT(qdata->qd_id || qdata_type);
-
         dquot = lustre_dqget(obd, info, qdata->qd_id, qdata_type);
         if (IS_ERR(dquot))
                 RETURN(PTR_ERR(dquot));
@@ -651,31 +648,32 @@ static int mds_init_slave_ilimits(struct obd_device *obd,
         /* XXX: for file limits only adjust local now */
         unsigned int uid = 0, gid = 0;
         struct obd_quotactl *ioqc = NULL;
+        int flag;
         int rc;
         ENTRY;
 
         /* if we are going to set zero limit, needn't init slaves */
-        if (!oqctl->qc_dqblk.dqb_ihardlimit && !oqctl->qc_dqblk.dqb_isoftlimit)
+        if (!oqctl->qc_dqblk.dqb_ihardlimit && !oqctl->qc_dqblk.dqb_isoftlimit &&
+            set)
                 RETURN(0);
-        
-        if (!set)
-                goto acquire;
 
         OBD_ALLOC_PTR(ioqc);
         if (!ioqc)
                 RETURN(-ENOMEM);
-
-        ioqc->qc_cmd = Q_INITQUOTA;
+        
+        flag = oqctl->qc_dqblk.dqb_ihardlimit || 
+               oqctl->qc_dqblk.dqb_isoftlimit || set;
+        ioqc->qc_cmd = flag ? Q_INITQUOTA : Q_SETQUOTA;
         ioqc->qc_id = oqctl->qc_id;
         ioqc->qc_type = oqctl->qc_type;
         ioqc->qc_dqblk.dqb_valid = QIF_ILIMITS;
-        ioqc->qc_dqblk.dqb_ihardlimit = MIN_QLIMIT;
+        ioqc->qc_dqblk.dqb_ihardlimit = flag ? MIN_QLIMIT : 0;
 
         /* set local limit to MIN_QLIMIT */
         rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, ioqc);
         if (rc)
                 GOTO(out, rc);
-acquire:
+
         /* trigger local qunit pre-acquire */
         if (oqctl->qc_type == USRQUOTA)
                 uid = oqctl->qc_id;
@@ -701,29 +699,30 @@ static int mds_init_slave_blimits(struct obd_device *obd,
         struct mds_obd *mds = &obd->u.mds;
         struct obd_quotactl *ioqc;
         unsigned int uid = 0, gid = 0;
+        int flag;
         int rc;
         ENTRY;
 
         /* if we are going to set zero limit, needn't init slaves */
-        if (!oqctl->qc_dqblk.dqb_bhardlimit && !oqctl->qc_dqblk.dqb_bsoftlimit)
+        if (!oqctl->qc_dqblk.dqb_bhardlimit && !oqctl->qc_dqblk.dqb_bsoftlimit &&
+            set)
                 RETURN(0);
 
         OBD_ALLOC_PTR(ioqc);
         if (!ioqc)
                 RETURN(-ENOMEM);
 
-        ioqc->qc_cmd = Q_INITQUOTA;
+        flag = oqctl->qc_dqblk.dqb_bhardlimit || 
+               oqctl->qc_dqblk.dqb_bsoftlimit || set;
+        ioqc->qc_cmd = flag ? Q_INITQUOTA : Q_SETQUOTA;
         ioqc->qc_id = oqctl->qc_id;
         ioqc->qc_type = oqctl->qc_type;
         ioqc->qc_dqblk.dqb_valid = QIF_BLIMITS;
-        ioqc->qc_dqblk.dqb_bhardlimit = set ? MIN_QLIMIT : 0;
+        ioqc->qc_dqblk.dqb_bhardlimit = flag ? MIN_QLIMIT : 0;
 
-        /* set local limit to MIN_QLIMIT */
-        if (set) {
-                rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, ioqc);
-                if (rc)
-                        GOTO(out, rc);
-        }
+        rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, ioqc);
+        if (rc)
+                GOTO(out, rc);
 
         /* trigger local qunit pre-acquire */
         if (oqctl->qc_type == USRQUOTA)
index 09184c9..73241fe 100644 (file)
@@ -1050,6 +1050,56 @@ test_13() {
 }
 run_test 13 "test multiple clients write block quota ==="
 
+check_if_quota_zero(){
+        line=`$LFS quota -$1 $2 $MOUNT | wc -l`
+       for i in `seq 3 $line`; do
+           for j in 3 4 6 7; do
+               tmp=`$LFS quota -$1 $2 $MOUNT | sed -n ${i}p | 
+                     awk  '{print $'"$j"'}'`
+               [ -n "$tmp" ] && [ $tmp -ne 0 ] && $LFS quota -$1 $2 $MOUNT && \
+                   error "quota on $1 isn't clean"
+           done
+       done
+       echo "pass check_if_quota_zero"
+}
+
+# test setting quota on root, b=12223
+test_13(){
+        TESTFILE="$TSTDIR/quota_tst13"
+
+       # reboot the lustre
+       cd $T_PWD; sh llmountcleanup.sh || error "llmountcleanup failed"
+       sh llmount.sh 
+       pre_test
+       setup
+       run_test 0 "reboot lustre"
+
+       # out of root's file and block quota
+        $LFS setquota -u root 10 10 10 10 $MOUNT
+       createmany -m ${TESTFILE} 20 || \
+           error "unexpected: user(root) create files failly!"
+       dd if=/dev/zero of=$TESTFILE bs=4k count=4096 || \
+           error "unexpected: user(root) write files failly!"
+       chmod 666 $TESTFILE
+       $RUNAS dd if=/dev/zero of=${TESTFILE} seek=4096 bs=4k count=4096 && \
+           error "unexpected: user(quota_usr) write a file successfully!"      
+
+       # trigger the llog
+       chmod 777 $MOUNT
+       for i in `seq 1 10`; do $RUNAS touch ${TESTFILE}a_$i; done 
+       for i in `seq 1 10`; do $RUNAS rm -f ${TESTFILE}a_$i; done 
+
+       # do the check
+       dmesg | tail | grep "\-122" |grep llog_obd_origin_add && error "test_13 failed."
+       $LFS setquota -u root 0 0 0 0 $MOUNT
+       #check_if_quota_zero u root
+
+       # clean 
+       unlinkmany ${TESTFILE} 15
+       rm -f $TESTFILE
+}
+run_test 13 "test setting quota on root ==="
+
 # turn off quota
 test_99()
 {