From: zam Date: Fri, 19 Dec 2008 12:03:11 +0000 (+0000) Subject: Branch b_release_1_8_0 X-Git-Tag: v1_7_160~58 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=6a19c1d5ce24c5dbefd6a40e3609bdd87f848156;p=fs%2Flustre-release.git Branch b_release_1_8_0 b=17688 i=oleg.drokin i=alexey.lyashkov A lockless truncate fix, to prevent excessive lock pingpong on multistipe files. --- diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 8fb9790..0f329aa 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -1171,7 +1171,7 @@ struct obd_ops { struct ptlrpc_request_set *rqset); int (*o_match)(struct obd_export *, struct lov_stripe_md *, __u32 type, ldlm_policy_data_t *, __u32 mode, int *flags, void *data, - struct lustre_handle *lockh); + struct lustre_handle *lockh, int *n_matches); int (*o_change_cbdata)(struct obd_export *, struct lov_stripe_md *, ldlm_iterator_t it, void *data); int (*o_cancel)(struct obd_export *, struct lov_stripe_md *md, diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index c07578d..b0080aa4 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -1346,7 +1346,8 @@ static inline int obd_enqueue(struct obd_export *exp, static inline int obd_match(struct obd_export *exp, struct lov_stripe_md *ea, __u32 type, ldlm_policy_data_t *policy, __u32 mode, - int *flags, void *data, struct lustre_handle *lockh) + int *flags, void *data, struct lustre_handle *lockh, + int *n_matches) { int rc; ENTRY; @@ -1355,7 +1356,7 @@ static inline int obd_match(struct obd_export *exp, struct lov_stripe_md *ea, EXP_COUNTER_INCREMENT(exp, match); rc = OBP(exp->exp_obd, match)(exp, ea, type, policy, mode, flags, data, - lockh); + lockh, n_matches); RETURN(rc); } diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c index 107cd02a..faab12a 100644 --- a/lustre/liblustre/super.c +++ b/lustre/liblustre/super.c @@ -750,7 +750,8 @@ int llu_setattr_raw(struct inode *inode, struct iattr *attr) /* check that there are no matching locks */ LASSERT(obd_match(sbi->ll_osc_exp, lsm, LDLM_EXTENT, &policy, - LCK_PW, &flags, inode, &match_lockh) <= 0); + LCK_PW, &flags, inode, &match_lockh, NULL) + <= 0); /* XXX when we fix the AST intents to pass the discard-range * XXX extent, make ast_flags always LDLM_AST_DISCARD_DATA diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index c440e86..4af1867 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1434,11 +1434,10 @@ static int ll_setattr_do_truncate(struct inode *inode, loff_t new_size) ldlm_policy_data_t policy = { .l_extent = {new_size, OBD_OBJECT_EOF } }; struct lustre_handle lockh = { 0 }; - int local_lock = 0; /* 0 - no local lock; + int local_lock = 1; /* 0 - no local lock; * 1 - lock taken by lock_extent; * 2 - by obd_match*/ int ast_flags; - int err; ENTRY; UNLOCK_INODE_MUTEX(inode); @@ -1446,24 +1445,34 @@ static int ll_setattr_do_truncate(struct inode *inode, loff_t new_size) if (sbi->ll_lockless_truncate_enable && (sbi->ll_lco.lco_flags & OBD_CONNECT_TRUNCLOCK)) { + int n_matches = 0; + ast_flags = LDLM_FL_BLOCK_GRANTED; rc = obd_match(sbi->ll_osc_exp, lsm, LDLM_EXTENT, - &policy, LCK_PW, &ast_flags, inode, &lockh); + &policy, LCK_PW, &ast_flags, inode, &lockh, + &n_matches); if (rc > 0) { local_lock = 2; rc = 0; - } else if (rc == 0) { - rc = ll_file_punch(inode, new_size, 1); + } else { + /* clear the lock handle as it not cleared + * by obd_match if no matched lock found */ + lockh.cookie = 0; + if (rc == 0 && n_matches == 0) { + local_lock = 0; + rc = ll_file_punch(inode, new_size, 1); + } } - } else { + } + if (local_lock == 1) { /* XXX when we fix the AST intents to pass the discard-range * XXX extent, make ast_flags always LDLM_AST_DISCARD_DATA * XXX here. */ ast_flags = (new_size == 0) ? LDLM_AST_DISCARD_DATA : 0; rc = ll_extent_lock(NULL, inode, lsm, LCK_PW, &policy, &lockh, ast_flags); - if (likely(rc == 0)) - local_lock = 1; + if (unlikely(rc != 0)) + local_lock = 0; } LOCK_INODE_MUTEX(inode); @@ -1484,10 +1493,11 @@ static int ll_setattr_do_truncate(struct inode *inode, loff_t new_size) } } if (local_lock) { - if (local_lock == 2) - err = obd_cancel(sbi->ll_osc_exp, lsm, LCK_PW, &lockh); - else - err = ll_extent_unlock(NULL, inode, lsm, LCK_PW, &lockh); + int err; + + err = (local_lock == 2) ? + obd_cancel(sbi->ll_osc_exp, lsm, LCK_PW, &lockh): + ll_extent_unlock(NULL, inode, lsm, LCK_PW, &lockh); if (unlikely(err != 0)){ CERROR("extent unlock failed: err=%d," " unlock method =%d\n", err, local_lock); diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 343084c..26522ae 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -2143,7 +2143,8 @@ out: static int lov_match(struct obd_export *exp, struct lov_stripe_md *lsm, __u32 type, ldlm_policy_data_t *policy, __u32 mode, - int *flags, void *data, struct lustre_handle *lockh) + int *flags, void *data, struct lustre_handle *lockh, + int *n_matches) { struct lov_request_set *set; struct obd_info oinfo; @@ -2176,7 +2177,8 @@ static int lov_match(struct obd_export *exp, struct lov_stripe_md *lsm, rc = obd_match(lov->lov_tgts[req->rq_idx]->ltd_exp, req->rq_oi.oi_md, type, &sub_policy, - mode, &lov_flags, data, lov_lockhp); + mode, &lov_flags, data, lov_lockhp, + n_matches); rc = lov_update_match_set(set, req, rc); if (rc <= 0) break; diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 76123f4..2cf4879 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -3222,7 +3222,8 @@ static int osc_enqueue(struct obd_export *exp, struct obd_info *oinfo, static int osc_match(struct obd_export *exp, struct lov_stripe_md *lsm, __u32 type, ldlm_policy_data_t *policy, __u32 mode, - int *flags, void *data, struct lustre_handle *lockh) + int *flags, void *data, struct lustre_handle *lockh, + int *n_matches) { struct ldlm_res_id res_id; struct obd_device *obd = exp->exp_obd; @@ -3254,7 +3255,8 @@ static int osc_match(struct obd_export *exp, struct lov_stripe_md *lsm, ldlm_lock_addref(lockh, LCK_PR); ldlm_lock_decref(lockh, LCK_PW); } - RETURN(rc); + if (n_matches != NULL) + (*n_matches)++; } RETURN(rc); diff --git a/lustre/tests/sanityN.sh b/lustre/tests/sanityN.sh index f8844e6..8243a5b 100644 --- a/lustre/tests/sanityN.sh +++ b/lustre/tests/sanityN.sh @@ -616,10 +616,12 @@ enable_lockless_truncate() { test_32a() { # bug 11270 local p="$TMP/sanityN-$TESTNAME.parameters" save_lustre_params $HOSTNAME llite.*.lockless_truncate > $p + rm -f $DIR1/$tfile cancel_lru_locks osc - clear_llite_stats enable_lockless_truncate 1 + lfs setstripe -c -1 -s 1m $DIR1/$tfile dd if=/dev/zero of=$DIR1/$tfile count=10 bs=1M > /dev/null 2>&1 + clear_llite_stats log "checking cached lockless truncate" $TRUNCATE $DIR1/$tfile 8000000