From 6d622d67edb0f330a02a1970437852b764cde7cd Mon Sep 17 00:00:00 2001 From: nathan Date: Thu, 5 Nov 2009 23:33:58 +0000 Subject: [PATCH] b=19669 i=adilger i=vitaly - get and set LMA in mdd layer - change LMA endianness and handle swabbing --- lustre/include/lustre/lustre_idl.h | 39 +++++++++++ lustre/include/lustre/lustre_user.h | 5 ++ lustre/include/md_object.h | 12 +++- lustre/mdd/mdd_object.c | 134 +++++++++++++++++++++++++++++++++++- lustre/osd/osd_handler.c | 11 +-- lustre/utils/liblustreapi.c | 2 +- 6 files changed, 195 insertions(+), 8 deletions(-) diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 7f76ca0..5344ad3 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -294,6 +294,45 @@ struct lustre_mdt_attrs { }; /** + * Fill \a lma with its first content. + * Only fid is stored. + */ +static inline void lustre_lma_init(struct lustre_mdt_attrs *lma, + const struct lu_fid *fid) +{ + lma->lma_compat = 0; + lma->lma_incompat = 0; + memcpy(&lma->lma_self_fid, fid, sizeof(*fid)); + lma->lma_flags = 0; + lma->lma_som_sectors = 0; + + /* If a field is added in struct lustre_mdt_attrs, zero it explicitly + * and change the test below. */ + LASSERT(sizeof(*lma) == + (offsetof(struct lustre_mdt_attrs, lma_som_sectors) + + sizeof(lma->lma_som_sectors))); +}; + +extern void lustre_swab_lu_fid(struct lu_fid *fid); + +/** + * Swab, if needed, lustre_mdt_attr struct to on-disk format. + * Otherwise, do not touch it. + */ +static inline void lustre_lma_swab(struct lustre_mdt_attrs *lma) +{ + /* Use LUSTRE_MSG_MAGIC to detect local endianess. */ + if (LUSTRE_MSG_MAGIC != cpu_to_le32(LUSTRE_MSG_MAGIC)) { + __swab32s(&lma->lma_compat); + __swab32s(&lma->lma_incompat); + lustre_swab_lu_fid(&lma->lma_self_fid); + __swab64s(&lma->lma_flags); + __swab64s(&lma->lma_som_sectors); + } +}; + + +/** * fid constants */ enum { diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index 0777e2a..4f3695b 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -522,6 +522,11 @@ enum changelog_message_type { /********* HSM **********/ + + +#define HSM_FLAGS_MASK 0 + + enum hsm_message_type { HMT_ACTION_LIST = 100, /* message is a hsm_action_list */ }; diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index bfa7de4..0e3dd26 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -123,7 +123,10 @@ enum ma_valid { MA_FLAGS = (1 << 3), MA_LMV = (1 << 4), MA_ACL_DEF = (1 << 5), - MA_LOV_DEF = (1 << 6) + MA_LOV_DEF = (1 << 6), +/* (Layout lock will used #7 here) */ + MA_HSM = (1 << 8), + MA_SOM = (1 << 9) }; typedef enum { @@ -144,6 +147,11 @@ typedef enum { MDT_PDO_LOCK = (1 << 1) } mdl_type_t; +struct md_hsm { + __u32 mh_flags; +}; +#define ma_hsm_flags ma_hsm.mh_flags + struct md_attr { __u64 ma_valid; __u64 ma_need; @@ -158,6 +166,8 @@ struct md_attr { struct llog_cookie *ma_cookie; int ma_cookie_size; struct lustre_capa *ma_capa; + struct md_hsm ma_hsm; +/* XXX: struct md_som_data *ma_som; */ }; /** Additional parameters for create */ diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 55b9f7b..ddb26db 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -685,6 +685,55 @@ static int __mdd_lmv_get(const struct lu_env *env, RETURN(rc); } +static int __mdd_lma_get(const struct lu_env *env, struct mdd_object *mdd_obj, + struct md_attr *ma) +{ + struct mdd_thread_info *info = mdd_env_info(env); + struct lustre_mdt_attrs *lma = + (struct lustre_mdt_attrs *)info->mti_xattr_buf; + int lma_size; + int rc; + ENTRY; + + /* If all needed data are already valid, nothing to do */ + if ((ma->ma_valid & (MA_HSM | MA_SOM)) == + (ma->ma_need & (MA_HSM | MA_SOM))) + RETURN(0); + + /* Read LMA from disk EA */ + lma_size = sizeof(info->mti_xattr_buf); + rc = mdd_get_md(env, mdd_obj, lma, &lma_size, XATTR_NAME_LMA); + if (rc <= 0) + RETURN(rc); + + /* Useless to check LMA incompatibility because this is already done in + * osd_ea_fid_get(), and this will fail long before this code is + * called. + * So, if we are here, LMA is compatible. + */ + + lustre_lma_swab(lma); + + /* Swab and copy LMA */ + if (ma->ma_need & MA_HSM) { + if (lma->lma_compat & LMAC_HSM) + ma->ma_hsm_flags = lma->lma_flags & HSM_FLAGS_MASK; + else + ma->ma_hsm_flags = 0; + ma->ma_valid |= MA_HSM; + } + if (ma->ma_need & MA_SOM) { + + /* XXX: Here, copy and swab SoM data, and then remove this + * assert. */ + LASSERT(!(ma->ma_need & MA_SOM)); + + ma->ma_valid |= MA_SOM; + } + + RETURN(0); +} + static int mdd_attr_get_internal(const struct lu_env *env, struct mdd_object *mdd_obj, struct md_attr *ma) @@ -704,6 +753,10 @@ static int mdd_attr_get_internal(const struct lu_env *env, if (S_ISDIR(mdd_object_type(mdd_obj))) rc = __mdd_lmv_get(env, mdd_obj, ma); } + if (rc == 0 && ma->ma_need & (MA_HSM | MA_SOM)) { + if (S_ISREG(mdd_object_type(mdd_obj))) + rc = __mdd_lma_get(env, mdd_obj, ma); + } #ifdef CONFIG_FS_POSIX_ACL if (rc == 0 && ma->ma_need & MA_ACL_DEF) { if (S_ISDIR(mdd_object_type(mdd_obj))) @@ -719,7 +772,8 @@ int mdd_attr_get_internal_locked(const struct lu_env *env, struct mdd_object *mdd_obj, struct md_attr *ma) { int rc; - int needlock = ma->ma_need & (MA_LOV | MA_LMV | MA_ACL_DEF); + int needlock = ma->ma_need & + (MA_LOV | MA_LMV | MA_ACL_DEF | MA_HSM | MA_SOM); if (needlock) mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD); @@ -1216,6 +1270,76 @@ static int mdd_changelog_data_store(const struct lu_env *env, return 0; } +/** + * Should be called with write lock held. + * + * \see mdd_lma_set_locked(). + */ +static int __mdd_lma_set(const struct lu_env *env, struct mdd_object *mdd_obj, + const struct md_attr *ma, struct thandle *handle) +{ + struct mdd_thread_info *info = mdd_env_info(env); + struct lu_buf *buf; + struct lustre_mdt_attrs *lma = + (struct lustre_mdt_attrs *) info->mti_xattr_buf; + int lmasize = sizeof(struct lustre_mdt_attrs); + int rc = 0; + + ENTRY; + + memset(lma, 0, lmasize); + + /* Either HSM or SOM part is not valid, we need to read it before */ + if ((!ma->ma_valid) & (MA_HSM | MA_SOM)) { + rc = mdd_get_md(env, mdd_obj, lma, &lmasize, XATTR_NAME_LMA); + if (rc) + RETURN(rc); + + lustre_lma_swab(lma); + } + + /* Copy HSM data */ + if (ma->ma_valid & MA_HSM) { + lma->lma_flags |= ma->ma_hsm_flags & HSM_FLAGS_MASK; + lma->lma_compat |= LMAC_HSM; + } + /* XXX: Copy SOM data */ + if (ma->ma_valid & MA_SOM) { + /* + lma->lma_compat |= LMAC_SOM; + */ + LASSERT(!(ma->ma_valid & MA_SOM)); + } + + /* Copy FID */ + memcpy(&lma->lma_self_fid, mdo2fid(mdd_obj), sizeof(lma->lma_self_fid)); + + lustre_lma_swab(lma); + buf = mdd_buf_get(env, lma, lmasize); + rc = __mdd_xattr_set(env, mdd_obj, buf, XATTR_NAME_LMA, 0, handle); + + RETURN(rc); +} + +/** + * Save LMA extended attributes with data from \a ma. + * + * HSM and Size-On-MDS data will be extracted from \ma if they are valid, if + * not, LMA EA will be first read from disk, modified and write back. + * + */ +static int mdd_lma_set_locked(const struct lu_env *env, + struct mdd_object *mdd_obj, + const struct md_attr *ma, struct thandle *handle) +{ + int rc; + + mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD); + rc = __mdd_lma_set(env, mdd_obj, ma, handle); + mdd_write_unlock(env, mdd_obj); + return rc; +} + /* set attr and LOV EA at once, return updated attr */ static int mdd_attr_set(const struct lu_env *env, struct md_object *obj, const struct md_attr *ma) @@ -1331,6 +1455,14 @@ static int mdd_attr_set(const struct lu_env *env, struct md_object *obj, } } + if (rc == 0 && ma->ma_valid & (MA_HSM | MA_SOM)) { + umode_t mode; + + mode = mdd_object_type(mdd_obj); + if (S_ISREG(mode)) + rc = mdd_lma_set_locked(env, mdd_obj, ma, handle); + + } cleanup: if ((rc == 0) && (ma->ma_attr.la_valid & (LA_MTIME | LA_CTIME))) rc = mdd_changelog_data_store(env, mdd, CL_SETATTR, mdd_obj, diff --git a/lustre/osd/osd_handler.c b/lustre/osd/osd_handler.c index 40901dd..cb3c654 100644 --- a/lustre/osd/osd_handler.c +++ b/lustre/osd/osd_handler.c @@ -1710,8 +1710,8 @@ static int osd_ea_fid_set(const struct lu_env *env, struct dt_object *dt, struct osd_thread_info *info = osd_oti_get(env); struct lustre_mdt_attrs *mdt_attrs = &info->oti_mdt_attrs; - fid_cpu_to_be(&mdt_attrs->lma_self_fid, fid); - + lustre_lma_init(mdt_attrs, fid); + lustre_lma_swab(mdt_attrs); return __osd_xattr_set(env, dt, osd_buf_get(env, mdt_attrs, sizeof *mdt_attrs), XATTR_NAME_LMA, LU_XATTR_CREATE); @@ -1794,15 +1794,16 @@ static int osd_ea_fid_get(const struct lu_env *env, struct osd_object *obj, /* Check LMA compatibility */ if (rc > 0 && - (mdt_attrs->lma_incompat & ~cpu_to_be32(LMA_INCOMPAT_SUPP))) { + (mdt_attrs->lma_incompat & ~cpu_to_le32(LMA_INCOMPAT_SUPP))) { CWARN("Inode %lx: Unsupported incompat LMA feature(s) %#x\n", - inode->i_ino, be32_to_cpu(mdt_attrs->lma_incompat) & + inode->i_ino, le32_to_cpu(mdt_attrs->lma_incompat) & ~LMA_INCOMPAT_SUPP); return -ENOSYS; } if (rc > 0) { - fid_be_to_cpu(fid, &mdt_attrs->lma_self_fid); + lustre_lma_swab(mdt_attrs); + memcpy(fid, &mdt_attrs->lma_self_fid, sizeof(*mdt_attrs)); rc = 0; } else if (rc == -ENODATA) { osd_igif_get(env, inode, fid); diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 33a9f46..d0c3144 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -2873,7 +2873,7 @@ static int path2fid_from_lma(const char *path, lustre_fid *fid) if (rc < 0) return -errno; lma = (struct lustre_mdt_attrs *)buf; - fid_be_to_cpu(fid, &lma->lma_self_fid); + fid_le_to_cpu(fid, &lma->lma_self_fid); return 0; } -- 1.8.3.1