ocfs2: Structure updates for inline data

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>
This commit is contained in:
Mark Fasheh 2007-09-07 13:58:15 -07:00
parent 8553cf4f36
commit 15b1e36bdb
6 changed files with 57 additions and 4 deletions

View File

@ -1482,6 +1482,7 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
lvb->lvb_imtime_packed = lvb->lvb_imtime_packed =
cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime)); cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime));
lvb->lvb_iattr = cpu_to_be32(oi->ip_attr); 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); lvb->lvb_igeneration = cpu_to_be32(inode->i_generation);
out: 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)); i_size_write(inode, be64_to_cpu(lvb->lvb_isize));
oi->ip_attr = be32_to_cpu(lvb->lvb_iattr); oi->ip_attr = be32_to_cpu(lvb->lvb_iattr);
oi->ip_dyn_features = be16_to_cpu(lvb->lvb_idynfeatures);
ocfs2_set_inode_flags(inode); ocfs2_set_inode_flags(inode);
/* fast-symlinks are a special case */ /* fast-symlinks are a special case */

View File

@ -29,12 +29,12 @@
#include "dcache.h" #include "dcache.h"
#define OCFS2_LVB_VERSION 4 #define OCFS2_LVB_VERSION 5
struct ocfs2_meta_lvb { struct ocfs2_meta_lvb {
__u8 lvb_version; __u8 lvb_version;
__u8 lvb_reserved0; __u8 lvb_reserved0;
__be16 lvb_reserved1; __be16 lvb_idynfeatures;
__be32 lvb_iclusters; __be32 lvb_iclusters;
__be32 lvb_iuid; __be32 lvb_iuid;
__be32 lvb_igid; __be32 lvb_igid;

View 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_clusters = le32_to_cpu(fe->i_clusters);
OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr); 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_version = 1;
inode->i_generation = le32_to_cpu(fe->i_generation); 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); fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters);
ocfs2_get_inode_flags(OCFS2_I(inode)); ocfs2_get_inode_flags(OCFS2_I(inode));
fe->i_attr = cpu_to_le32(OCFS2_I(inode)->ip_attr); 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); spin_unlock(&OCFS2_I(inode)->ip_lock);
fe->i_size = cpu_to_le64(i_size_read(inode)); 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_clusters = le32_to_cpu(fe->i_clusters);
OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr); 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); ocfs2_set_inode_flags(inode);
i_size_write(inode, le64_to_cpu(fe->i_size)); i_size_write(inode, le64_to_cpu(fe->i_size));
inode->i_nlink = le16_to_cpu(fe->i_links_count); inode->i_nlink = le16_to_cpu(fe->i_links_count);

View File

@ -51,6 +51,7 @@ struct ocfs2_inode_info
u32 ip_flags; /* see below */ u32 ip_flags; /* see below */
u32 ip_attr; /* inode attributes */ u32 ip_attr; /* inode attributes */
u16 ip_dyn_features;
/* protected by recovery_lock. */ /* protected by recovery_lock. */
struct inode *ip_next_orphan; struct inode *ip_next_orphan;

View File

@ -319,6 +319,13 @@ static inline int ocfs2_writes_unwritten_extents(struct ocfs2_super *osb)
return 0; 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 /* set / clear functions because cluster events can make these happen
* in parallel so we want the transitions to be atomic. this also * in parallel so we want the transitions to be atomic. this also
* means that any future flags osb_flags must be protected by spinlock * means that any future flags osb_flags must be protected by spinlock

View File

@ -87,7 +87,8 @@
#define OCFS2_FEATURE_COMPAT_SUPP OCFS2_FEATURE_COMPAT_BACKUP_SB #define OCFS2_FEATURE_COMPAT_SUPP OCFS2_FEATURE_COMPAT_BACKUP_SB
#define OCFS2_FEATURE_INCOMPAT_SUPP (OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT \ #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_RO_COMPAT_SUPP OCFS2_FEATURE_RO_COMPAT_UNWRITTEN
/* /*
@ -121,6 +122,9 @@
*/ */
#define OCFS2_FEATURE_INCOMPAT_TUNEFS_INPROG 0x0020 #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 * backup superblock flag is used to indicate that this volume
* has backup superblocks. * has backup superblocks.
@ -162,6 +166,17 @@
#define OCFS2_CHAIN_FL (0x00000400) /* Chain allocator */ #define OCFS2_CHAIN_FL (0x00000400) /* Chain allocator */
#define OCFS2_DEALLOC_FL (0x00000800) /* Truncate log */ #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 */ /* Inode attributes, keep in sync with EXT2 */
#define OCFS2_SECRM_FL (0x00000001) /* Secure deletion */ #define OCFS2_SECRM_FL (0x00000001) /* Secure deletion */
#define OCFS2_UNRM_FL (0x00000002) /* Undelete */ #define OCFS2_UNRM_FL (0x00000002) /* Undelete */
@ -486,6 +501,19 @@ struct ocfs2_local_alloc
/*10*/ __u8 la_bitmap[0]; /*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 * On disk inode for OCFS2
*/ */
@ -518,7 +546,7 @@ struct ocfs2_dinode {
__le32 i_attr; __le32 i_attr;
__le16 i_orphaned_slot; /* Only valid when OCFS2_ORPHANED_FL __le16 i_orphaned_slot; /* Only valid when OCFS2_ORPHANED_FL
was set in i_flags */ was set in i_flags */
__le16 i_reserved1; __le16 i_dyn_features;
/*70*/ __le64 i_reserved2[8]; /*70*/ __le64 i_reserved2[8];
/*B8*/ union { /*B8*/ union {
__le64 i_pad1; /* Generic way to refer to this __le64 i_pad1; /* Generic way to refer to this
@ -544,6 +572,7 @@ struct ocfs2_dinode {
struct ocfs2_chain_list i_chain; struct ocfs2_chain_list i_chain;
struct ocfs2_extent_list i_list; struct ocfs2_extent_list i_list;
struct ocfs2_truncate_log i_dealloc; struct ocfs2_truncate_log i_dealloc;
struct ocfs2_inline_data i_data;
__u8 i_symlink[0]; __u8 i_symlink[0];
} id2; } id2;
/* Actual on-disk size is one block */ /* 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); 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) static inline int ocfs2_extent_recs_per_inode(struct super_block *sb)
{ {
int size; int size;
@ -672,6 +707,11 @@ static inline int ocfs2_fast_symlink_chars(int blocksize)
return blocksize - offsetof(struct ocfs2_dinode, id2.i_symlink); 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) static inline int ocfs2_extent_recs_per_inode(int blocksize)
{ {
int size; int size;