From: alex Date: Thu, 22 Sep 2005 19:09:45 +0000 (+0000) Subject: b=7148 X-Git-Tag: v1_7_100~613 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=02be224ce61aa34c95d5c6323027de99d4485e6b b=7148 r=alex (original patch by don milos) - revalide i_size/i_blocks along with LOV EA in case of OSS removal --- diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 02b8d22..65a3d0b 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -3702,6 +3702,7 @@ static int mds_setup(struct obd_device *obd, obd_count len, void *buf) obd->obd_replayable = 1; mds->mds_crypto_type = NO_CRYPTO; + mds->mds_capa_stat = 1; rc = mds_postsetup(obd); if (rc) diff --git a/lustre/mds/mds_internal.h b/lustre/mds/mds_internal.h index cb979af..25fad02 100644 --- a/lustre/mds/mds_internal.h +++ b/lustre/mds/mds_internal.h @@ -178,7 +178,7 @@ int mds_notify(struct obd_device *obd, struct obd_device *watched, int mds_dt_update_config(struct obd_device *obd, int transno); int mds_convert_lov_ea(struct obd_device *obd, struct inode *inode, struct lov_mds_md *lmm, int lmm_size); -int mds_revalidate_lov_ea(struct obd_device *obd, struct inode *inode, +int mds_revalidate_lov_ea(struct obd_device *obd, struct dentry *dentry, struct lustre_msg *msg, int offset); void mds_dt_update_objids(struct obd_device *obd, obd_id *ids); void mds_dt_save_objids(struct obd_device *obd, obd_id *ids); @@ -202,7 +202,8 @@ int mds_done_writing(struct ptlrpc_request *req, int offset); struct mds_file_data *mds_handle2mfd(struct lustre_handle *handle); void mds_mfd_put(struct mds_file_data *mfd); int mds_validate_size(struct obd_device *obd, struct inode *inode, - struct mds_body *body, struct iattr *iattr); + struct mds_body *body, struct lov_stripe_md *lsm, + struct iattr *iattr); int accmode(int flags); /* mds/mds_fs.c */ diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c index 6d78907..ddc5958 100644 --- a/lustre/mds/mds_lov.c +++ b/lustre/mds/mds_lov.c @@ -928,22 +928,27 @@ conv_end: } /* Must be called with i_sem held */ -int mds_revalidate_lov_ea(struct obd_device *obd, struct inode *inode, +int mds_revalidate_lov_ea(struct obd_device *obd, struct dentry *dentry, struct lustre_msg *msg, int offset) { struct mds_obd *mds = &obd->u.mds; struct obd_export *dt_exp = mds->mds_dt_exp; + struct inode *inode = dentry->d_inode; struct lov_mds_md *lmm= NULL; struct lov_stripe_md *lsm = NULL; struct obdo *oa = NULL; struct obd_trans_info oti = {0}; + struct iattr iattr = { 0 }; obd_valid valid = 0; + char idname[LL_ID_NAMELEN]; int lmm_size = 0, lsm_size = 0, err, rc; void *handle; ENTRY; LASSERT(down_trylock(&inode->i_sem) != 0); + ll_id2str(idname, inode->i_ino, inode->i_generation); + /* XXX - add way to know if EA is already up to date & return * without doing anything. Easy to do since we get notified of * LOV updates. */ @@ -995,6 +1000,10 @@ int mds_revalidate_lov_ea(struct obd_device *obd, struct inode *inode, GOTO(out_oa, rc); lmm_size = rc; + DOWN_WRITE_I_ALLOC_SEM(inode); + mds_inode_set_attrs_old(inode); + UP_WRITE_I_ALLOC_SEM(inode); + handle = fsfilt_start(obd, inode, FSFILT_OP_SETATTR, NULL); if (IS_ERR(handle)) { rc = PTR_ERR(handle); @@ -1002,10 +1011,23 @@ int mds_revalidate_lov_ea(struct obd_device *obd, struct inode *inode, } rc = fsfilt_set_md(obd, inode, handle, lmm, lmm_size, EA_LOV); + if (rc) { + CERROR("error in fsfilt_set_md(%s): rc %d\n", idname, rc); + GOTO(commit, rc); + } + + /* the EA has changed - let's update i_size/i_blocks */ + /* NOTE: that we're calling mds_validate_size() with the i_sem held. */ + mds_validate_size(obd, inode, NULL, lsm, &iattr); + if (iattr.ia_valid != 0) { + rc = fsfilt_setattr(obd, dentry, handle, &iattr, 0); + if (rc) + CERROR("error in setattr(%s): rc %d\n", idname, rc); + } +commit: err = fsfilt_commit(obd, inode->i_sb, inode, handle, 0); if (!rc) rc = err; - EXIT; out_oa: obdo_free(oa); diff --git a/lustre/mds/mds_open.c b/lustre/mds/mds_open.c index 4790488..52aef76 100644 --- a/lustre/mds/mds_open.c +++ b/lustre/mds/mds_open.c @@ -763,8 +763,7 @@ static int mds_finish_open(struct ptlrpc_request *req, struct dentry *dchild, if (S_ISREG(dchild->d_inode->i_mode) && (body->valid & OBD_MD_FLEASIZE)) { - rc = mds_revalidate_lov_ea(obd, dchild->d_inode, - req->rq_repmsg, 2); + rc = mds_revalidate_lov_ea(obd,dchild,req->rq_repmsg,2); if (!rc) rc = mds_pack_md(obd, req->rq_repmsg, 2, body, dchild->d_inode, 0, 0); @@ -1652,7 +1651,7 @@ int mds_mfd_close(struct ptlrpc_request *req, int offset, goto out; /* Don't bother updating attrs on unlinked inode */ } else if ((mfd->mfd_mode & FMODE_WRITE) && rc == 0) { /* last writer closed file - let's update i_size/i_blocks */ - mds_validate_size(obd, inode, request_body, &iattr); + mds_validate_size(obd, inode, request_body, NULL, &iattr); } #if 0 @@ -1782,12 +1781,12 @@ __u64 lov_merge_blocks(struct lov_stripe_md *lsm); __u64 lov_merge_mtime(struct lov_stripe_md *lsm, __u64 current_time); int mds_validate_size(struct obd_device *obd, struct inode *inode, - struct mds_body *body, struct iattr *iattr) + struct mds_body *body, struct lov_stripe_md *lsm, + struct iattr *iattr) { ldlm_policy_data_t policy = { .l_extent = { 0, OBD_OBJECT_EOF } }; struct lustre_handle lockh = { 0 }; - struct lov_stripe_md *lsm = NULL; - int rc, len, flags; + int rc, len = 0, flags; void *lmm = NULL; ENTRY; @@ -1810,6 +1809,9 @@ int mds_validate_size(struct obd_device *obd, struct inode *inode, * 3: the file doesn't look like to be disappeared * conclusion: we're gonna fetch them from OSSes */ + if (lsm) + goto have_lsm; + down(&inode->i_sem); len = fsfilt_get_md(obd, inode, NULL, 0, EA_LOV); up(&inode->i_sem); @@ -1842,7 +1844,9 @@ int mds_validate_size(struct obd_device *obd, struct inode *inode, CERROR("error getting inode %lu MD: %d\n", inode->i_ino, rc); GOTO(cleanup, rc); } - + + have_lsm: + CDEBUG(D_DLMTRACE, "Glimpsing inode %lu\n", inode->i_ino); flags = LDLM_FL_HAS_INTENT; @@ -1860,8 +1864,11 @@ int mds_validate_size(struct obd_device *obd, struct inode *inode, GOTO(cleanup, rc); } - CDEBUG(D_INODE, "LOV reports "LPD64"/%lu for "DLID4" [%s%s%s]\n", - inode->i_size, inode->i_blocks, OLID4(&body->id1), + if (body) + CDEBUG(D_INODE, ""DLID4"\n", OLID4(&body->id1)); + + CDEBUG(D_INODE, "LOV reports "LPD64"/%lu [%s%s%s]\n", + inode->i_size, inode->i_blocks, atomic_read(&inode->i_writecount) > 1 ? "U" : "", mds_inode_has_old_attrs(inode) ? "D" : "", mds_inode_is_orphan(inode) ? "O" : ""); @@ -1880,10 +1887,11 @@ int mds_validate_size(struct obd_device *obd, struct inode *inode, obd_cancel(obd->u.mds.mds_dt_exp, lsm, LCK_PR, &lockh); cleanup: - if (lsm != NULL) - obd_free_memmd(obd->u.mds.mds_dt_exp, &lsm); - if (lmm != NULL) + if (lmm != NULL) { + if (lsm != NULL) + obd_free_memmd(obd->u.mds.mds_dt_exp, &lsm); OBD_FREE(lmm, len); + } RETURN(rc); }