]> err.no Git - linux-2.6/commitdiff
ocfs2: Structure updates for inline data
authorMark Fasheh <mark.fasheh@oracle.com>
Fri, 7 Sep 2007 20:58:15 +0000 (13:58 -0700)
committerMark Fasheh <mark.fasheh@oracle.com>
Fri, 12 Oct 2007 18:54:39 +0000 (11:54 -0700)
Add the disk, network and memory structures needed to support data in inode.

Struct ocfs2_inline_data is defined and embedded in ocfs2_dinode for storing
inline data.

A new inode field, i_dyn_features, is added to facilitate tracking of
dynamic inode state. Since it will be used often, we want to mirror it on
ocfs2_inode_info, and transfer it via the meta data lvb.

Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Reviewed-by: Joel Becker <joel.becker@oracle.com>
fs/ocfs2/dlmglue.c
fs/ocfs2/dlmglue.h
fs/ocfs2/inode.c
fs/ocfs2/inode.h
fs/ocfs2/ocfs2.h
fs/ocfs2/ocfs2_fs.h

index f71250ed166fe9d3eac561e9aec5a9bb99e98813..41c76ff2fcfbc4d725be65a4498b5fd603aa6f2c 100644 (file)
@@ -1482,6 +1482,7 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
        lvb->lvb_imtime_packed =
                cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime));
        lvb->lvb_iattr    = cpu_to_be32(oi->ip_attr);
+       lvb->lvb_idynfeatures = cpu_to_be16(oi->ip_dyn_features);
        lvb->lvb_igeneration = cpu_to_be32(inode->i_generation);
 
 out:
@@ -1515,6 +1516,7 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
        i_size_write(inode, be64_to_cpu(lvb->lvb_isize));
 
        oi->ip_attr = be32_to_cpu(lvb->lvb_iattr);
+       oi->ip_dyn_features = be16_to_cpu(lvb->lvb_idynfeatures);
        ocfs2_set_inode_flags(inode);
 
        /* fast-symlinks are a special case */
index 492bad32a8c0a6be8b576321adb871ecce4b44ee..87a785e41205c4cef900e6d38aeebf288a7f1adf 100644 (file)
 
 #include "dcache.h"
 
-#define OCFS2_LVB_VERSION 4
+#define OCFS2_LVB_VERSION 5
 
 struct ocfs2_meta_lvb {
        __u8         lvb_version;
        __u8         lvb_reserved0;
-       __be16       lvb_reserved1;
+       __be16       lvb_idynfeatures;
        __be32       lvb_iclusters;
        __be32       lvb_iuid;
        __be32       lvb_igid;
index c53a6763bbbebf7500f4c53e9e1e38ca9806eb15..c8923bab422aa885abf55ceb189f638f46b10557 100644 (file)
@@ -241,6 +241,7 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
 
        OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
        OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
+       OCFS2_I(inode)->ip_dyn_features = le16_to_cpu(fe->i_dyn_features);
 
        inode->i_version = 1;
        inode->i_generation = le32_to_cpu(fe->i_generation);
@@ -1220,6 +1221,7 @@ int ocfs2_mark_inode_dirty(handle_t *handle,
        fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters);
        ocfs2_get_inode_flags(OCFS2_I(inode));
        fe->i_attr = cpu_to_le32(OCFS2_I(inode)->ip_attr);
+       fe->i_dyn_features = cpu_to_le16(OCFS2_I(inode)->ip_dyn_features);
        spin_unlock(&OCFS2_I(inode)->ip_lock);
 
        fe->i_size = cpu_to_le64(i_size_read(inode));
@@ -1257,6 +1259,7 @@ void ocfs2_refresh_inode(struct inode *inode,
 
        OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
        OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
+       OCFS2_I(inode)->ip_dyn_features = le16_to_cpu(fe->i_dyn_features);
        ocfs2_set_inode_flags(inode);
        i_size_write(inode, le64_to_cpu(fe->i_size));
        inode->i_nlink = le16_to_cpu(fe->i_links_count);
index a41d0817121b21ed35e73def7ec91a5e603b7dec..70e881c5553621d4e8f6fc380f1b682c5499587d 100644 (file)
@@ -51,6 +51,7 @@ struct ocfs2_inode_info
 
        u32                             ip_flags; /* see below */
        u32                             ip_attr; /* inode attributes */
+       u16                             ip_dyn_features;
 
        /* protected by recovery_lock. */
        struct inode                    *ip_next_orphan;
index 58307853fb4a5be7100405d720f720202bcec6f6..60a23e1906b0c054c9b3a7091a662437cb3c7ab5 100644 (file)
@@ -319,6 +319,13 @@ static inline int ocfs2_writes_unwritten_extents(struct ocfs2_super *osb)
        return 0;
 }
 
+static inline int ocfs2_supports_inline_data(struct ocfs2_super *osb)
+{
+       if (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_INLINE_DATA)
+               return 1;
+       return 0;
+}
+
 /* set / clear functions because cluster events can make these happen
  * in parallel so we want the transitions to be atomic. this also
  * means that any future flags osb_flags must be protected by spinlock
index bf10a545383318b06feffa9902abcc3313761b02..6ef876759a737eb098d7abbf70e87d69663114f9 100644 (file)
@@ -87,7 +87,8 @@
 
 #define OCFS2_FEATURE_COMPAT_SUPP      OCFS2_FEATURE_COMPAT_BACKUP_SB
 #define OCFS2_FEATURE_INCOMPAT_SUPP    (OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT \
-                                        | OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC)
+                                        | OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC \
+                                        | OCFS2_FEATURE_INCOMPAT_INLINE_DATA)
 #define OCFS2_FEATURE_RO_COMPAT_SUPP   OCFS2_FEATURE_RO_COMPAT_UNWRITTEN
 
 /*
  */
 #define OCFS2_FEATURE_INCOMPAT_TUNEFS_INPROG   0x0020
 
+/* Support for data packed into inode blocks */
+#define OCFS2_FEATURE_INCOMPAT_INLINE_DATA     0x0040
+
 /*
  * backup superblock flag is used to indicate that this volume
  * has backup superblocks.
 #define OCFS2_CHAIN_FL         (0x00000400)    /* Chain allocator */
 #define OCFS2_DEALLOC_FL       (0x00000800)    /* Truncate log */
 
+/*
+ * Flags on ocfs2_dinode.i_dyn_features
+ *
+ * These can change much more often than i_flags. When adding flags,
+ * keep in mind that i_dyn_features is only 16 bits wide.
+ */
+#define OCFS2_INLINE_DATA_FL   (0x0001)        /* Data stored in inode block */
+#define OCFS2_HAS_XATTR_FL     (0x0002)
+#define OCFS2_INLINE_XATTR_FL  (0x0004)
+#define OCFS2_INDEXED_DIR_FL   (0x0008)
+
 /* Inode attributes, keep in sync with EXT2 */
 #define OCFS2_SECRM_FL         (0x00000001)    /* Secure deletion */
 #define OCFS2_UNRM_FL          (0x00000002)    /* Undelete */
@@ -486,6 +501,19 @@ struct ocfs2_local_alloc
 /*10*/ __u8   la_bitmap[0];
 };
 
