From bc6ff00b0cb68f011f6d07c708a31779b211bbb4 Mon Sep 17 00:00:00 2001 From: LaiSiYao Date: Wed, 30 Mar 2011 13:59:08 +0400 Subject: [PATCH] b=24437 revoke open lock for executable files if needed When a normal lustre client open write/exec a file, the open lock on that file needs to be revoked in case an NFSD lustre client still holds it. i=green@whamcloud.com i=vladimir.saveliev@oracle.com --- lustre/mds/mds_open.c | 62 +++++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index 2f845f4..8ff4860 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -997,33 +997,25 @@ int mds_lock_new_child(struct obd_device *obd, struct inode *inode, RETURN(rc); } -int noinline mds_get_open_lock(struct obd_device *obd, struct dentry *dchild, - int child_mode, struct lustre_handle *child_lockh, - struct ldlm_reply *rep) +static int noinline mds_get_open_lock(struct obd_device *obd, + struct dentry *dchild, + int child_mode, + struct lustre_handle *child_lockh) { - ldlm_policy_data_t policy = { .l_inodebits = { MDS_INODELOCK_LOOKUP | MDS_INODELOCK_OPEN } }; - struct ldlm_res_id child_res_id; - int rc = 0, lock_flags = 0; - - /* In case of replay we do not get a lock assuming that the - caller has it already */ - memset(&child_res_id, 0, sizeof(child_res_id)); - child_res_id.name[0] = dchild->d_inode->i_ino; - child_res_id.name[1] = dchild->d_inode->i_generation; - - rc = ldlm_cli_enqueue_local(obd->obd_namespace, &child_res_id, - LDLM_IBITS, &policy, child_mode, - &lock_flags, ldlm_blocking_ast, - ldlm_completion_ast, NULL, NULL, - 0, NULL, child_lockh); - if (rc != ELDLM_OK) - goto out; - - /* Let mds_intent_policy know that we have a lock to return */ - ldlm_reply_set_disposition(rep, DISP_OPEN_LOCK); - -out: - return rc; + ldlm_policy_data_t policy = { + .l_inodebits = { MDS_INODELOCK_LOOKUP | MDS_INODELOCK_OPEN } + }; + struct ldlm_res_id child_res_id = { + .name[0] = dchild->d_inode->i_ino, + .name[1] = dchild->d_inode->i_generation, + }; + int lock_flags = 0; + + return ldlm_cli_enqueue_local(obd->obd_namespace, &child_res_id, + LDLM_IBITS, &policy, child_mode, + &lock_flags, ldlm_blocking_ast, + ldlm_completion_ast, NULL, NULL, + 0, NULL, child_lockh); } int mds_open(struct mds_update_record *rec, int offset, @@ -1385,9 +1377,25 @@ found_child: } if (need_open_lock) { - rc = mds_get_open_lock(obd, dchild, child_mode, child_lockh, rep); + rc = mds_get_open_lock(obd, dchild, child_mode, child_lockh); + if (rc != ELDLM_OK) + GOTO(cleanup, rc); + /* Let mds_intent_policy know that we have a lock to return */ + ldlm_reply_set_disposition(rep, DISP_OPEN_LOCK); + } else if (!(rec->ur_flags & MDS_OPEN_LOCK) && + S_ISREG(dchild->d_inode->i_mode) && + (dchild->d_inode->i_mode & S_IXUGO) && + (rec->ur_flags & (FMODE_WRITE | MDS_FMODE_EXEC))) { + /* if this is an executable, and a non-nfsd client open write or + * execute it, revoke open lock in case other client holds a + * open lock which denies writing/executing in mds_finish_open() + * below. LU-146 + */ + rc = mds_get_open_lock(obd, dchild, child_mode, child_lockh); if (rc != ELDLM_OK) GOTO(cleanup, rc); + ldlm_lock_decref(child_lockh, child_mode); + memset(child_lockh, 0, sizeof(*child_lockh)); } if (!S_ISREG(dchild->d_inode->i_mode) && -- 1.8.3.1