From: Di Wang Date: Sat, 9 Jan 2016 15:05:32 +0000 (-0500) Subject: LU-7579 osd: move ORPHAN/DEAD flag to OSD X-Git-Tag: 2.8.51~76 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=098fb363c3902f67b29ddfa864b452d0a8460ad2 LU-7579 osd: move ORPHAN/DEAD flag to OSD If a directory is unlinked while it is opened, then it will set LUSTRE_ORPHAN_FL flag to osd object, so the remote target can get this status by dt_attr_get(). And also LUSTRE_ORPHAN_FL will be stored inside LMA (converted to LMAI_ORPHAN). In the meantime, it will remove LUSTRE_SLAVE_DEAD_FL flag for dead stripes of a striped directory, i.e. all of dead directories (stripes) will use LMAI_ORPHAN in LMA to indicate the status. Also in osp_xattr, it should retrieve the return value from the reply, which is the real length of EA, instead of using reply buffer length. Change-Id: I14e933b5f008981cbacbdfa478e4ec8cbebf97dc Signed-off-by: Di Wang Reviewed-on: http://review.whamcloud.com/18024 Reviewed-by: John L. Hammond Reviewed-by: Andreas Dilger Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index b0fa434..af7c90a 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -195,8 +195,10 @@ enum lma_incompat { LMAI_REMOTE_PARENT = 0x00000004, /* the parent of the object is on the remote MDT */ LMAI_STRIPED = 0x00000008, /* striped directory inode */ + LMAI_ORPHAN = 0x00000010, /* inode is orphan */ + LMA_INCOMPAT_SUPP = (LMAI_AGENT | LMAI_REMOTE_PARENT | \ + LMAI_STRIPED | LMAI_ORPHAN) }; -#define LMA_INCOMPAT_SUPP (LMAI_AGENT | LMAI_REMOTE_PARENT | LMAI_STRIPED) extern void lustre_lma_swab(struct lustre_mdt_attrs *lma); extern void lustre_lma_init(struct lustre_mdt_attrs *lma, @@ -2107,18 +2109,44 @@ enum { #define MDS_STATUS_CONN 1 #define MDS_STATUS_LOV 2 -/* these should be identical to their EXT4_*_FL counterparts, they are - * redefined here only to avoid dragging in fs/ext4/ext4.h */ -#define LUSTRE_SYNC_FL 0x00000008 /* Synchronous updates */ -#define LUSTRE_IMMUTABLE_FL 0x00000010 /* Immutable file */ -#define LUSTRE_APPEND_FL 0x00000020 /* writes to file may only append */ -#define LUSTRE_NODUMP_FL 0x00000040 /* do not dump file */ -#define LUSTRE_NOATIME_FL 0x00000080 /* do not update atime */ -#define LUSTRE_INDEX_FL 0x00001000 /* hash-indexed directory */ -#define LUSTRE_DIRSYNC_FL 0x00010000 /* dirsync behaviour (dir only) */ -#define LUSTRE_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/ -#define LUSTRE_DIRECTIO_FL 0x00100000 /* Use direct i/o */ -#define LUSTRE_INLINE_DATA_FL 0x10000000 /* Inode has inline data. */ +enum { + /* these should be identical to their EXT4_*_FL counterparts, they are + * redefined here only to avoid dragging in fs/ext4/ext4.h */ + LUSTRE_SYNC_FL = 0x00000008, /* Synchronous updates */ + LUSTRE_IMMUTABLE_FL = 0x00000010, /* Immutable file */ + LUSTRE_APPEND_FL = 0x00000020, /* writes to file may only append */ + LUSTRE_NODUMP_FL = 0x00000040, /* do not dump file */ + LUSTRE_NOATIME_FL = 0x00000080, /* do not update atime */ + LUSTRE_INDEX_FL = 0x00001000, /* hash-indexed directory */ + LUSTRE_DIRSYNC_FL = 0x00010000, /* dirsync behaviour (dir only) */ + LUSTRE_TOPDIR_FL = 0x00020000, /* Top of directory hierarchies*/ + LUSTRE_DIRECTIO_FL = 0x00100000, /* Use direct i/o */ + LUSTRE_INLINE_DATA_FL = 0x10000000, /* Inode has inline data. */ + + /* These flags will not be identical to any EXT4_*_FL counterparts, + * and only reserved for lustre purpose. Note: these flags might + * be conflict with some of EXT4 flags, so + * 1. these conflict flags needs to be removed when the flag is + * wired by la_flags see osd_attr_get(). + * 2. If these flags needs to be stored into inode, they will be + * stored in LMA. see LMAI_XXXX */ + LUSTRE_ORPHAN_FL = 0x00002000, + + LUSTRE_LMA_FL_MASKS = LUSTRE_ORPHAN_FL, +}; + +/* LUSTRE_LMA_FL_MASKS defines which flags will be stored in LMA */ + +static inline int lma_to_lustre_flags(__u32 lma_flags) +{ + return (lma_flags & LMAI_ORPHAN) ? LUSTRE_ORPHAN_FL : 0; +} + +static inline int lustre_to_lma_flags(__u32 la_flags) +{ + return (la_flags & LUSTRE_ORPHAN_FL) ? LMAI_ORPHAN : 0; +} + #ifdef __KERNEL__ /* Convert wire LUSTRE_*_FL to corresponding client local VFS S_* values @@ -2576,7 +2604,14 @@ struct lmv_mds_md_v1 { #define LMV_HASH_TYPE_MASK 0x0000ffff #define LMV_HASH_FLAG_MIGRATION 0x80000000 + +#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 10, 53, 0) +/* Since lustre 2.8, this flag will not be needed, instead this DEAD + * and orphan flags will be stored in LMA (see LMAI_ORPHAN) + * Keep this flag just for LFSCK, because it still might meet such + * flag when it checks the old FS */ #define LMV_HASH_FLAG_DEAD 0x40000000 +#endif #define LMV_HASH_FLAG_BAD_TYPE 0x20000000 /* The striped directory has ever lost its master LMV EA, then LFSCK diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index 9e2087b..49dd2e6 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -289,14 +289,6 @@ struct md_object { const struct md_dir_operations *mo_dir_ops; }; -/* Mark the object to be dead, and can not be accessed anymore. - * XXX, right now, it will only be used for striped directory to - * mark the slave stripes dead, when deleting master object. It will be - * stored in slave LMV EA (see lod_mark_dead_object), which is only - * temporary, and will be removed later when we have proper way to mark - * the dead object. */ -#define LUSTRE_SLAVE_DEAD_FL 0x80000000 - static inline struct md_device *lu2md_dev(const struct lu_device *d) { LASSERT(IS_ERR(d) || lu_device_is_md(d)); diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index 5834cf3..f8aec41 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -508,6 +508,7 @@ extern char obd_jobid_var[]; #define OBD_FAIL_LLITE_XATTR_ENOMEM 0x1405 #define OBD_FAIL_MAKE_LOVEA_HOLE 0x1406 #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407 +#define OBD_FAIL_LLITE_NO_CHECK_DEAD 0x1408 #define OBD_FAIL_FID_INDIR 0x1501 #define OBD_FAIL_FID_INLMA 0x1502 diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 2ebad02..4f28145 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -469,6 +469,10 @@ static int ll_dir_setdirstripe(struct inode *parent, struct lmv_user_md *lump, !(exp_connect_flags(sbi->ll_md_exp) & OBD_CONNECT_DIR_STRIPE)) RETURN(-EINVAL); + if (IS_DEADDIR(parent) && + !OBD_FAIL_CHECK(OBD_FAIL_LLITE_NO_CHECK_DEAD)) + RETURN(-ENOENT); + if (lump->lum_magic != cpu_to_le32(LMV_USER_MAGIC)) lustre_swab_lmv_user_md(lump); diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index aab61a3..04cbd1a 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -1065,78 +1065,6 @@ static int lod_attr_get(const struct lu_env *env, } /** - * Mark all of the striped directory sub-stripes dead. - * - * When a striped object is a subject to removal, we have - * to mark all the stripes to prevent further access to - * them (e.g. create a new file in those). So we mark - * all the stripes with LMV_HASH_FLAG_DEAD. The function - * can be used to declare the changes and to apply them. - * If the object isn't striped, then just return success. - * - * \param[in] env execution environment - * \param[in] dt the striped object - * \param[in] handle transaction handle - * \param[in] declare whether to declare the change or apply - * - * \retval 0 on success - * \retval negative if failed - **/ -static int lod_mark_dead_object(const struct lu_env *env, - struct dt_object *dt, - struct thandle *th, - bool declare) -{ - struct lod_object *lo = lod_dt_obj(dt); - struct lmv_mds_md_v1 *lmv; - __u32 dead_hash_type; - int rc; - int i; - - ENTRY; - - if (!S_ISDIR(dt->do_lu.lo_header->loh_attr)) - RETURN(0); - - rc = lod_load_striping_locked(env, lo); - if (rc != 0) - RETURN(rc); - - if (lo->ldo_stripenr == 0) - RETURN(0); - - rc = lod_get_lmv_ea(env, lo); - if (rc <= 0) - RETURN(rc); - - lmv = lod_env_info(env)->lti_ea_store; - lmv->lmv_magic = cpu_to_le32(LMV_MAGIC_STRIPE); - dead_hash_type = le32_to_cpu(lmv->lmv_hash_type) | LMV_HASH_FLAG_DEAD; - lmv->lmv_hash_type = cpu_to_le32(dead_hash_type); - for (i = 0; i < lo->ldo_stripenr; i++) { - struct lu_buf buf; - - lmv->lmv_master_mdt_index = i; - buf.lb_buf = lmv; - buf.lb_len = sizeof(*lmv); - if (declare) { - rc = lod_sub_object_declare_xattr_set(env, - lo->ldo_stripe[i], &buf, - XATTR_NAME_LMV, - LU_XATTR_REPLACE, th); - } else { - rc = lod_sub_object_xattr_set(env, lo->ldo_stripe[i], - &buf, XATTR_NAME_LMV, - LU_XATTR_REPLACE, th); - } - if (rc != 0) - break; - } - - RETURN(rc); -} - -/** * Implementation of dt_object_operations::do_declare_attr_set. * * If the object is striped, then apply the changes to all the stripes. @@ -1154,13 +1082,6 @@ static int lod_declare_attr_set(const struct lu_env *env, int rc, i; ENTRY; - /* Set dead object on all other stripes */ - if (attr->la_valid & LA_FLAGS && !(attr->la_valid & ~LA_FLAGS) && - attr->la_flags & LUSTRE_SLAVE_DEAD_FL) { - rc = lod_mark_dead_object(env, dt, th, true); - RETURN(rc); - } - /* * declare setattr on the local object */ @@ -1253,13 +1174,6 @@ static int lod_attr_set(const struct lu_env *env, int rc, i; ENTRY; - /* Set dead object on all other stripes */ - if (attr->la_valid & LA_FLAGS && !(attr->la_valid & ~LA_FLAGS) && - attr->la_flags & LUSTRE_SLAVE_DEAD_FL) { - rc = lod_mark_dead_object(env, dt, th, false); - RETURN(rc); - } - /* * apply changes to the local object */ diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 93f1f49..2cb3736 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -380,8 +380,6 @@ int mdd_may_create(const struct lu_env *env, struct mdd_object *pobj, const struct lu_attr *pattr, struct mdd_object *cobj, bool check_perm) { - struct mdd_thread_info *info = mdd_env_info(env); - struct lu_buf *xbuf; int rc = 0; ENTRY; @@ -391,18 +389,6 @@ int mdd_may_create(const struct lu_env *env, struct mdd_object *pobj, if (mdd_is_dead_obj(pobj)) RETURN(-ENOENT); - /* If the parent is a sub-stripe, check whether it is dead */ - xbuf = mdd_buf_get(env, info->mti_key, sizeof(info->mti_key)); - rc = mdo_xattr_get(env, pobj, xbuf, XATTR_NAME_LMV); - if (unlikely(rc > 0)) { - struct lmv_mds_md_v1 *lmv1 = xbuf->lb_buf; - - if (le32_to_cpu(lmv1->lmv_magic) == LMV_MAGIC_STRIPE && - le32_to_cpu(lmv1->lmv_hash_type) & LMV_HASH_FLAG_DEAD) - RETURN(-ESTALE); - } - rc = 0; - if (check_perm) rc = mdd_permission_internal_locked(env, pobj, pattr, MAY_WRITE | MAY_EXEC, @@ -1418,21 +1404,18 @@ out_pending: return rc; } -static int mdd_mark_dead_object(const struct lu_env *env, +static int mdd_mark_orphan_object(const struct lu_env *env, struct mdd_object *obj, struct thandle *handle, bool declare) { struct lu_attr *attr = MDD_ENV_VAR(env, la_for_start); int rc; - if (!declare) - obj->mod_flags |= DEAD_OBJ; - if (!S_ISDIR(mdd_object_type(obj))) return 0; attr->la_valid = LA_FLAGS; - attr->la_flags = LUSTRE_SLAVE_DEAD_FL; + attr->la_flags = LUSTRE_ORPHAN_FL; if (declare) rc = mdo_declare_attr_set(env, obj, attr, handle); @@ -1448,7 +1431,10 @@ static int mdd_declare_finish_unlink(const struct lu_env *env, { int rc; - rc = mdd_mark_dead_object(env, obj, handle, true); + /* Sigh, we do not know if the unlink object will become orphan in + * declare phase, but fortunately the flags here does not matter + * in current declare implementation */ + rc = mdd_mark_orphan_object(env, obj, handle, true); if (rc != 0) return rc; @@ -1471,34 +1457,35 @@ int mdd_finish_unlink(const struct lu_env *env, struct thandle *th) { int rc = 0; - int is_dir = S_ISDIR(ma->ma_attr.la_mode); - ENTRY; + int is_dir = S_ISDIR(ma->ma_attr.la_mode); + ENTRY; - LASSERT(mdd_write_locked(env, obj) != 0); + LASSERT(mdd_write_locked(env, obj) != 0); if (ma->ma_attr.la_nlink == 0 || is_dir) { - rc = mdd_mark_dead_object(env, obj, th, false); - if (rc != 0) - RETURN(rc); + /* add new orphan and the object + * will be deleted during mdd_close() */ + obj->mod_flags |= DEAD_OBJ; + if (obj->mod_count) { + rc = mdd_mark_orphan_object(env, obj, th, false); + if (rc != 0) + RETURN(rc); - /* add new orphan and the object - * will be deleted during mdd_close() */ - if (obj->mod_count) { - rc = __mdd_orphan_add(env, obj, th); - if (rc == 0) - CDEBUG(D_HA, "Object "DFID" is inserted into " - "orphan list, open count = %d\n", - PFID(mdd_object_fid(obj)), - obj->mod_count); - else - CERROR("Object "DFID" fail to be an orphan, " - "open count = %d, maybe cause failed " - "open replay\n", - PFID(mdd_object_fid(obj)), - obj->mod_count); - } else { + rc = __mdd_orphan_add(env, obj, th); + if (rc == 0) + CDEBUG(D_HA, "Object "DFID" is inserted into " + "orphan list, open count = %d\n", + PFID(mdd_object_fid(obj)), + obj->mod_count); + else + CERROR("Object "DFID" fail to be an orphan, " + "open count = %d, maybe cause failed " + "open replay\n", + PFID(mdd_object_fid(obj)), + obj->mod_count); + } else { rc = mdo_destroy(env, obj, th); - } + } } else if (!is_dir) { /* old files may not have link ea; ignore errors */ mdd_links_del(env, obj, mdo2fid(pobj), lname, th); @@ -1732,14 +1719,22 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, rc = mdd_finish_unlink(env, mdd_cobj, ma, mdd_pobj, lname, handle); /* fetch updated nlink */ - if (rc == 0) - rc = mdd_la_get(env, mdd_cobj, cattr); + if (rc != 0) + GOTO(cleanup, rc); + + rc = mdd_la_get(env, mdd_cobj, cattr); + /* if object is removed then we can't get its attrs, + * use last get */ + if (rc == -ENOENT) { + cattr->la_nlink = 0; + rc = 0; + } - /* if object is removed then we can't get its attrs, use last get */ if (cattr->la_nlink == 0) { ma->ma_attr = *cattr; ma->ma_valid |= MA_INODE; } + EXIT; cleanup: if (likely(mdd_cobj != NULL)) @@ -1955,10 +1950,9 @@ static int mdd_create_sanity_check(const struct lu_env *env, int rc; ENTRY; - /* EEXIST check */ - if (mdd_is_dead_obj(obj) || - pattr->la_flags & LUSTRE_SLAVE_DEAD_FL) - RETURN(-ENOENT); + /* EEXIST check */ + if (mdd_is_dead_obj(obj)) + RETURN(-ENOENT); /* * In some cases this lookup is not needed - we know before if name @@ -2955,7 +2949,12 @@ static int mdd_rename(const struct lu_env *env, /* fetch updated nlink */ rc = mdd_la_get(env, mdd_tobj, tattr); - if (rc != 0) { + if (rc == -ENOENT) { + /* the object got removed, let's + * return the latest known attributes */ + tattr->la_nlink = 0; + rc = 0; + } else if (rc != 0) { CERROR("%s: Failed to get nlink for tobj " DFID": rc = %d\n", mdd2obd_dev(mdd)->obd_name, diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 541efbf..58d51b7 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -65,13 +65,26 @@ static int mdd_xattr_get(const struct lu_env *env, int mdd_la_get(const struct lu_env *env, struct mdd_object *obj, struct lu_attr *la) { - if (mdd_object_exists(obj) == 0) { - CERROR("%s: object "DFID" not found: rc = -2\n", - mdd_obj_dev_name(obj), PFID(mdd_object_fid(obj))); - return -ENOENT; - } + int rc; + + if (mdd_object_exists(obj) == 0) { + CERROR("%s: object "DFID" not found: rc = -2\n", + mdd_obj_dev_name(obj), PFID(mdd_object_fid(obj))); + return -ENOENT; + } + + rc = mdo_attr_get(env, obj, la); + if (unlikely(rc != 0)) { + if (rc == -ENOENT) + obj->mod_flags |= DEAD_OBJ; + return rc; + } + + if (la->la_valid & LA_FLAGS && + la->la_flags & LUSTRE_ORPHAN_FL) + obj->mod_flags |= ORPHAN_OBJ | DEAD_OBJ; - return mdo_attr_get(env, obj, la); + return 0; } struct mdd_thread_info *mdd_env_info(const struct lu_env *env) diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 944b035..d894e86 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -1013,8 +1013,22 @@ static int osd_object_init(const struct lu_env *env, struct lu_object *l, result = osd_fid_lookup(env, obj, lu_object_fid(l), conf); obj->oo_dt.do_body_ops = &osd_body_ops_new; - if (result == 0 && obj->oo_inode != NULL) + if (result == 0 && obj->oo_inode != NULL) { + struct osd_thread_info *oti = osd_oti_get(env); + struct lustre_mdt_attrs *lma = &oti->oti_mdt_attrs; + osd_object_init0(obj); + result = osd_get_lma(oti, obj->oo_inode, + &oti->oti_obj_dentry, lma); + if (result == 0) { + /* Convert LMAI flags to lustre LMA flags + * and cache it to oo_lma_flags */ + obj->oo_lma_flags = + lma_to_lustre_flags(lma->lma_incompat); + } else if (result == -ENODATA) { + result = 0; + } + } LINVRNT(osd_invariant(obj)); return result; @@ -1902,7 +1916,6 @@ static struct timespec *osd_inode_time(const struct lu_env *env, return t; } - static void osd_inode_getattr(const struct lu_env *env, struct inode *inode, struct lu_attr *attr) { @@ -1919,7 +1932,7 @@ static void osd_inode_getattr(const struct lu_env *env, attr->la_blocks = inode->i_blocks; attr->la_uid = i_uid_read(inode); attr->la_gid = i_gid_read(inode); - attr->la_flags = LDISKFS_I(inode)->i_flags; + attr->la_flags = ll_inode_to_ext_flags(inode->i_flags); attr->la_nlink = inode->i_nlink; attr->la_rdev = inode->i_rdev; attr->la_blksize = 1 << inode->i_blkbits; @@ -1932,7 +1945,9 @@ static int osd_attr_get(const struct lu_env *env, { struct osd_object *obj = osd_dt_obj(dt); - if (!dt_object_exists(dt)) + if (unlikely(!dt_object_exists(dt))) + return -ENOENT; + if (unlikely(obj->oo_destroyed)) return -ENOENT; LASSERT(!dt_object_remote(dt)); @@ -1940,7 +1955,10 @@ static int osd_attr_get(const struct lu_env *env, spin_lock(&obj->oo_guard); osd_inode_getattr(env, obj->oo_inode, attr); + if (obj->oo_lma_flags & LUSTRE_ORPHAN_FL) + attr->la_flags |= LUSTRE_ORPHAN_FL; spin_unlock(&obj->oo_guard); + return 0; } @@ -1972,6 +1990,9 @@ static int osd_declare_attr_set(const struct lu_env *env, osd_trans_declare_op(env, oh, OSD_OT_ATTR_SET, osd_dto_credits_noquota[DTO_ATTR_SET_BASE]); + osd_trans_declare_op(env, oh, OSD_OT_XATTR_SET, + osd_dto_credits_noquota[DTO_XATTR_SET]); + if (attr == NULL || obj->oo_inode == NULL) RETURN(rc); @@ -2216,10 +2237,41 @@ static int osd_attr_set(const struct lu_env *env, spin_lock(&obj->oo_guard); rc = osd_inode_setattr(env, inode, attr); spin_unlock(&obj->oo_guard); + if (rc != 0) + GOTO(out, rc); - if (!rc) - ll_dirty_inode(inode, I_DIRTY_DATASYNC); + ll_dirty_inode(inode, I_DIRTY_DATASYNC); + + if (!(attr->la_valid & LA_FLAGS)) + GOTO(out, rc); + + /* Let's check if there are extra flags need to be set into LMA */ + if (attr->la_flags & LUSTRE_LMA_FL_MASKS) { + struct osd_thread_info *info = osd_oti_get(env); + struct lustre_mdt_attrs *lma = &info->oti_mdt_attrs; + + rc = osd_get_lma(info, inode, &info->oti_obj_dentry, lma); + if (rc != 0) + GOTO(out, rc); + lma->lma_incompat |= + lustre_to_lma_flags(attr->la_flags); + lustre_lma_swab(lma); + rc = __osd_xattr_set(info, inode, XATTR_NAME_LMA, + lma, sizeof(*lma), XATTR_REPLACE); + if (rc != 0) { + struct osd_device *osd = osd_obj2dev(obj); + + CWARN("%s: set "DFID" lma flags %u failed: rc = %d\n", + osd_name(osd), PFID(lu_object_fid(&dt->do_lu)), + lma->lma_incompat, rc); + } else { + obj->oo_lma_flags = + attr->la_flags & LUSTRE_LMA_FL_MASKS; + } + osd_trans_exec_check(env, handle, OSD_OT_XATTR_SET); + } +out: osd_trans_exec_check(env, handle, OSD_OT_ATTR_SET); return rc; @@ -2467,20 +2519,20 @@ static void osd_attr_init(struct osd_thread_info *info, struct osd_object *obj, if (result) return; - if (attr->la_valid != 0) { - result = osd_inode_setattr(info->oti_env, inode, attr); - /* - * The osd_inode_setattr() should always succeed here. The - * only error that could be returned is EDQUOT when we are - * trying to change the UID or GID of the inode. However, this - * should not happen since quota enforcement is no longer - * enabled on ldiskfs (lquota takes care of it). - */ + if (attr->la_valid != 0) { + result = osd_inode_setattr(info->oti_env, inode, attr); + /* + * The osd_inode_setattr() should always succeed here. The + * only error that could be returned is EDQUOT when we are + * trying to change the UID or GID of the inode. However, this + * should not happen since quota enforcement is no longer + * enabled on ldiskfs (lquota takes care of it). + */ LASSERTF(result == 0, "%d\n", result); ll_dirty_inode(inode, I_DIRTY_DATASYNC); - } + } - attr->la_valid = valid; + attr->la_valid = valid; } /** diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index ae51525..ec6fdd8 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -129,6 +129,9 @@ struct osd_object { spinlock_t oo_guard; __u32 oo_destroyed:1; + + /* the i_flags in LMA */ + __u32 oo_lma_flags; /** * Following two members are used to indicate the presence of dot and * dotdot in the given directory. This is required for interop mode diff --git a/lustre/osd-zfs/osd_internal.h b/lustre/osd-zfs/osd_internal.h index 62543f8..527eb79 100644 --- a/lustre/osd-zfs/osd_internal.h +++ b/lustre/osd-zfs/osd_internal.h @@ -332,6 +332,9 @@ struct osd_object { enum osd_destroy_type oo_destroy; __u32 oo_destroyed:1; + + /* the i_flags in LMA */ + __u32 oo_lma_flags; /* record size for index file */ unsigned char oo_keysize; unsigned char oo_recsize; @@ -530,16 +533,16 @@ osd_xattr_set_internal(const struct lu_env *env, struct osd_object *obj, static inline uint64_t attrs_fs2zfs(const uint32_t flags) { - return (((flags & FS_APPEND_FL) ? ZFS_APPENDONLY : 0) | - ((flags & FS_NODUMP_FL) ? ZFS_NODUMP : 0) | - ((flags & FS_IMMUTABLE_FL) ? ZFS_IMMUTABLE : 0)); + return (flags & LUSTRE_APPEND_FL ? ZFS_APPENDONLY : 0) | + (flags & LUSTRE_NODUMP_FL ? ZFS_NODUMP : 0) | + (flags & LUSTRE_IMMUTABLE_FL ? ZFS_IMMUTABLE : 0); } static inline uint32_t attrs_zfs2fs(const uint64_t flags) { - return (((flags & ZFS_APPENDONLY) ? FS_APPEND_FL : 0) | - ((flags & ZFS_NODUMP) ? FS_NODUMP_FL : 0) | - ((flags & ZFS_IMMUTABLE) ? FS_IMMUTABLE_FL : 0)); + return (flags & ZFS_APPENDONLY ? LUSTRE_APPEND_FL : 0) | + (flags & ZFS_NODUMP ? LUSTRE_NODUMP_FL : 0) | + (flags & ZFS_IMMUTABLE ? LUSTRE_IMMUTABLE_FL : 0); } #endif diff --git a/lustre/osd-zfs/osd_object.c b/lustre/osd-zfs/osd_object.c index 9884333..7935fab 100644 --- a/lustre/osd-zfs/osd_object.c +++ b/lustre/osd-zfs/osd_object.c @@ -231,6 +231,28 @@ int __osd_object_attr_get(const struct lu_env *env, struct osd_device *o, la->la_flags = attrs_zfs2fs(osa->flags); la->la_size = osa->size; + /* Try to get extra flag from LMA. Right now, only LMAI_ORPHAN + * flags is stored in LMA, and it is only for orphan directory */ + if (S_ISDIR(la->la_mode) && dt_object_exists(&obj->oo_dt)) { + struct osd_thread_info *info = osd_oti_get(env); + struct lustre_mdt_attrs *lma; + struct lu_buf buf; + + lma = (struct lustre_mdt_attrs *)info->oti_buf; + buf.lb_buf = lma; + buf.lb_len = sizeof(info->oti_buf); + rc = osd_xattr_get(env, &obj->oo_dt, &buf, XATTR_NAME_LMA); + if (rc > 0) { + rc = 0; + lma->lma_incompat = le32_to_cpu(lma->lma_incompat); + obj->oo_lma_flags = + lma_to_lustre_flags(lma->lma_incompat); + + } else if (rc == -ENODATA) { + rc = 0; + } + } + if (S_ISCHR(la->la_mode) || S_ISBLK(la->la_mode)) { rc = -sa_lookup(sa_hdl, SA_ZPL_RDEV(o), &osa->rdev, 8); if (rc) @@ -719,12 +741,18 @@ static int osd_attr_get(const struct lu_env *env, uint64_t blocks; uint32_t blksize; - LASSERT(dt_object_exists(dt)); + if (unlikely(!dt_object_exists(dt))) + return -ENOENT; + if (unlikely(obj->oo_destroyed)) + return -ENOENT; + LASSERT(osd_invariant(obj)); LASSERT(obj->oo_db); read_lock(&obj->oo_attr_lock); *attr = obj->oo_attr; + if (obj->oo_lma_flags & LUSTRE_ORPHAN_FL) + attr->la_flags |= LUSTRE_ORPHAN_FL; read_unlock(&obj->oo_attr_lock); /* with ZFS_DEBUG zrl_add_debug() called by DB_DNODE_ENTER() @@ -842,6 +870,9 @@ static int osd_declare_attr_set(const struct lu_env *env, sa_object_size(obj->oo_sa_hdl, &blksize, &bspace); bspace = toqb(bspace * blksize); + __osd_xattr_declare_set(env, obj, sizeof(struct lustre_mdt_attrs), + XATTR_NAME_LMA, oh); + if (attr && attr->la_valid & LA_UID) { /* account for user inode tracking ZAP update */ dmu_tx_hold_bonus(oh->ot_tx, osd->od_iusr_oid); @@ -886,10 +917,11 @@ static int osd_declare_attr_set(const struct lu_env *env, static int osd_attr_set(const struct lu_env *env, struct dt_object *dt, const struct lu_attr *la, struct thandle *handle) { + struct osd_thread_info *info = osd_oti_get(env); struct osd_object *obj = osd_dt_obj(dt); struct osd_device *osd = osd_obj2dev(obj); struct osd_thandle *oh; - struct osa_attr *osa = &osd_oti_get(env)->oti_osa; + struct osa_attr *osa = &info->oti_osa; sa_bulk_attr_t *bulk; __u64 valid = la->la_valid; int cnt; @@ -913,6 +945,39 @@ static int osd_attr_set(const struct lu_env *env, struct dt_object *dt, if (valid == 0) RETURN(0); + if (valid & LA_FLAGS) { + struct lustre_mdt_attrs *lma; + struct lu_buf buf; + + if (la->la_flags & LUSTRE_LMA_FL_MASKS) { + CLASSERT(sizeof(info->oti_buf) >= sizeof(*lma)); + lma = (struct lustre_mdt_attrs *)&info->oti_buf; + buf.lb_buf = lma; + buf.lb_len = sizeof(info->oti_buf); + rc = osd_xattr_get(env, &obj->oo_dt, &buf, + XATTR_NAME_LMA); + if (rc > 0) { + lma->lma_incompat = + le32_to_cpu(lma->lma_incompat); + lma->lma_incompat |= + lustre_to_lma_flags(la->la_flags); + lma->lma_incompat = + cpu_to_le32(lma->lma_incompat); + buf.lb_buf = lma; + buf.lb_len = sizeof(*lma); + rc = osd_xattr_set_internal(env, obj, &buf, + XATTR_NAME_LMA, + LU_XATTR_REPLACE, + oh); + } + if (rc < 0) { + CWARN("%s: failed to set LMA flags: rc = %d\n", + osd->od_svname, rc); + RETURN(rc); + } + } + } + OBD_ALLOC(bulk, sizeof(sa_bulk_attr_t) * 10); if (bulk == NULL) RETURN(-ENOMEM); diff --git a/lustre/osp/osp_object.c b/lustre/osp/osp_object.c index a71af4e..294aff1 100644 --- a/lustre/osp/osp_object.c +++ b/lustre/osp/osp_object.c @@ -1039,7 +1039,6 @@ unlock: GOTO(out, rc = -ERANGE); memcpy(buf->lb_buf, rbuf->lb_buf, rbuf->lb_len); - rc = rbuf->lb_len; if (obj->opo_ooa == NULL || osp->opd_connect_mdt) GOTO(out, rc); diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index f048a4c..97e32cc 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -421,6 +421,14 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_self_fid)); LASSERTF(LMAI_RELEASED == 0x00000001UL, "found 0x%.8xUL\n", (unsigned)LMAI_RELEASED); + LASSERTF(LMAI_AGENT == 0x00000002UL, "found 0x%.8xUL\n", + (unsigned)LMAI_AGENT); + LASSERTF(LMAI_REMOTE_PARENT == 0x00000004UL, "found 0x%.8xUL\n", + (unsigned)LMAI_REMOTE_PARENT); + LASSERTF(LMAI_STRIPED == 0x00000008UL, "found 0x%.8xUL\n", + (unsigned)LMAI_STRIPED); + LASSERTF(LMAI_ORPHAN == 0x00000010UL, "found 0x%.8xUL\n", + (unsigned)LMAI_ORPHAN); LASSERTF(LMAC_HSM == 0x00000001UL, "found 0x%.8xUL\n", (unsigned)LMAC_HSM); LASSERTF(LMAC_NOT_IN_OI == 0x00000004UL, "found 0x%.8xUL\n", @@ -2160,26 +2168,28 @@ void lustre_assert_wire_constants(void) (long long)MDS_OPEN_NEWSTRIPE); LASSERTF(MDS_OPEN_VOLATILE == 00000000000400000000000ULL, "found 0%.22lloULL\n", (long long)MDS_OPEN_VOLATILE); - LASSERTF(LUSTRE_SYNC_FL == 0x00000008, "found 0x%.8x\n", - LUSTRE_SYNC_FL); - LASSERTF(LUSTRE_IMMUTABLE_FL == 0x00000010, "found 0x%.8x\n", - LUSTRE_IMMUTABLE_FL); - LASSERTF(LUSTRE_APPEND_FL == 0x00000020, "found 0x%.8x\n", - LUSTRE_APPEND_FL); - LASSERTF(LUSTRE_NODUMP_FL == 0x00000040, "found 0x%.8x\n", - LUSTRE_NODUMP_FL); - LASSERTF(LUSTRE_NOATIME_FL == 0x00000080, "found 0x%.8x\n", - LUSTRE_NOATIME_FL); - LASSERTF(LUSTRE_INDEX_FL == 0x00001000, "found 0x%.8x\n", - LUSTRE_INDEX_FL); - LASSERTF(LUSTRE_DIRSYNC_FL == 0x00010000, "found 0x%.8x\n", - LUSTRE_DIRSYNC_FL); - LASSERTF(LUSTRE_TOPDIR_FL == 0x00020000, "found 0x%.8x\n", - LUSTRE_TOPDIR_FL); - LASSERTF(LUSTRE_DIRECTIO_FL == 0x00100000, "found 0x%.8x\n", - LUSTRE_DIRECTIO_FL); - LASSERTF(LUSTRE_INLINE_DATA_FL == 0x10000000, "found 0x%.8x\n", - LUSTRE_INLINE_DATA_FL); + LASSERTF(LUSTRE_SYNC_FL == 0x00000008UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_SYNC_FL); + LASSERTF(LUSTRE_IMMUTABLE_FL == 0x00000010UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_IMMUTABLE_FL); + LASSERTF(LUSTRE_APPEND_FL == 0x00000020UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_APPEND_FL); + LASSERTF(LUSTRE_NODUMP_FL == 0x00000040UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_NODUMP_FL); + LASSERTF(LUSTRE_NOATIME_FL == 0x00000080UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_NOATIME_FL); + LASSERTF(LUSTRE_INDEX_FL == 0x00001000UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_INDEX_FL); + LASSERTF(LUSTRE_ORPHAN_FL == 0x00002000UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_ORPHAN_FL); + LASSERTF(LUSTRE_DIRSYNC_FL == 0x00010000UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_DIRSYNC_FL); + LASSERTF(LUSTRE_TOPDIR_FL == 0x00020000UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_TOPDIR_FL); + LASSERTF(LUSTRE_DIRECTIO_FL == 0x00100000UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_DIRECTIO_FL); + LASSERTF(LUSTRE_INLINE_DATA_FL == 0x10000000UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_INLINE_DATA_FL); LASSERTF(MDS_INODELOCK_LOOKUP == 0x000001, "found 0x%.8x\n", MDS_INODELOCK_LOOKUP); LASSERTF(MDS_INODELOCK_UPDATE == 0x000002, "found 0x%.8x\n", diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index ac1624c..ab6ea8c 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -14238,6 +14238,26 @@ test_300p() { } run_test 300p "create striped directory without space" +test_300q() { + [ $PARALLEL == "yes" ] && skip "skip parallel run" && return + [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return + + local fd=$(free_fd) + local cmd="exec $fd<$tdir" + cd $DIR + $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails" + eval $cmd + cmd="exec $fd<&-" + trap "eval $cmd" EXIT + cd $tdir || error "cd $tdir fails" + rmdir ../$tdir || error "rmdir $tdir fails" + mkdir local_dir && error "create dir succeeds" + $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds" + eval $cmd + return 0 +} +run_test 300q "create remote directory under orphan directory" + prepare_remote_file() { mkdir $DIR/$tdir/src_dir || error "create remote source failed" diff --git a/lustre/tests/sanityn.sh b/lustre/tests/sanityn.sh index 5bb7c8a..096bebc 100644 --- a/lustre/tests/sanityn.sh +++ b/lustre/tests/sanityn.sh @@ -3544,6 +3544,29 @@ test_91() { } run_test 91 "chmod and unlink striped directory" +test_92() { + [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return + + local fd=$(free_fd) + local cmd="exec $fd<$DIR1/$tdir" + $LFS setdirstripe -c$MDSCOUNT $DIR1/$tdir || error "mkdir $tdir fails" + eval $cmd + cmd="exec $fd<&-" + trap "eval $cmd" EXIT + cd $DIR1/$tdir || error "cd $DIR1/$tdir fails" + rmdir ../$tdir || error "rmdir ../$tdir fails" + + #define OBD_FAIL_LLITE_NO_CHECK_DEAD 0x1408 + $LCTL set_param fail_loc=0x1408 + mkdir $DIR2/$tdir/dir && error "create dir succeeds" + $LFS setdirstripe -i1 $DIR2/$tdir/remote_dir && + error "create remote dir succeeds" + $LCTL set_param fail_loc=0 + eval $cmd + return 0 +} +run_test 92 "create remote directory under orphan directory" + log "cleanup: ======================================================" # kill and wait in each test only guarentee script finish, but command in script diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index cd0890d..cbb62c2 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -207,6 +207,10 @@ check_lustre_mdt_attrs(void) CHECK_MEMBER(lustre_mdt_attrs, lma_incompat); CHECK_MEMBER(lustre_mdt_attrs, lma_self_fid); CHECK_VALUE_X(LMAI_RELEASED); + CHECK_VALUE_X(LMAI_AGENT); + CHECK_VALUE_X(LMAI_REMOTE_PARENT); + CHECK_VALUE_X(LMAI_STRIPED); + CHECK_VALUE_X(LMAI_ORPHAN); CHECK_VALUE_X(LMAC_HSM); CHECK_VALUE_X(LMAC_NOT_IN_OI); @@ -961,16 +965,17 @@ check_mdt_body(void) /* these should be identical to their EXT3_*_FL counterparts, and * are redefined only to avoid dragging in ext3_fs.h */ - CHECK_DEFINE_X(LUSTRE_SYNC_FL); - CHECK_DEFINE_X(LUSTRE_IMMUTABLE_FL); - CHECK_DEFINE_X(LUSTRE_APPEND_FL); - CHECK_DEFINE_X(LUSTRE_NODUMP_FL); - CHECK_DEFINE_X(LUSTRE_NOATIME_FL); - CHECK_DEFINE_X(LUSTRE_INDEX_FL); - CHECK_DEFINE_X(LUSTRE_DIRSYNC_FL); - CHECK_DEFINE_X(LUSTRE_TOPDIR_FL); - CHECK_DEFINE_X(LUSTRE_DIRECTIO_FL); - CHECK_DEFINE_X(LUSTRE_INLINE_DATA_FL); + CHECK_VALUE_X(LUSTRE_SYNC_FL); + CHECK_VALUE_X(LUSTRE_IMMUTABLE_FL); + CHECK_VALUE_X(LUSTRE_APPEND_FL); + CHECK_VALUE_X(LUSTRE_NODUMP_FL); + CHECK_VALUE_X(LUSTRE_NOATIME_FL); + CHECK_VALUE_X(LUSTRE_INDEX_FL); + CHECK_VALUE_X(LUSTRE_ORPHAN_FL); + CHECK_VALUE_X(LUSTRE_DIRSYNC_FL); + CHECK_VALUE_X(LUSTRE_TOPDIR_FL); + CHECK_VALUE_X(LUSTRE_DIRECTIO_FL); + CHECK_VALUE_X(LUSTRE_INLINE_DATA_FL); CHECK_DEFINE_X(MDS_INODELOCK_LOOKUP); CHECK_DEFINE_X(MDS_INODELOCK_UPDATE); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 1a3dc98..8bcf604 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -435,6 +435,14 @@ void lustre_assert_wire_constants(void) (long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_self_fid)); LASSERTF(LMAI_RELEASED == 0x00000001UL, "found 0x%.8xUL\n", (unsigned)LMAI_RELEASED); + LASSERTF(LMAI_AGENT == 0x00000002UL, "found 0x%.8xUL\n", + (unsigned)LMAI_AGENT); + LASSERTF(LMAI_REMOTE_PARENT == 0x00000004UL, "found 0x%.8xUL\n", + (unsigned)LMAI_REMOTE_PARENT); + LASSERTF(LMAI_STRIPED == 0x00000008UL, "found 0x%.8xUL\n", + (unsigned)LMAI_STRIPED); + LASSERTF(LMAI_ORPHAN == 0x00000010UL, "found 0x%.8xUL\n", + (unsigned)LMAI_ORPHAN); LASSERTF(LMAC_HSM == 0x00000001UL, "found 0x%.8xUL\n", (unsigned)LMAC_HSM); LASSERTF(LMAC_NOT_IN_OI == 0x00000004UL, "found 0x%.8xUL\n", @@ -2174,26 +2182,28 @@ void lustre_assert_wire_constants(void) (long long)MDS_OPEN_NEWSTRIPE); LASSERTF(MDS_OPEN_VOLATILE == 00000000000400000000000ULL, "found 0%.22lloULL\n", (long long)MDS_OPEN_VOLATILE); - LASSERTF(LUSTRE_SYNC_FL == 0x00000008, "found 0x%.8x\n", - LUSTRE_SYNC_FL); - LASSERTF(LUSTRE_IMMUTABLE_FL == 0x00000010, "found 0x%.8x\n", - LUSTRE_IMMUTABLE_FL); - LASSERTF(LUSTRE_APPEND_FL == 0x00000020, "found 0x%.8x\n", - LUSTRE_APPEND_FL); - LASSERTF(LUSTRE_NODUMP_FL == 0x00000040, "found 0x%.8x\n", - LUSTRE_NODUMP_FL); - LASSERTF(LUSTRE_NOATIME_FL == 0x00000080, "found 0x%.8x\n", - LUSTRE_NOATIME_FL); - LASSERTF(LUSTRE_INDEX_FL == 0x00001000, "found 0x%.8x\n", - LUSTRE_INDEX_FL); - LASSERTF(LUSTRE_DIRSYNC_FL == 0x00010000, "found 0x%.8x\n", - LUSTRE_DIRSYNC_FL); - LASSERTF(LUSTRE_TOPDIR_FL == 0x00020000, "found 0x%.8x\n", - LUSTRE_TOPDIR_FL); - LASSERTF(LUSTRE_DIRECTIO_FL == 0x00100000, "found 0x%.8x\n", - LUSTRE_DIRECTIO_FL); - LASSERTF(LUSTRE_INLINE_DATA_FL == 0x10000000, "found 0x%.8x\n", - LUSTRE_INLINE_DATA_FL); + LASSERTF(LUSTRE_SYNC_FL == 0x00000008UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_SYNC_FL); + LASSERTF(LUSTRE_IMMUTABLE_FL == 0x00000010UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_IMMUTABLE_FL); + LASSERTF(LUSTRE_APPEND_FL == 0x00000020UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_APPEND_FL); + LASSERTF(LUSTRE_NODUMP_FL == 0x00000040UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_NODUMP_FL); + LASSERTF(LUSTRE_NOATIME_FL == 0x00000080UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_NOATIME_FL); + LASSERTF(LUSTRE_INDEX_FL == 0x00001000UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_INDEX_FL); + LASSERTF(LUSTRE_ORPHAN_FL == 0x00002000UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_ORPHAN_FL); + LASSERTF(LUSTRE_DIRSYNC_FL == 0x00010000UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_DIRSYNC_FL); + LASSERTF(LUSTRE_TOPDIR_FL == 0x00020000UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_TOPDIR_FL); + LASSERTF(LUSTRE_DIRECTIO_FL == 0x00100000UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_DIRECTIO_FL); + LASSERTF(LUSTRE_INLINE_DATA_FL == 0x10000000UL, "found 0x%.8xUL\n", + (unsigned)LUSTRE_INLINE_DATA_FL); LASSERTF(MDS_INODELOCK_LOOKUP == 0x000001, "found 0x%.8x\n", MDS_INODELOCK_LOOKUP); LASSERTF(MDS_INODELOCK_UPDATE == 0x000002, "found 0x%.8x\n",