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,
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;
EXP_COUNTER_INCREMENT(exp, match);
rc = OBP(exp->exp_obd, match)(exp, ea, type, policy, mode, flags, data,
- lockh);
+ lockh, n_matches);
RETURN(rc);
}
/* 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
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);
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);
}
}
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);
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;
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;
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;
ldlm_lock_addref(lockh, LCK_PR);
ldlm_lock_decref(lockh, LCK_PW);
}
- RETURN(rc);
+ if (n_matches != NULL)
+ (*n_matches)++;
}
RETURN(rc);
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