From ee380d571fb4cffbb9505fc8cea97e7b6bb4fb83 Mon Sep 17 00:00:00 2001 From: huanghua Date: Mon, 20 Nov 2006 02:57:14 +0000 Subject: [PATCH] (1) use hash value 0xfffffffeUL to mark end of a directory instead of -1; (2) add a TODO to handle readdir from removed dir. mdd_object is set to be dead when its nlink drops to zero. --- lustre/include/lustre/lustre_idl.h | 2 ++ lustre/llite/dir.c | 13 ++++++++----- lustre/lmv/lmv_obd.c | 2 +- lustre/mdd/mdd_dir.c | 7 +++++++ lustre/mdd/mdd_object.c | 19 +++++++++++-------- 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 0011a98..9015553 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -326,6 +326,8 @@ static inline int lu_dirent_size(struct lu_dirent *ent) return le16_to_cpu(ent->lde_reclen); } +#define DIR_END_OFF 0xfffffffeUL + #define MEA_MAGIC_LAST_CHAR 0xb2221ca1 #define MEA_MAGIC_ALL_CHARS 0xb222a11c #define MEA_MAGIC_HASH_SEGMENT 0xb222a11b diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index e7b91e8..b07894b 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -410,7 +410,7 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) inode->i_ino, inode->i_generation, inode, (unsigned long)pos, inode->i_size); - if (pos == ~0) + if (pos == DIR_END_OFF) /* * end-of-file. */ @@ -428,8 +428,11 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) struct lu_dirent *ent; if (!IS_ERR(page)) { - __u32 hash = ~0; /* if page is empty (end of directory - * is reached) use this value. */ + /* + * If page is empty (end of directoryis reached), + * use this value. + */ + __u32 hash = DIR_END_OFF; __u32 next; dp = page_address(page); @@ -472,7 +475,7 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) ll_put_page(page); if (!done) { pos = next; - if (pos == ~0) + if (pos == DIR_END_OFF) /* * End of directory reached. */ @@ -498,7 +501,7 @@ int ll_readdir(struct file *filp, void *cookie, filldir_t filldir) } } - filp->f_pos = pos; + filp->f_pos = (loff_t)(__s32)pos; filp->f_version = inode->i_version; touch_atime(filp->f_vfsmnt, filp->f_dentry); diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index a82b6ce..715ec2a 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -2035,7 +2035,7 @@ static int lmv_readpage(struct obd_export *exp, const struct lu_fid *fid, (void)kmap(page); dp = cfs_page_address(page); end = le32_to_cpu(dp->ldp_hash_end); - if (end == ~0ul) { + if (end == DIR_END_OFF) { __u64 max_hash = MAX_HASH_SIZE; do_div(max_hash, obj->lo_objcount); diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index 7d365de..bff8fdc 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -437,6 +437,12 @@ out_trans: return rc; } +static inline void mdd_set_dead_obj(struct mdd_object *obj) +{ + if (obj) + obj->mod_flags |= DEAD_OBJ; +} + /* caller should take a lock before calling */ int mdd_finish_unlink(const struct lu_env *env, struct mdd_object *obj, struct md_attr *ma, @@ -452,6 +458,7 @@ int mdd_finish_unlink(const struct lu_env *env, if (__mdd_orphan_add(env, obj, th) == 0) obj->mod_flags |= ORPHAN_OBJ; + mdd_set_dead_obj(obj); if (obj->mod_count == 0) rc = mdd_object_kill(env, obj, ma); else diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 33806b3..e47eb93 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -48,12 +48,6 @@ static struct lu_object_operations mdd_lu_obj_ops; -static inline void mdd_set_dead_obj(struct mdd_object *obj) -{ - if (obj) - obj->mod_flags |= DEAD_OBJ; -} - int mdd_la_get(const struct lu_env *env, struct mdd_object *obj, struct lu_attr *la, struct lustre_capa *capa) { @@ -1206,7 +1200,6 @@ int mdd_object_kill(const struct lu_env *env, struct mdd_object *obj, int rc = 0; ENTRY; - mdd_set_dead_obj(obj); if (S_ISREG(mdd_object_type(obj))) { /* Return LOV & COOKIES unconditionally here. We clean evth up. * Caller must be ready for that. */ @@ -1405,7 +1398,7 @@ static int __mdd_readpage(const struct lu_env *env, struct mdd_object *obj, /* * end of directory. */ - hash_end = ~0ul; + hash_end = DIR_END_OFF; rc = 0; } if (rc == 0) { @@ -1443,6 +1436,16 @@ static int mdd_readpage(const struct lu_env *env, struct md_object *obj, rc = mdd_readpage_sanity_check(env, mdd_obj); if (rc) GOTO(out_unlock, rc); + + if (mdd_is_dead_obj(mdd_obj)) { + /* + * TODO: + * According to POSIX, please do not return any entry to client: + * even dot and dotdot should not be returned. How to do this? + */ + CWARN("readdir from dead object: "DFID"\n", + PFID(lu_object_fid(mdd2lu_obj(mdd_obj)))); + } rc = __mdd_readpage(env, mdd_obj, rdpg); -- 1.8.3.1