Commit 721f69c4 authored by Tao Ma's avatar Tao Ma Committed by Joel Becker
Browse files

ocfs2: Define refcount tree structure.



Signed-off-by: default avatarTao Ma <tao.ma@oracle.com>
parent 5e404e9e
Loading
Loading
Loading
Loading
+85 −3
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@
#define OCFS2_DIR_TRAILER_SIGNATURE	"DIRTRL1"
#define OCFS2_DX_ROOT_SIGNATURE		"DXDIR01"
#define OCFS2_DX_LEAF_SIGNATURE		"DXLEAF1"
#define OCFS2_REFCOUNT_BLOCK_SIGNATURE	"REFCNT1"

/* Compatibility flags */
#define OCFS2_HAS_COMPAT_FEATURE(sb,mask)			\
@@ -160,6 +161,9 @@
/* Metadata checksum and error correction */
#define OCFS2_FEATURE_INCOMPAT_META_ECC		0x0800

/* Refcount tree support */
#define OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE	0x1000

/*
 * backup superblock flag is used to indicate that this volume
 * has backup superblocks.
@@ -223,6 +227,7 @@
#define OCFS2_HAS_XATTR_FL	(0x0002)
#define OCFS2_INLINE_XATTR_FL	(0x0004)
#define OCFS2_INDEXED_DIR_FL	(0x0008)
#define OCFS2_HAS_REFCOUNT_FL   (0x0010)

/* Inode attributes, keep in sync with EXT2 */
#define OCFS2_SECRM_FL		(0x00000001)	/* Secure deletion */
@@ -243,6 +248,9 @@
 */
#define OCFS2_EXT_UNWRITTEN		(0x01)	/* Extent is allocated but
						 * unwritten */
#define OCFS2_EXT_REFCOUNTED		(0x02)  /* Extent is reference
						 * counted in an associated
						 * refcount tree */

/*
 * ioctl commands
@@ -717,7 +725,8 @@ struct ocfs2_dinode {
	__le64 i_xattr_loc;
/*80*/	struct ocfs2_block_check i_check;	/* Error checking */
/*88*/	__le64 i_dx_root;		/* Pointer to dir index root block */
	__le64 i_reserved2[5];
/*90*/	__le64 i_refcount_loc;
	__le64 i_reserved2[4];
/*B8*/	union {
		__le64 i_pad1;		/* Generic way to refer to this
					   64bit union */
@@ -901,6 +910,59 @@ struct ocfs2_group_desc
/*40*/	__u8    bg_bitmap[0];
};

struct ocfs2_refcount_rec {
/*00*/	__le64 r_cpos;		/* Physical offset, in clusters */
	__le32 r_clusters;	/* Clusters covered by this extent */
	__le32 r_refcount;	/* Reference count of this extent */
/*10*/
};

#define OCFS2_REFCOUNT_LEAF_FL          (0x00000001)
#define OCFS2_REFCOUNT_TREE_FL          (0x00000002)

struct ocfs2_refcount_list {
/*00*/	__le16 rl_count;	/* Maximum number of entries possible
				   in rl_records */
	__le16 rl_used;		/* Current number of used records */
	__le32 rl_reserved2;
	__le64 rl_reserved1;	/* Pad to sizeof(ocfs2_refcount_record) */
/*10*/	struct ocfs2_refcount_rec rl_recs[0];	/* Refcount records */
};


struct ocfs2_refcount_block {
/*00*/	__u8 rf_signature[8];		/* Signature for verification */
	__le16 rf_suballoc_slot;	/* Slot suballocator this block
					   belongs to */
	__le16 rf_suballoc_bit;		/* Bit offset in suballocator
					   block group */
	__le32 rf_fs_generation;	/* Must match superblock */
/*10*/	__le64 rf_blkno;		/* Offset on disk, in blocks */
	__le64 rf_parent;		/* Parent block, only valid if
					   OCFS2_REFCOUNT_LEAF_FL is set in
					   rf_flags */
/*20*/	struct ocfs2_block_check rf_check;	/* Error checking */
	__le64 rf_last_eb_blk;		/* Pointer to last extent block */
/*30*/	__le32 rf_count;		/* Number of inodes sharing this
					   refcount tree */
	__le32 rf_flags;		/* See the flags above */
	__le32 rf_clusters;		/* clusters covered by refcount tree. */
	__le32 rf_cpos;			/* cluster offset in refcount tree.*/
/*40*/	__le32 rf_generation;		/* generation number. all be the same
					 * for the same refcount tree. */
	__le32 rf_reserved0;
	__le64 rf_reserved1[7];
/*80*/	union {
		struct ocfs2_refcount_list rf_records;  /* List of refcount
							  records */
		struct ocfs2_extent_list rf_list;	/* Extent record list,
							only valid if
							OCFS2_REFCOUNT_TREE_FL
							is set in rf_flags */
	};
/* Actual on-disk size is one block */
};

/*
 * On disk extended attribute structure for OCFS2.
 */
@@ -1312,6 +1374,26 @@ static inline u16 ocfs2_xattr_recs_per_xb(struct super_block *sb)

	return size / sizeof(struct ocfs2_extent_rec);
}

static inline u16 ocfs2_extent_recs_per_rb(struct super_block *sb)
{
	int size;

	size = sb->s_blocksize -
		offsetof(struct ocfs2_refcount_block, rf_list.l_recs);

	return size / sizeof(struct ocfs2_extent_rec);
}

static inline u16 ocfs2_refcount_recs_per_rb(struct super_block *sb)
{
	int size;

	size = sb->s_blocksize -
		offsetof(struct ocfs2_refcount_block, rf_records.rl_recs);

	return size / sizeof(struct ocfs2_refcount_rec);
}
#else
static inline int ocfs2_fast_symlink_chars(int blocksize)
{