From: Alex Zhuravlev Date: Fri, 9 Nov 2012 11:15:46 +0000 (+0400) Subject: LU-2118 mdt: fetch parent fid if requested X-Git-Tag: 2.3.57~41 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=dde765543c5a94e5762ad9eb0adeb366fdf32a92 LU-2118 mdt: fetch parent fid if requested open-by-fid replay needs this functionality to use correct parent and appropriate default striping. Signed-off-by: Alex Zhuravlev Change-Id: I8aa618f98f7a7dbbcf32f3407fa89c79a8b98d83 Reviewed-on: http://review.whamcloud.com/4503 Reviewed-by: Mike Pershin Tested-by: Hudson Tested-by: Maloo Reviewed-by: wangdi Reviewed-by: Oleg Drokin --- diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 30347c9..847d8de 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -542,19 +542,15 @@ void mdt_client_compatibility(struct mdt_thread_info *info) EXIT; } -static int mdt_big_lmm_get(const struct lu_env *env, struct mdt_object *o, - struct md_attr *ma) +static int mdt_big_xattr_get(struct mdt_thread_info *info, struct mdt_object *o, + char *name) { - struct mdt_thread_info *info; + const struct lu_env *env = info->mti_env; int rc; ENTRY; - info = lu_context_key_get(&env->le_ctx, &mdt_thread_key); - LASSERT(info != NULL); - LASSERT(ma->ma_lmm_size > 0); LASSERT(info->mti_big_lmm_used == 0); - rc = mo_xattr_get(env, mdt_object_child(o), &LU_BUF_NULL, - XATTR_NAME_LOV); + rc = mo_xattr_get(env, mdt_object_child(o), &LU_BUF_NULL, name); if (rc < 0) RETURN(rc); @@ -580,21 +576,9 @@ static int mdt_big_lmm_get(const struct lu_env *env, struct mdt_object *o, info->mti_buf.lb_buf = info->mti_big_lmm; info->mti_buf.lb_len = info->mti_big_lmmsize; - rc = mo_xattr_get(env, mdt_object_child(o), &info->mti_buf, - XATTR_NAME_LOV); - if (rc < 0) - RETURN(rc); - - info->mti_big_lmm_used = 1; - ma->ma_valid |= MA_LOV; - ma->ma_lmm = info->mti_big_lmm; - ma->ma_lmm_size = rc; + rc = mo_xattr_get(env, mdt_object_child(o), &info->mti_buf, name); - /* update mdt_max_mdsize so all clients will be aware about that */ - if (info->mti_mdt->mdt_max_mdsize < rc) - info->mti_mdt->mdt_max_mdsize = rc; - - RETURN(0); + RETURN(rc); } int mdt_attr_get_lov(struct mdt_thread_info *info, @@ -615,12 +599,70 @@ int mdt_attr_get_lov(struct mdt_thread_info *info, /* no LOV EA */ rc = 0; } else if (rc == -ERANGE) { - rc = mdt_big_lmm_get(info->mti_env, o, ma); + rc = mdt_big_xattr_get(info, o, XATTR_NAME_LOV); + if (rc > 0) { + info->mti_big_lmm_used = 1; + ma->ma_valid |= MA_LOV; + ma->ma_lmm = info->mti_big_lmm; + ma->ma_lmm_size = rc; + /* update mdt_max_mdsize so all clients + * will be aware about that */ + if (info->mti_mdt->mdt_max_mdsize < rc) + info->mti_mdt->mdt_max_mdsize = rc; + rc = 0; + } } return rc; } +int mdt_attr_get_pfid(struct mdt_thread_info *info, + struct mdt_object *o, struct lu_fid *pfid) +{ + struct lu_buf *buf = &info->mti_buf; + struct link_ea_header *leh; + struct link_ea_entry *lee; + int rc; + ENTRY; + + buf->lb_buf = info->mti_big_lmm; + buf->lb_len = info->mti_big_lmmsize; + rc = mo_xattr_get(info->mti_env, mdt_object_child(o), + buf, XATTR_NAME_LINK); + /* ignore errors, MA_PFID won't be set and it is + * up to the caller to treat this as an error */ + if (rc == -ERANGE || buf->lb_len == 0) { + rc = mdt_big_xattr_get(info, o, XATTR_NAME_LINK); + buf->lb_buf = info->mti_big_lmm; + buf->lb_len = info->mti_big_lmmsize; + } + + if (rc < 0) + RETURN(rc); + if (rc < sizeof(*leh)) { + CERROR("short LinkEA on "DFID": rc = %d\n", + PFID(mdt_object_fid(o)), rc); + RETURN(-ENODATA); + } + + leh = (struct link_ea_header *) buf->lb_buf; + lee = (struct link_ea_entry *)(leh + 1); + if (leh->leh_magic == __swab32(LINK_EA_MAGIC)) { + leh->leh_magic = LINK_EA_MAGIC; + leh->leh_reccount = __swab32(leh->leh_reccount); + leh->leh_len = __swab64(leh->leh_len); + } + if (leh->leh_magic != LINK_EA_MAGIC) + RETURN(-EINVAL); + if (leh->leh_reccount == 0) + RETURN(-ENODATA); + + memcpy(pfid, &lee->lee_parent_fid, sizeof(*pfid)); + fid_be_to_cpu(pfid, pfid); + + RETURN(0); +} + int mdt_attr_get_complex(struct mdt_thread_info *info, struct mdt_object *o, struct md_attr *ma) { @@ -632,9 +674,6 @@ int mdt_attr_get_complex(struct mdt_thread_info *info, int rc = 0, rc2; ENTRY; - /* do we really need PFID */ - LASSERT((ma->ma_need & MA_PFID) == 0); - ma->ma_valid = 0; if (need & MA_INODE) { @@ -645,6 +684,14 @@ int mdt_attr_get_complex(struct mdt_thread_info *info, ma->ma_valid |= MA_INODE; } + if (need & MA_PFID) { + rc = mdt_attr_get_pfid(info, o, &ma->ma_pfid); + if (rc == 0) + ma->ma_valid |= MA_PFID; + /* ignore this error, parent fid is not mandatory */ + rc = 0; + } + if (need & MA_LOV && (S_ISREG(mode) || S_ISDIR(mode))) { rc = mdt_attr_get_lov(info, o, ma); if (rc)