From: shadow Date: Thu, 21 Feb 2008 12:04:12 +0000 (+0000) Subject: Correctly check stale fid and not start epoch if ost not support SOM X-Git-Tag: v1_7_0_51~223 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=c2d30a619aff0e4ccd3ddef6e7626b91a7b1318a;p=fs%2Flustre-release.git Correctly check stale fid and not start epoch if ost not support SOM b=13537 i=umka i=vitaly --- diff --git a/lustre/ChangeLog b/lustre/ChangeLog index ab46c21..14fa8b3 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -12,6 +12,16 @@ tbd Sun Microsystems, Inc. * RHEL 4 and RHEL 5/SLES 10 clients behaves differently on 'cd' to a removed cwd "./" (refer to Bugzilla 14399). +Severity : normal +Frequency : occasional +Bugzilla : 13537 +Description: Correctly check stale fid, not start epoch if ost not support SOM +Details : open with flag O_CREATE need set old fid in op_fid3 because op_fid2 + overwrited with new generated fid, but mds can anwer with one of these + two fids and both is not stale. setattr incorectly start epoch and + assume will be called done_writeting, but without SOM done_writing + never called. + Severity : major Frequency : rare, depends on device drivers and load Bugzilla : 14529 diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index fe890ca..7081ba5 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -890,6 +890,10 @@ dont_check_exports: export->exp_lock_replay_needed = 1; spin_unlock(&export->exp_lock); if ((lustre_msg_get_op_flags(req->rq_reqmsg) & MSG_CONNECT_TRANSNO) + && (data->ocd_transno == 0)) + CWARN("Connect with zero transno!\n"); + + if ((lustre_msg_get_op_flags(req->rq_reqmsg) & MSG_CONNECT_TRANSNO) && data->ocd_transno < target->obd_next_recovery_transno) target->obd_next_recovery_transno = data->ocd_transno; target->obd_connected_clients++; diff --git a/lustre/llite/dcache.c b/lustre/llite/dcache.c index 42bce6f..3ef3a35 100644 --- a/lustre/llite/dcache.c +++ b/lustre/llite/dcache.c @@ -156,8 +156,8 @@ void ll_intent_release(struct lookup_intent *it) it->it_op_release = 0; #endif /* We are still holding extra reference on a request, need to free it */ - if (it_disposition(it, DISP_ENQ_OPEN_REF)) /* open req for llfile_open*/ - ptlrpc_req_finished(it->d.lustre.it_data); + if (it_disposition(it, DISP_ENQ_OPEN_REF)) + ptlrpc_req_finished(it->d.lustre.it_data); /* ll_file_open */ if (it_disposition(it, DISP_ENQ_CREATE_REF)) /* create rec */ ptlrpc_req_finished(it->d.lustre.it_data); if (it_disposition(it, DISP_ENQ_COMPLETE)) /* saved req from revalidate @@ -359,7 +359,6 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags, rc = ll_have_md_lock(de->d_parent->d_inode, MDS_INODELOCK_UPDATE); - RETURN(rc); } @@ -378,18 +377,11 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags, OBD_FAIL_TIMEOUT(OBD_FAIL_MDC_REVALIDATE_PAUSE, 5); ll_frob_intent(&it, &lookup_it); LASSERT(it); - parent = de->d_parent->d_inode; - if (it->it_op & IT_CREAT) { - op_data = ll_prep_md_op_data(NULL, parent, NULL, - de->d_name.name, de->d_name.len, - 0, LUSTRE_OPC_CREATE, NULL); - } else { - op_data = ll_prep_md_op_data(NULL, parent, de->d_inode, - de->d_name.name, de->d_name.len, - 0, LUSTRE_OPC_ANY, NULL); - } + op_data = ll_prep_md_op_data(NULL, parent, de->d_inode, + de->d_name.name, de->d_name.len, + 0, LUSTRE_OPC_ANY, NULL); if (IS_ERR(op_data)) RETURN(PTR_ERR(op_data)); @@ -398,7 +390,7 @@ int ll_revalidate_it(struct dentry *de, int lookup_flags, struct ll_inode_info *lli = ll_i2info(inode); struct obd_client_handle **och_p; __u64 *och_usecount; - + /* * We used to check for MDS_INODELOCK_OPEN here, but in fact * just having LOOKUP lock is enough to justify inode is the @@ -558,7 +550,7 @@ do_lookup: struct mdt_body *mdt_body; struct lu_fid fid = {.f_seq = 0, .f_oid = 0, .f_ver = 0}; mdt_body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY); - + if (de->d_inode) fid = *ll_inode2fid(de->d_inode); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 11b4805..fc4ed66 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -1313,13 +1313,14 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr) OBD_ALLOC_PTR(op_data); if (op_data == NULL) RETURN(-ENOMEM); - + memcpy(&op_data->op_attr, attr, sizeof(*attr)); /* Open epoch for truncate. */ - if (ia_valid & ATTR_SIZE) + if ((ll_i2mdexp(inode)->exp_connect_flags & OBD_CONNECT_SOM) && + (ia_valid & ATTR_SIZE)) op_data->op_flags = MF_EPOCH_OPEN; - + rc = ll_md_setattr(inode, op_data, &mod); if (rc) GOTO(out, rc); diff --git a/lustre/lmv/lmv_intent.c b/lustre/lmv/lmv_intent.c index 6b0c365..f87d2f5 100644 --- a/lustre/lmv/lmv_intent.c +++ b/lustre/lmv/lmv_intent.c @@ -243,6 +243,8 @@ repeat: * For open with IT_CREATE and for IT_CREATE cases allocate new * fid and setup FLD for it. */ + /* save old child fid for correctly check stale data*/ + sop_data->op_fid3 = sop_data->op_fid2; rc = lmv_fid_alloc(exp, &sop_data->op_fid2, sop_data); if (rc) GOTO(out_free_sop_data, rc); diff --git a/lustre/mdc/mdc_locks.c b/lustre/mdc/mdc_locks.c index c546ef8..343b918 100644 --- a/lustre/mdc/mdc_locks.c +++ b/lustre/mdc/mdc_locks.c @@ -816,8 +816,17 @@ int mdc_intent_lock(struct obd_export *exp, struct md_op_data *op_data, it_set_disposition(it, DISP_ENQ_COMPLETE); /* Also: did we find the same inode? */ - if (!lu_fid_eq(&op_data->op_fid2, &mdt_body->fid1)) + /* sever can return one of two fids: + * op_fid2 - new allocated fid - if file is created. + * op_fid3 - existent fid - if file only open. + * op_fid3 is saved in lmv_intent_open */ + if ((!lu_fid_eq(&op_data->op_fid2, &mdt_body->fid1)) && + (!lu_fid_eq(&op_data->op_fid3, &mdt_body->fid1))) { + CDEBUG(D_DENTRY, "Found stale data "DFID"("DFID")/"DFID + "\n", PFID(&op_data->op_fid2), + PFID(&op_data->op_fid2), PFID(&mdt_body->fid1)); RETURN(-ESTALE); + } } rc = it_open_error(DISP_LOOKUP_EXECD, it); diff --git a/lustre/ptlrpc/import.c b/lustre/ptlrpc/import.c index 93800ce..5082bc5 100644 --- a/lustre/ptlrpc/import.c +++ b/lustre/ptlrpc/import.c @@ -353,12 +353,17 @@ int ptlrpc_first_transno(struct obd_import *imp, __u64 *transno) { struct ptlrpc_request *req; struct list_head *tmp; - + if (list_empty(&imp->imp_replay_list)) return 0; tmp = imp->imp_replay_list.next; req = list_entry(tmp, struct ptlrpc_request, rq_replay_list); *transno = req->rq_transno; + if (req->rq_transno == 0) { + DEBUG_REQ(D_ERROR, req, "zero transno in replay"); + LBUG(); + } + return 1; }