diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 32a55de31bbccac3d913634491a2eeffcfdf500d..3ae82e2d85018c77e7e01c2176d928df24c83b6f 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -42,6 +42,13 @@ tbd Sun Microsystems, Inc. * A new Lustre ADIO driver is available for: MPICH2-1.0.7 +Severity : normal +Frequency : Create a symlink file with a very long name +Bugzilla : 16578 +Description: ldlm_cancel_pack()) ASSERTION(max >= dlm->lock_count + count) +Details : If there is no extra space in the request for early cancels, + ldlm_req_handles_avail() returns 0 instead of a negative value. + Severity : major Frequency : rare Bugzilla : 16492 @@ -186,8 +193,8 @@ Severity : normal Bugzilla : 17197 Description: (rw.c:1323:ll_read_ahead_pages()) ASSERTION(page_idx > ria->ria_stoff) failed Details : Once the unmatched stride IO mode is detected, shrink the stride-ahead - window to 0. If it does hit cache miss, and read-pattern is still - stride-io mode, does not reset the stride window, but also does not + window to 0. If it does hit cache miss, and read-pattern is still + stride-io mode, does not reset the stride window, but also does not increase the stride window length in this case. -------------------------------------------------------------------------- diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index d25b55d0e36e322ea76d3d967400fe49be969acb..1865867761ccabefc7df53c9920af3d0a5133b33 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -536,7 +536,10 @@ static inline int ldlm_req_handles_avail(struct obd_export *exp, avail -= lustre_msg_size(class_exp2cliimp(exp)->imp_msg_magic, bufcount, size); - avail /= sizeof(struct lustre_handle); + if (likely(avail >= 0)) + avail /= (int)sizeof(struct lustre_handle); + else + avail = 0; avail += LDLM_LOCKREQ_HANDLES - off; return avail; @@ -570,12 +573,12 @@ struct ptlrpc_request *ldlm_prep_elc_req(struct obd_export *exp, int version, LASSERT(bufoff < bufcount); avail = ldlm_req_handles_avail(exp, size, bufcount, canceloff); - flags = ns_connect_lru_resize(ns) ? + flags = ns_connect_lru_resize(ns) ? LDLM_CANCEL_LRUR : LDLM_CANCEL_AGED; to_free = !ns_connect_lru_resize(ns) && opc == LDLM_ENQUEUE ? 1 : 0; - /* Cancel lru locks here _only_ if the server supports + /* Cancel lru locks here _only_ if the server supports * EARLY_CANCEL. Otherwise we have to send extra CANCEL * rpc, what will make us slower. */ if (avail > count) @@ -1027,28 +1030,28 @@ int ldlm_cli_update_pool(struct ptlrpc_request *req) __u64 old_slv, new_slv; __u32 new_limit; ENTRY; - - if (unlikely(!req->rq_import || !req->rq_import->imp_obd || + + if (unlikely(!req->rq_import || !req->rq_import->imp_obd || !imp_connect_lru_resize(req->rq_import))) { - /* - * Do nothing for corner cases. + /* + * Do nothing for corner cases. */ RETURN(0); } - /* - * In some cases RPC may contain slv and limit zeroed out. This is + /* + * In some cases RPC may contain slv and limit zeroed out. This is * the case when server does not support lru resize feature. This is * also possible in some recovery cases when server side reqs have no - * ref to obd export and thus access to server side namespace is no - * possible. + * ref to obd export and thus access to server side namespace is no + * possible. */ - if (lustre_msg_get_slv(req->rq_repmsg) == 0 || + if (lustre_msg_get_slv(req->rq_repmsg) == 0 || lustre_msg_get_limit(req->rq_repmsg) == 0) { DEBUG_REQ(D_HA, req, "Zero SLV or Limit found " - "(SLV: "LPU64", Limit: %u)", - lustre_msg_get_slv(req->rq_repmsg), + "(SLV: "LPU64", Limit: %u)", + lustre_msg_get_slv(req->rq_repmsg), lustre_msg_get_limit(req->rq_repmsg)); RETURN(0); } @@ -1057,12 +1060,12 @@ int ldlm_cli_update_pool(struct ptlrpc_request *req) new_slv = lustre_msg_get_slv(req->rq_repmsg); obd = req->rq_import->imp_obd; - /* - * Set new SLV and Limit to obd fields to make accessible for pool + /* + * Set new SLV and Limit to obd fields to make accessible for pool * thread. We do not access obd_namespace and pool directly here * as there is no reliable way to make sure that they are still * alive in cleanup time. Evil races are possible which may cause - * oops in that time. + * oops in that time. */ write_lock(&obd->obd_pool_lock); old_slv = obd->obd_pool_slv; @@ -1088,7 +1091,7 @@ int ldlm_cli_cancel(struct lustre_handle *lockh) LDLM_DEBUG_NOLOCK("lock is already being destroyed\n"); RETURN(0); } - + rc = ldlm_cli_cancel_local(lock); if (rc < 0 || rc == LDLM_FL_LOCAL_ONLY) { LDLM_LOCK_PUT(lock); @@ -1156,17 +1159,17 @@ static int ldlm_cancel_list(struct list_head *cancels, int count, int flags) RETURN(count); } -/* Return 1 to stop lru processing and keep current lock cached. Return zero +/* Return 1 to stop lru processing and keep current lock cached. Return zero * otherwise. */ static ldlm_policy_res_t ldlm_cancel_shrink_policy(struct ldlm_namespace *ns, struct ldlm_lock *lock, - int unused, int added, + int unused, int added, int count) { int lock_cost; __u64 page_nr; - /* Stop lru processing when we reached passed @count or checked all + /* Stop lru processing when we reached passed @count or checked all * locks in lru. */ if (count && added >= count) return LDLM_POLICY_KEEP_LOCK; @@ -1183,7 +1186,7 @@ static ldlm_policy_res_t ldlm_cancel_shrink_policy(struct ldlm_namespace *ns, #ifdef __KERNEL__ /* XXX: In fact this is evil hack, we can't access inode * here. For doing it right we need somehow to have number - * of covered by lock. This should be fixed later when 10718 + * of covered by lock. This should be fixed later when 10718 * is landed. */ if (lock->l_ast_data != NULL) { struct inode *inode = lock->l_ast_data; @@ -1200,15 +1203,15 @@ static ldlm_policy_res_t ldlm_cancel_shrink_policy(struct ldlm_namespace *ns, /* Keep all expensive locks in lru for the memory pressure time * cancel policy. They anyways may be canceled by lru resize * pplicy if they have not small enough CLV. */ - return lock_cost > ns->ns_shrink_thumb ? + return lock_cost > ns->ns_shrink_thumb ? LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK; } -/* Return 1 to stop lru processing and keep current lock cached. Return zero +/* Return 1 to stop lru processing and keep current lock cached. Return zero * otherwise. */ static ldlm_policy_res_t ldlm_cancel_lrur_policy(struct ldlm_namespace *ns, - struct ldlm_lock *lock, - int unused, int added, + struct ldlm_lock *lock, + int unused, int added, int count) { cfs_time_t cur = cfs_time_current(); @@ -1216,7 +1219,7 @@ static ldlm_policy_res_t ldlm_cancel_lrur_policy(struct ldlm_namespace *ns, __u64 slv, lvf, lv; cfs_time_t la; - /* Stop lru processing when we reached passed @count or checked all + /* Stop lru processing when we reached passed @count or checked all * locks in lru. */ if (count && added >= count) return LDLM_POLICY_KEEP_LOCK; @@ -1224,63 +1227,63 @@ static ldlm_policy_res_t ldlm_cancel_lrur_policy(struct ldlm_namespace *ns, slv = ldlm_pool_get_slv(pl); lvf = ldlm_pool_get_lvf(pl); - la = cfs_duration_sec(cfs_time_sub(cur, + la = cfs_duration_sec(cfs_time_sub(cur, lock->l_last_used)); - /* Stop when slv is not yet come from server or + /* Stop when slv is not yet come from server or * lv is smaller than it is. */ lv = lvf * la * unused; /* Inform pool about current CLV to see it via proc. */ ldlm_pool_set_clv(pl, lv); - return (slv == 1 || lv < slv) ? + return (slv == 1 || lv < slv) ? LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK; } -/* Return 1 to stop lru processing and keep current lock cached. Return zero +/* Return 1 to stop lru processing and keep current lock cached. Return zero * otherwise. */ static ldlm_policy_res_t ldlm_cancel_passed_policy(struct ldlm_namespace *ns, - struct ldlm_lock *lock, + struct ldlm_lock *lock, int unused, int added, int count) { - /* Stop lru processing when we reached passed @count or checked all + /* Stop lru processing when we reached passed @count or checked all * locks in lru. */ - return (added >= count) ? + return (added >= count) ? LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK; } -/* Return 1 to stop lru processing and keep current lock cached. Return zero +/* Return 1 to stop lru processing and keep current lock cached. Return zero * otherwise. */ static ldlm_policy_res_t ldlm_cancel_aged_policy(struct ldlm_namespace *ns, - struct ldlm_lock *lock, + struct ldlm_lock *lock, int unused, int added, int count) { - /* Stop lru processing if young lock is found and we reached passed + /* Stop lru processing if young lock is found and we reached passed * @count. */ - return ((added >= count) && + return ((added >= count) && cfs_time_before(cfs_time_current(), cfs_time_add(lock->l_last_used, - ns->ns_max_age))) ? + ns->ns_max_age))) ? LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK; } -/* Return 1 to stop lru processing and keep current lock cached. Return zero +/* Return 1 to stop lru processing and keep current lock cached. Return zero * otherwise. */ static ldlm_policy_res_t ldlm_cancel_default_policy(struct ldlm_namespace *ns, - struct ldlm_lock *lock, + struct ldlm_lock *lock, int unused, int added, int count) { - /* Stop lru processing when we reached passed @count or checked all + /* Stop lru processing when we reached passed @count or checked all * locks in lru. */ - return (added >= count) ? + return (added >= count) ? LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK; } -typedef ldlm_policy_res_t (*ldlm_cancel_lru_policy_t)(struct ldlm_namespace *, - struct ldlm_lock *, int, +typedef ldlm_policy_res_t (*ldlm_cancel_lru_policy_t)(struct ldlm_namespace *, + struct ldlm_lock *, int, int, int); static ldlm_cancel_lru_policy_t @@ -1297,10 +1300,10 @@ ldlm_cancel_lru_policy(struct ldlm_namespace *ns, int flags) if (flags & LDLM_CANCEL_AGED) return ldlm_cancel_aged_policy; } - + return ldlm_cancel_default_policy; } - + /* - Free space in lru for @count new locks, * redundant unused locks are canceled locally; * - also cancel locally unused aged locks; @@ -1343,7 +1346,7 @@ int ldlm_cancel_lru_local(struct ldlm_namespace *ns, struct list_head *cancels, pf = ldlm_cancel_lru_policy(ns, flags); LASSERT(pf != NULL); - + while (!list_empty(&ns->ns_unused_list)) { /* For any flags, stop scanning if @max is reached. */ if (max && added >= max) @@ -1370,11 +1373,11 @@ int ldlm_cancel_lru_local(struct ldlm_namespace *ns, struct list_head *cancels, * we find a lock that should stay in the cache. * We should take into account lock age anyway * as new lock even if it is small of weight is - * valuable resource. + * valuable resource. * * That is, for shrinker policy we drop only * old locks, but additionally chose them by - * their weight. Big extent locks will stay in + * their weight. Big extent locks will stay in * the cache. */ if (pf(ns, lock, unused, added, count) == LDLM_POLICY_KEEP_LOCK) break; @@ -1400,8 +1403,8 @@ int ldlm_cancel_lru_local(struct ldlm_namespace *ns, struct list_head *cancels, /* If we have chosen to cancel this lock voluntarily, we * better send cancel notification to server, so that it - * frees appropriate state. This might lead to a race - * where while we are doing cancel here, server is also + * frees appropriate state. This might lead to a race + * where while we are doing cancel here, server is also * silently cancelling this lock. */ lock->l_flags &= ~LDLM_FL_CANCEL_ON_BLOCK; @@ -1430,7 +1433,7 @@ int ldlm_cancel_lru_local(struct ldlm_namespace *ns, struct list_head *cancels, RETURN(ldlm_cancel_list(cancels, added, cancel_flags)); } -/* Returns number of locks which could be canceled next time when +/* Returns number of locks which could be canceled next time when * ldlm_cancel_lru() is called. Used from locks pool shrinker. */ int ldlm_cancel_lru_estimate(struct ldlm_namespace *ns, int count, int max, int flags) @@ -1451,10 +1454,10 @@ int ldlm_cancel_lru_estimate(struct ldlm_namespace *ns, break; /* Somebody is already doing CANCEL or there is a - * blocking request will send cancel. Let's not count + * blocking request will send cancel. Let's not count * this lock. */ if ((lock->l_flags & LDLM_FL_CANCELING) || - (lock->l_flags & LDLM_FL_BL_AST)) + (lock->l_flags & LDLM_FL_BL_AST)) continue; /* Pass the lock through the policy filter and see if it @@ -1473,7 +1476,7 @@ int ldlm_cancel_lru_estimate(struct ldlm_namespace *ns, * in a thread and this function will return after the thread has been * asked to call the callback. when called with LDLM_SYNC the blocking * callback will be performed in this function. */ -int ldlm_cancel_lru(struct ldlm_namespace *ns, int nr, ldlm_sync_t sync, +int ldlm_cancel_lru(struct ldlm_namespace *ns, int nr, ldlm_sync_t sync, int flags) { CFS_LIST_HEAD(cancels); @@ -1528,7 +1531,7 @@ int ldlm_cancel_resource_local(struct ldlm_resource *res, /* If somebody is already doing CANCEL, or blocking ast came, * skip this lock. */ - if (lock->l_flags & LDLM_FL_BL_AST || + if (lock->l_flags & LDLM_FL_BL_AST || lock->l_flags & LDLM_FL_CANCELING) continue; diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 59cb08e0673655a7d6f4fea0062f9a28506eadbe..32fcfe17275c3833d06c10b1cf4a33edb98101cf 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -444,6 +444,16 @@ test_17e() { } run_test 17e "symlinks: create recursive symlink (should return error) ====" +test_17g() { + mkdir -p $DIR/$tdir + for ((i = 0; i < 511; ++i)); do + LONGSYMLINK="${LONGSYMLINK}01234567" + done + ln -s $LONGSYMLINK $DIR/$tdir/$tfile + ls -l $DIR/$tdir +} +run_test 17g "symlinks: really long symlink name ===============================" + test_18() { touch $DIR/f ls $DIR || error @@ -937,7 +947,7 @@ exhaust_all_precreations() { test_27n() { [ "$OSTCOUNT" -lt "2" ] && skip "too few OSTs" && return remote_mds_nodsh && skip "remote MDS with nodsh" && return - remote_ost_nodsh && skip "remote OST with nodsh" && return + remote_ost_nodsh && skip "remote OST with nodsh" && return reset_enospc rm -f $DIR/d27/f27n @@ -952,7 +962,7 @@ run_test 27n "create file with some full OSTs ==================" test_27o() { [ "$OSTCOUNT" -lt "2" ] && skip "too few OSTs" && return remote_mds_nodsh && skip "remote MDS with nodsh" && return - remote_ost_nodsh && skip "remote OST with nodsh" && return + remote_ost_nodsh && skip "remote OST with nodsh" && return reset_enospc rm -f $DIR/d27/f27o @@ -968,7 +978,7 @@ run_test 27o "create file with all full OSTs (should error) ====" test_27p() { [ "$OSTCOUNT" -lt "2" ] && skip "too few OSTs" && return remote_mds_nodsh && skip "remote MDS with nodsh" && return - remote_ost_nodsh && skip "remote OST with nodsh" && return + remote_ost_nodsh && skip "remote OST with nodsh" && return reset_enospc rm -f $DIR/d27/f27p @@ -988,7 +998,7 @@ run_test 27p "append to a truncated file with some full OSTs ===" test_27q() { [ "$OSTCOUNT" -lt "2" ] && skip "too few OSTs" && return remote_mds_nodsh && skip "remote MDS with nodsh" && return - remote_ost_nodsh && skip "remote OST with nodsh" && return + remote_ost_nodsh && skip "remote OST with nodsh" && return reset_enospc rm -f $DIR/d27/f27q @@ -1009,7 +1019,7 @@ run_test 27q "append to truncated file with all OSTs full (should error) ===" test_27r() { [ "$OSTCOUNT" -lt "2" ] && skip "too few OSTs" && return remote_mds_nodsh && skip "remote MDS with nodsh" && return - remote_ost_nodsh && skip "remote OST with nodsh" && return + remote_ost_nodsh && skip "remote OST with nodsh" && return reset_enospc rm -f $DIR/d27/f27r @@ -1061,7 +1071,7 @@ run_test 27u "skip object creation on OSC w/o objects ==========" test_27v() { # bug 4900 [ "$OSTCOUNT" -lt "2" ] && skip "too few OSTs" && return remote_mds_nodsh && skip "remote MDS with nodsh" && return - remote_ost_nodsh && skip "remote OST with nodsh" && return + remote_ost_nodsh && skip "remote OST with nodsh" && return exhaust_all_precreations @@ -3052,7 +3062,7 @@ test_69() { remote_ost_nodsh && skip "remote OST with nodsh" && return f="$DIR/$tfile" - $SETSTRIPE $f -c 1 -i 0 + $SETSTRIPE $f -c 1 -i 0 $DIRECTIO write ${f}.2 0 1 || error "directio write error" @@ -3615,7 +3625,7 @@ test_100() { error "local: $LPORT > 1024, remote: $RPORT" fi done - [ "$rc" = 0 ] || error "privileged port not found" ) + [ "$rc" = 0 ] || error "privileged port not found" ) } run_test 100 "check local port using privileged port ==========="