From 75b2f9067d9ead67492593ea76611f7e75c8d56e Mon Sep 17 00:00:00 2001 From: tianzy Date: Fri, 24 Aug 2007 12:39:50 +0000 Subject: [PATCH] Branch HEAD fix the bug of "mds_obd_create error creating tmp object" b=12223 i=green i=wangdi --- lustre/ChangeLog | 6 ++++++ lustre/include/lustre_log.h | 16 ++++++++++++++ lustre/mds/mds_fs.c | 4 ++-- lustre/obdclass/llog_obd.c | 5 ++++- lustre/quota/quota_context.c | 4 ---- lustre/quota/quota_ctl.c | 17 ++++++++++++++- lustre/quota/quota_master.c | 39 +++++++++++++++++----------------- lustre/tests/sanity-quota.sh | 50 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 113 insertions(+), 28 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index cd2acd2..6d7c580 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -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. diff --git a/lustre/include/lustre_log.h b/lustre/include/lustre_log.h index 9f6725f..e32a840 100644 --- a/lustre/include/lustre_log.h +++ b/lustre/include/lustre_log.h @@ -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); } diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c index b1e80ec..c62dd11 100644 --- a/lustre/mds/mds_fs.c +++ b/lustre/mds/mds_fs.c @@ -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); diff --git a/lustre/obdclass/llog_obd.c b/lustre/obdclass/llog_obd.c index f8c875b..f2cd312 100644 --- a/lustre/obdclass/llog_obd.c +++ b/lustre/obdclass/llog_obd.c @@ -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); diff --git a/lustre/quota/quota_context.c b/lustre/quota/quota_context.c index 595f5e4..65c727e 100644 --- a/lustre/quota/quota_context.c +++ b/lustre/quota/quota_context.c @@ -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); diff --git a/lustre/quota/quota_ctl.c b/lustre/quota/quota_ctl.c index c056048..4f50f7d 100644 --- a/lustre/quota/quota_ctl.c +++ b/lustre/quota/quota_ctl.c @@ -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); } diff --git a/lustre/quota/quota_master.c b/lustre/quota/quota_master.c index 216f2c2..f007b68 100644 --- a/lustre/quota/quota_master.c +++ b/lustre/quota/quota_master.c @@ -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) diff --git a/lustre/tests/sanity-quota.sh b/lustre/tests/sanity-quota.sh index 09184c9..73241fe 100644 --- a/lustre/tests/sanity-quota.sh +++ b/lustre/tests/sanity-quota.sh @@ -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() { -- 1.8.3.1