From c7176318dc754deedf33fb385e47fb723a00a279 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Wed, 21 Nov 2012 10:10:42 -0800 Subject: [PATCH] LU-2304 lov: check enq flags when matching top lock cld_enq_flags must be checked when matching top lock, otherwise if a sublock is missing then it will be reenqueued with wrong enq flags. For LU-2304, a previous truncate to zero lock(with CEF_DISCARD_DATA) flags was matched by not-to-zero truncate and then wrongly reenqueued with discard flag. This caused dirty pages to be discarded on the other clients. Signed-off-by: Jinshan Xiong Change-Id: I290df2fdb9453c2fd7c8c3d3e7289e60bae9b095 Reviewed-on: http://review.whamcloud.com/4651 Tested-by: Hudson Tested-by: Maloo Reviewed-by: Bobi Jam Reviewed-by: Andreas Dilger --- lustre/include/lustre_dlm.h | 16 +++++++++++----- lustre/ldlm/ldlm_request.c | 3 ++- lustre/llite/llite_lib.c | 6 +++--- lustre/llite/vvp_io.c | 8 ++++---- lustre/lov/lov_lock.c | 5 +++++ lustre/osc/osc_lock.c | 8 ++++++-- 6 files changed, 31 insertions(+), 15 deletions(-) diff --git a/lustre/include/lustre_dlm.h b/lustre/include/lustre_dlm.h index 55a2665..3a19073 100644 --- a/lustre/include/lustre_dlm.h +++ b/lustre/include/lustre_dlm.h @@ -990,6 +990,10 @@ extern struct obd_ops ldlm_obd_ops; extern char *ldlm_lockname[]; extern char *ldlm_typename[]; extern char *ldlm_it2str(int it); + +#define LDLM_DEBUG_NOLOCK(format, a...) \ + CDEBUG(D_DLMTRACE, "### " format "\n" , ##a) + #ifdef LIBCFS_DEBUG #define ldlm_lock_debug(msgdata, mask, cdls, lock, fmt, a...) do { \ CFS_CHECK_STACK(msgdata, mask, cdls); \ @@ -1015,8 +1019,13 @@ void _ldlm_lock_debug(struct ldlm_lock *lock, #define LDLM_WARN(lock, fmt, a...) LDLM_DEBUG_LIMIT(D_WARNING, lock, fmt, ## a) #define LDLM_DEBUG(lock, fmt, a...) do { \ - LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_DLMTRACE, NULL); \ - ldlm_lock_debug(&msgdata, D_DLMTRACE, NULL, lock, "### " fmt , ##a);\ + if (likely(lock != NULL)) { \ + LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_DLMTRACE, NULL); \ + ldlm_lock_debug(&msgdata, D_DLMTRACE, NULL, lock, \ + "### " fmt , ##a); \ + } else { \ + LDLM_DEBUG_NOLOCK("no dlm lock: " fmt, ##a); \ + } \ } while (0) #else /* !LIBCFS_DEBUG */ # define LDLM_DEBUG_LIMIT(mask, lock, fmt, a...) ((void)0) @@ -1024,9 +1033,6 @@ void _ldlm_lock_debug(struct ldlm_lock *lock, # define LDLM_ERROR(lock, fmt, a...) ((void)0) #endif -#define LDLM_DEBUG_NOLOCK(format, a...) \ - CDEBUG(D_DLMTRACE, "### " format "\n" , ##a) - typedef int (*ldlm_processing_policy)(struct ldlm_lock *lock, __u64 *flags, int first_enq, ldlm_error_t *err, cfs_list_t *work_list); diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index f7fc23b..36bdc5a2 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -840,7 +840,8 @@ int ldlm_cli_enqueue(struct obd_export *exp, struct ptlrpc_request **reqp, if (einfo->ei_type == LDLM_EXTENT) lock->l_req_extent = policy->l_extent; - LDLM_DEBUG(lock, "client-side enqueue START"); + LDLM_DEBUG(lock, "client-side enqueue START, flags %llx\n", + *flags); } lock->l_conn_export = exp; diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index b25c913..d805a0d 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1410,9 +1410,9 @@ int ll_setattr_raw(struct dentry *dentry, struct iattr *attr) int rc = 0, rc1 = 0; ENTRY; - CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu (%p) to %llu, valid %x\n", - inode->i_ino, - inode,i_size_read(inode), + CDEBUG(D_VFSTRACE, "%s: setattr inode %p/fid:"DFID" from %llu to %llu, " + "valid %x\n", ll_get_fsname(inode->i_sb, NULL, 0), inode, + PFID(&lli->lli_fid), i_size_read(inode), attr->ia_size, attr->ia_valid); if (ia_valid & ATTR_SIZE) { diff --git a/lustre/llite/vvp_io.c b/lustre/llite/vvp_io.c index f6f2271..ce492f7 100644 --- a/lustre/llite/vvp_io.c +++ b/lustre/llite/vvp_io.c @@ -315,10 +315,10 @@ static int vvp_io_setattr_iter_init(const struct lu_env *env, static int vvp_io_setattr_lock(const struct lu_env *env, const struct cl_io_slice *ios) { - struct ccc_io *cio = ccc_env_io(env); - struct cl_io *io = ios->cis_io; - size_t new_size; - __u32 enqflags = 0; + struct ccc_io *cio = ccc_env_io(env); + struct cl_io *io = ios->cis_io; + __u64 new_size; + __u32 enqflags = 0; if (cl_io_is_trunc(io)) { new_size = io->u.ci_setattr.sa_attr.lvb_size; diff --git a/lustre/lov/lov_lock.c b/lustre/lov/lov_lock.c index 2424581..1faf299 100644 --- a/lustre/lov/lov_lock.c +++ b/lustre/lov/lov_lock.c @@ -1007,6 +1007,11 @@ static int lov_lock_fits_into(const struct lu_env *env, ENTRY; + /* for top lock, it's necessary to match enq flags otherwise it will + * run into problem if a sublock is missing and reenqueue. */ + if (need->cld_enq_flags != lov->lls_orig.cld_enq_flags) + return 0; + if (need->cld_mode == CLM_GROUP) /* * always allow to match group lock. diff --git a/lustre/osc/osc_lock.c b/lustre/osc/osc_lock.c index 3a518c4..b4b5e5a 100644 --- a/lustre/osc/osc_lock.c +++ b/lustre/osc/osc_lock.c @@ -1329,8 +1329,9 @@ static int osc_lock_flush(struct osc_lock *ols, int discard) result = osc_cache_writeback_range(env, obj, descr->cld_start, descr->cld_end, 1, discard); - CDEBUG(D_DLMTRACE, "write out %d pages for lock %p.\n", - result, lock); + LDLM_DEBUG(ols->ols_lock, + "lock %p: %d pages were %s.\n", lock, result, + discard ? "discarded" : "written"); if (result > 0) result = 0; } @@ -1715,6 +1716,9 @@ int osc_lock_init(const struct lu_env *env, if (clk->ols_locklessable && !(enqflags & CEF_DISCARD_DATA)) clk->ols_flags |= LDLM_FL_DENY_ON_CONTENTION; + LDLM_DEBUG_NOLOCK("lock %p, osc lock %p, flags %llx\n", + lock, clk, clk->ols_flags); + result = 0; } else result = -ENOMEM; -- 1.8.3.1