+/*
+ * Data-in-inode header. This is only used if i_dyn_features has
+ * OCFS2_INLINE_DATA_FL set.
+ */
+struct ocfs2_inline_data
+{
+/*00*/ __le16  id_count;       /* Number of bytes that can be used
+                                * for data, starting at id_data */
+       __le16  id_reserved0;
+       __le32  id_reserved1;
+       __u8    id_data[0];     /* Start of user data */
+};
+
 /*
  * On disk inode for OCFS2
  */
@@ -518,7 +546,7 @@ struct ocfs2_dinode {
        __le32 i_attr;
        __le16 i_orphaned_slot;         /* Only valid when OCFS2_ORPHANED_FL
                                           was set in i_flags */
-       __le16 i_reserved1;
+       __le16 i_dyn_features;
 /*70*/ __le64 i_reserved2[8];
 /*B8*/ union {
                __le64 i_pad1;          /* Generic way to refer to this
@@ -544,6 +572,7 @@ struct ocfs2_dinode {
                struct ocfs2_chain_list         i_chain;
                struct ocfs2_extent_list        i_list;
                struct ocfs2_truncate_log       i_dealloc;
+               struct ocfs2_inline_data        i_data;
                __u8                            i_symlink[0];
        } id2;
 /* Actual on-disk size is one block */
@@ -593,6 +622,12 @@ static inline int ocfs2_fast_symlink_chars(struct super_block *sb)
                 offsetof(struct ocfs2_dinode, id2.i_symlink);
 }
 
+static inline int ocfs2_max_inline_data(struct super_block *sb)
+{
+       return sb->s_blocksize -
+               offsetof(struct ocfs2_dinode, id2.i_data.id_data);
+}
+
 static inline int ocfs2_extent_recs_per_inode(struct super_block *sb)
 {
        int size;
@@ -672,6 +707,11 @@ static inline int ocfs2_fast_symlink_chars(int blocksize)
        return blocksize - offsetof(struct ocfs2_dinode, id2.i_symlink);
 }
 
+static inline int ocfs2_max_inline_data(int blocksize)
+{
+       return blocksize - offsetof(struct ocfs2_dinode, id2.i_data.id_data);
+}
+
 static inline int ocfs2_extent_recs_per_inode(int blocksize)
 {
        int size;