From: pravins Date: Sun, 8 Feb 2009 17:24:39 +0000 (+0000) Subject: b=15134 X-Git-Tag: v1_8_0_110~274 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=22af94cfc8d491b8929b46e8f41a34b9dad13144;p=fs%2Flustre-release.git b=15134 i=adilger i=h.huang interop patch for lu_dirent attribute handling. --- diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 7e97469..256da3b 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -766,6 +766,19 @@ typedef enum { /* This FULL lock is useful to take on unlink sort of operations */ #define MDS_INODELOCK_FULL ((1<<(MDS_INODELOCK_MAXSHIFT+1))-1) + +/** + * Enumeration of possible directory entry attributes. + * + * Attributes follow directory entry header in the order they appear in this + * enumeration. + */ +enum lu_dirent_attrs { + LUDA_FID = 0x0001, + LUDA_TYPE = 0x0002, +}; + + extern void lustre_swab_ll_fid (struct ll_fid *fid); struct lu_fid { diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 05f8157..f8f55a8 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -439,15 +439,26 @@ static inline __u32 hash_x_index(__u32 value) return ((__u32)~0) - value; } -/* +/** * Layout of readdir pages, as transmitted on wire. - */ + */ struct lu_dirent { + /** valid if LUDA_FID is set. */ struct lu_fid lde_fid; + /** a unique entry identifier: a hash or an offset. */ __u64 lde_hash; + /** total record length, including all attributes. */ __u16 lde_reclen; + /** name length */ __u16 lde_namelen; - __u32 lde_padding; + /** optional variable size attributes following this entry. + * taken from enum lu_dirent_attrs. + */ + __u32 lde_attrs; + /** name is followed by the attributes indicated in ->ldp_attrs, in + * their natural order. After the last attribute, padding bytes are + * added to make ->lde_reclen a multiple of 8. + */ char lde_name[0]; }; @@ -460,10 +471,74 @@ struct lu_dirpage { struct lu_dirent ldp_entries[0]; }; +/* + * Definitions of optional directory entry attributes formats. + * + * Individual attributes do not have their length encoded in a generic way. It + * is assumed that consumer of an attribute knows its format. This means that + * it is impossible to skip over an unknown attribute, except by skipping over all + * remaining attributes (by using ->lde_reclen), which is not too + * constraining, because new server versions will append new attributes at + * the end of an entry. + */ + +/** + * Fid directory attribute: a fid of an object referenced by the entry. This + * will be almost always requested by the client and supplied by the server. + * + * Aligned to 8 bytes. + */ +/* To have compatibility with 1.8, lets have fid in lu_dirent struct. */ + +/** + * File type. + * + * Aligned to 2 bytes. + */ +struct luda_type { + __u16 lt_type; +}; + enum lu_dirpage_flags { LDF_EMPTY = 1 << 0 }; +static inline int lu_dirent_calc_size(int namelen, __u16 attr) +{ + int size; + + if (attr & LUDA_TYPE) { + const unsigned align = sizeof(struct luda_type) - 1; + size = (sizeof(struct lu_dirent) + namelen + align) & ~align; + size += sizeof(struct luda_type); + } else + size = sizeof(struct lu_dirent) + namelen; + + return (size + 7) & ~7; +} + +/** + * return IF_* type for given lu_dirent entry. + * IF_* flag shld be converted to particular OS file type in + * platform llite module. + */ +__u16 ll_dirent_type_get(struct lu_dirent *ent) +{ + __u16 type = 0; + struct luda_type *lt; + int len = 0; + + if (le32_to_cpu(ent->lde_attrs) & LUDA_TYPE) { + const unsigned align = sizeof(struct luda_type) - 1; + + len = le16_to_cpu(ent->lde_namelen); + len = (len + align) & ~align; + lt = (void *) ent->lde_name + len; + type = CFS_IFTODT(le16_to_cpu(lt->lt_type)); + } + return type; +} + static inline struct lu_dirent *lu_dirent_start(struct lu_dirpage *dp) { if (le16_to_cpu(dp->ldp_flags) & LDF_EMPTY) @@ -487,8 +562,8 @@ static inline struct lu_dirent *lu_dirent_next(struct lu_dirent *ent) static inline int lu_dirent_size(struct lu_dirent *ent) { if (le16_to_cpu(ent->lde_reclen) == 0) { - return (sizeof(*ent) + - le16_to_cpu(ent->lde_namelen) + 3) & ~3; + return lu_dirent_calc_size(le16_to_cpu(ent->lde_namelen), + le32_to_cpu(ent->lde_attrs)); } return le16_to_cpu(ent->lde_reclen); } @@ -735,6 +810,7 @@ static int ll_readdir_20(struct file *filp, void *cookie, filldir_t filldir) int rc; int done; int shift; + __u16 type; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p) pos %lu/%llu\n", @@ -794,9 +870,9 @@ static int ll_readdir_20(struct file *filp, void *cookie, filldir_t filldir) name = ent->lde_name; fid_le_to_cpu(&fid, &fid); ino = ll_fid_build_ino(sbi, (struct ll_fid*)&fid); - + type = ll_dirent_type_get(ent); done = filldir(cookie, name, namelen, - (loff_t)hash, ino, DT_UNKNOWN); + (loff_t)hash, ino, type); } next = le64_to_cpu(dp->ldp_hash_end); ll_put_page(page); diff --git a/lustre/mdc/mdc_lib.c b/lustre/mdc/mdc_lib.c index 579e6d5..1e61f0f 100644 --- a/lustre/mdc/mdc_lib.c +++ b/lustre/mdc/mdc_lib.c @@ -91,6 +91,7 @@ static void mdc_readdir_pack_20(struct ptlrpc_request *req, int offset, b->size = pg_off; /* !! */ b->suppgid = -1; b->nlink = size; /* !! */ + b->mode = LUDA_FID | LUDA_TYPE; EXIT; }