Whamcloud - gitweb
b=15134
authorpravins <pravins>
Sun, 8 Feb 2009 17:24:39 +0000 (17:24 +0000)
committerpravins <pravins>
Sun, 8 Feb 2009 17:24:39 +0000 (17:24 +0000)
i=adilger
i=h.huang
interop patch for lu_dirent attribute handling.

lustre/include/lustre/lustre_idl.h
lustre/llite/dir.c
lustre/mdc/mdc_lib.c

index 7e97469..256da3b 100644 (file)
@@ -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 {
index 05f8157..f8f55a8 100644 (file)
@@ -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);
index 579e6d5..1e61f0f 100644 (file)
@@ -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;
 }