Merge branch 'discontig-bg' of git://oss.oracle.com/git/tma/linux-2.6 into ocfs2-merge-window
This commit is contained in:
commit
41841b0bce
|
@ -1006,7 +1006,7 @@ static int ocfs2_create_new_meta_bhs(handle_t *handle,
|
|||
int count, status, i;
|
||||
u16 suballoc_bit_start;
|
||||
u32 num_got;
|
||||
u64 first_blkno;
|
||||
u64 suballoc_loc, first_blkno;
|
||||
struct ocfs2_super *osb =
|
||||
OCFS2_SB(ocfs2_metadata_cache_get_super(et->et_ci));
|
||||
struct ocfs2_extent_block *eb;
|
||||
|
@ -1015,10 +1015,10 @@ static int ocfs2_create_new_meta_bhs(handle_t *handle,
|
|||
|
||||
count = 0;
|
||||
while (count < wanted) {
|
||||
status = ocfs2_claim_metadata(osb,
|
||||
handle,
|
||||
status = ocfs2_claim_metadata(handle,
|
||||
meta_ac,
|
||||
wanted - count,
|
||||
&suballoc_loc,
|
||||
&suballoc_bit_start,
|
||||
&num_got,
|
||||
&first_blkno);
|
||||
|
@ -1052,6 +1052,7 @@ static int ocfs2_create_new_meta_bhs(handle_t *handle,
|
|||
eb->h_fs_generation = cpu_to_le32(osb->fs_generation);
|
||||
eb->h_suballoc_slot =
|
||||
cpu_to_le16(meta_ac->ac_alloc_slot);
|
||||
eb->h_suballoc_loc = cpu_to_le64(suballoc_loc);
|
||||
eb->h_suballoc_bit = cpu_to_le16(suballoc_bit_start);
|
||||
eb->h_list.l_count =
|
||||
cpu_to_le16(ocfs2_extent_recs_per_eb(osb->sb));
|
||||
|
@ -4786,7 +4787,7 @@ int ocfs2_add_clusters_in_btree(handle_t *handle,
|
|||
goto leave;
|
||||
}
|
||||
|
||||
status = __ocfs2_claim_clusters(osb, handle, data_ac, 1,
|
||||
status = __ocfs2_claim_clusters(handle, data_ac, 1,
|
||||
clusters_to_add, &bit_off, &num_bits);
|
||||
if (status < 0) {
|
||||
if (status != -ENOSPC)
|
||||
|
@ -6295,6 +6296,7 @@ int ocfs2_truncate_log_init(struct ocfs2_super *osb)
|
|||
*/
|
||||
struct ocfs2_cached_block_free {
|
||||
struct ocfs2_cached_block_free *free_next;
|
||||
u64 free_bg;
|
||||
u64 free_blk;
|
||||
unsigned int free_bit;
|
||||
};
|
||||
|
@ -6341,8 +6343,11 @@ static int ocfs2_free_cached_blocks(struct ocfs2_super *osb,
|
|||
}
|
||||
|
||||
while (head) {
|
||||
bg_blkno = ocfs2_which_suballoc_group(head->free_blk,
|
||||
head->free_bit);
|
||||
if (head->free_bg)
|
||||
bg_blkno = head->free_bg;
|
||||
else
|
||||
bg_blkno = ocfs2_which_suballoc_group(head->free_blk,
|
||||
head->free_bit);
|
||||
mlog(0, "Free bit: (bit %u, blkno %llu)\n",
|
||||
head->free_bit, (unsigned long long)head->free_blk);
|
||||
|
||||
|
@ -6390,7 +6395,7 @@ int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
|
|||
int ret = 0;
|
||||
struct ocfs2_cached_block_free *item;
|
||||
|
||||
item = kmalloc(sizeof(*item), GFP_NOFS);
|
||||
item = kzalloc(sizeof(*item), GFP_NOFS);
|
||||
if (item == NULL) {
|
||||
ret = -ENOMEM;
|
||||
mlog_errno(ret);
|
||||
|
@ -6530,8 +6535,8 @@ ocfs2_find_per_slot_free_list(int type,
|
|||
}
|
||||
|
||||
int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
|
||||
int type, int slot, u64 blkno,
|
||||
unsigned int bit)
|
||||
int type, int slot, u64 suballoc,
|
||||
u64 blkno, unsigned int bit)
|
||||
{
|
||||
int ret;
|
||||
struct ocfs2_per_slot_free_list *fl;
|
||||
|
@ -6544,7 +6549,7 @@ int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
|
|||
goto out;
|
||||
}
|
||||
|
||||
item = kmalloc(sizeof(*item), GFP_NOFS);
|
||||
item = kzalloc(sizeof(*item), GFP_NOFS);
|
||||
if (item == NULL) {
|
||||
ret = -ENOMEM;
|
||||
mlog_errno(ret);
|
||||
|
@ -6554,6 +6559,7 @@ int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
|
|||
mlog(0, "Insert: (type %d, slot %u, bit %u, blk %llu)\n",
|
||||
type, slot, bit, (unsigned long long)blkno);
|
||||
|
||||
item->free_bg = suballoc;
|
||||
item->free_blk = blkno;
|
||||
item->free_bit = bit;
|
||||
item->free_next = fl->f_first;
|
||||
|
@ -6570,6 +6576,7 @@ static int ocfs2_cache_extent_block_free(struct ocfs2_cached_dealloc_ctxt *ctxt,
|
|||
{
|
||||
return ocfs2_cache_block_dealloc(ctxt, EXTENT_ALLOC_SYSTEM_INODE,
|
||||
le16_to_cpu(eb->h_suballoc_slot),
|
||||
le64_to_cpu(eb->h_suballoc_loc),
|
||||
le64_to_cpu(eb->h_blkno),
|
||||
le16_to_cpu(eb->h_suballoc_bit));
|
||||
}
|
||||
|
@ -6883,7 +6890,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode,
|
|||
|
||||
data_ac->ac_resv = &OCFS2_I(inode)->ip_la_data_resv;
|
||||
|
||||
ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off,
|
||||
ret = ocfs2_claim_clusters(handle, data_ac, 1, &bit_off,
|
||||
&num);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
|
|
|
@ -210,7 +210,7 @@ static inline void ocfs2_init_dealloc_ctxt(struct ocfs2_cached_dealloc_ctxt *c)
|
|||
int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
|
||||
u64 blkno, unsigned int bit);
|
||||
int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
|
||||
int type, int slot, u64 blkno,
|
||||
int type, int slot, u64 suballoc, u64 blkno,
|
||||
unsigned int bit);
|
||||
static inline int ocfs2_dealloc_has_cluster(struct ocfs2_cached_dealloc_ctxt *c)
|
||||
{
|
||||
|
|
|
@ -2395,15 +2395,15 @@ static int ocfs2_dx_dir_attach_index(struct ocfs2_super *osb,
|
|||
int ret;
|
||||
struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
|
||||
u16 dr_suballoc_bit;
|
||||
u64 dr_blkno;
|
||||
u64 suballoc_loc, dr_blkno;
|
||||
unsigned int num_bits;
|
||||
struct buffer_head *dx_root_bh = NULL;
|
||||
struct ocfs2_dx_root_block *dx_root;
|
||||
struct ocfs2_dir_block_trailer *trailer =
|
||||
ocfs2_trailer_from_bh(dirdata_bh, dir->i_sb);
|
||||
|
||||
ret = ocfs2_claim_metadata(osb, handle, meta_ac, 1, &dr_suballoc_bit,
|
||||
&num_bits, &dr_blkno);
|
||||
ret = ocfs2_claim_metadata(handle, meta_ac, 1, &suballoc_loc,
|
||||
&dr_suballoc_bit, &num_bits, &dr_blkno);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
goto out;
|
||||
|
@ -2431,6 +2431,7 @@ static int ocfs2_dx_dir_attach_index(struct ocfs2_super *osb,
|
|||
memset(dx_root, 0, osb->sb->s_blocksize);
|
||||
strcpy(dx_root->dr_signature, OCFS2_DX_ROOT_SIGNATURE);
|
||||
dx_root->dr_suballoc_slot = cpu_to_le16(meta_ac->ac_alloc_slot);
|
||||
dx_root->dr_suballoc_loc = cpu_to_le64(suballoc_loc);
|
||||
dx_root->dr_suballoc_bit = cpu_to_le16(dr_suballoc_bit);
|
||||
dx_root->dr_fs_generation = cpu_to_le32(osb->fs_generation);
|
||||
dx_root->dr_blkno = cpu_to_le64(dr_blkno);
|
||||
|
@ -2544,7 +2545,7 @@ static int __ocfs2_dx_dir_new_cluster(struct inode *dir,
|
|||
* chance of contiguousness as the directory grows in number
|
||||
* of entries.
|
||||
*/
|
||||
ret = __ocfs2_claim_clusters(osb, handle, data_ac, 1, 1, &phys, &num);
|
||||
ret = __ocfs2_claim_clusters(handle, data_ac, 1, 1, &phys, &num);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
goto out;
|
||||
|
@ -2979,7 +2980,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
|
|||
*/
|
||||
if (ocfs2_dir_resv_allowed(osb))
|
||||
data_ac->ac_resv = &oi->ip_la_data_resv;
|
||||
ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off, &len);
|
||||
ret = ocfs2_claim_clusters(handle, data_ac, 1, &bit_off, &len);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
goto out_commit;
|
||||
|
@ -3118,7 +3119,7 @@ static int ocfs2_expand_inline_dir(struct inode *dir, struct buffer_head *di_bh,
|
|||
* pass. Claim the 2nd cluster as a separate extent.
|
||||
*/
|
||||
if (alloc > len) {
|
||||
ret = ocfs2_claim_clusters(osb, handle, data_ac, 1, &bit_off,
|
||||
ret = ocfs2_claim_clusters(handle, data_ac, 1, &bit_off,
|
||||
&len);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
|
@ -4465,7 +4466,10 @@ static int ocfs2_dx_dir_remove_index(struct inode *dir,
|
|||
|
||||
blk = le64_to_cpu(dx_root->dr_blkno);
|
||||
bit = le16_to_cpu(dx_root->dr_suballoc_bit);
|
||||
bg_blkno = ocfs2_which_suballoc_group(blk, bit);
|
||||
if (dx_root->dr_suballoc_loc)
|
||||
bg_blkno = le64_to_cpu(dx_root->dr_suballoc_loc);
|
||||
else
|
||||
bg_blkno = ocfs2_which_suballoc_group(blk, bit);
|
||||
ret = ocfs2_free_suballoc_bits(handle, dx_alloc_inode, dx_alloc_bh,
|
||||
bit, bg_blkno, 1);
|
||||
if (ret)
|
||||
|
|
|
@ -561,6 +561,18 @@ static inline int ocfs2_calc_group_alloc_credits(struct super_block *sb,
|
|||
return blocks;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocating a discontiguous block group requires the credits from
|
||||
* ocfs2_calc_group_alloc_credits() as well as enough credits to fill
|
||||
* the group descriptor's extent list. The caller already has started
|
||||
* the transaction with ocfs2_calc_group_alloc_credits(). They extend
|
||||
* it with these credits.
|
||||
*/
|
||||
static inline int ocfs2_calc_bg_discontig_credits(struct super_block *sb)
|
||||
{
|
||||
return ocfs2_extent_recs_per_gd(sb);
|
||||
}
|
||||
|
||||
static inline int ocfs2_calc_tree_trunc_credits(struct super_block *sb,
|
||||
unsigned int clusters_to_del,
|
||||
struct ocfs2_dinode *fe,
|
||||
|
|
|
@ -122,7 +122,7 @@ unsigned int ocfs2_la_default_mb(struct ocfs2_super *osb)
|
|||
struct super_block *sb = osb->sb;
|
||||
|
||||
gd_mb = ocfs2_clusters_to_megabytes(osb->sb,
|
||||
8 * ocfs2_group_bitmap_size(sb));
|
||||
8 * ocfs2_group_bitmap_size(sb, 0, osb->s_feature_incompat));
|
||||
|
||||
/*
|
||||
* This takes care of files systems with very small group
|
||||
|
@ -1161,7 +1161,7 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb,
|
|||
/* we used the generic suballoc reserve function, but we set
|
||||
* everything up nicely, so there's no reason why we can't use
|
||||
* the more specific cluster api to claim bits. */
|
||||
status = ocfs2_claim_clusters(osb, handle, ac, osb->local_alloc_bits,
|
||||
status = ocfs2_claim_clusters(handle, ac, osb->local_alloc_bits,
|
||||
&cluster_off, &cluster_count);
|
||||
if (status == -ENOSPC) {
|
||||
retry_enospc:
|
||||
|
@ -1175,7 +1175,7 @@ retry_enospc:
|
|||
goto bail;
|
||||
|
||||
ac->ac_bits_wanted = osb->local_alloc_default_bits;
|
||||
status = ocfs2_claim_clusters(osb, handle, ac,
|
||||
status = ocfs2_claim_clusters(handle, ac,
|
||||
osb->local_alloc_bits,
|
||||
&cluster_off,
|
||||
&cluster_count);
|
||||
|
|
|
@ -480,14 +480,15 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
|
|||
int status = 0;
|
||||
struct ocfs2_dinode *fe = NULL;
|
||||
struct ocfs2_extent_list *fel;
|
||||
u64 fe_blkno = 0;
|
||||
u64 suballoc_loc, fe_blkno = 0;
|
||||
u16 suballoc_bit;
|
||||
u16 feat;
|
||||
|
||||
*new_fe_bh = NULL;
|
||||
|
||||
status = ocfs2_claim_new_inode(osb, handle, dir, parent_fe_bh,
|
||||
inode_ac, &suballoc_bit, &fe_blkno);
|
||||
status = ocfs2_claim_new_inode(handle, dir, parent_fe_bh,
|
||||
inode_ac, &suballoc_loc,
|
||||
&suballoc_bit, &fe_blkno);
|
||||
if (status < 0) {
|
||||
mlog_errno(status);
|
||||
goto leave;
|
||||
|
@ -524,6 +525,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
|
|||
fe->i_generation = cpu_to_le32(inode->i_generation);
|
||||
fe->i_fs_generation = cpu_to_le32(osb->fs_generation);
|
||||
fe->i_blkno = cpu_to_le64(fe_blkno);
|
||||
fe->i_suballoc_loc = cpu_to_le64(suballoc_loc);
|
||||
fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
|
||||
fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
|
||||
fe->i_uid = cpu_to_le32(inode->i_uid);
|
||||
|
|
|
@ -491,6 +491,13 @@ static inline int ocfs2_supports_indexed_dirs(struct ocfs2_super *osb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int ocfs2_supports_discontig_bg(struct ocfs2_super *osb)
|
||||
{
|
||||
if (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned int ocfs2_link_max(struct ocfs2_super *osb)
|
||||
{
|
||||
if (ocfs2_supports_indexed_dirs(osb))
|
||||
|
|
|
@ -100,7 +100,8 @@
|
|||
| OCFS2_FEATURE_INCOMPAT_XATTR \
|
||||
| OCFS2_FEATURE_INCOMPAT_META_ECC \
|
||||
| OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS \
|
||||
| OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE)
|
||||
| OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE \
|
||||
| OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG)
|
||||
#define OCFS2_FEATURE_RO_COMPAT_SUPP (OCFS2_FEATURE_RO_COMPAT_UNWRITTEN \
|
||||
| OCFS2_FEATURE_RO_COMPAT_USRQUOTA \
|
||||
| OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)
|
||||
|
@ -165,6 +166,9 @@
|
|||
/* Refcount tree support */
|
||||
#define OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE 0x1000
|
||||
|
||||
/* Discontigous block groups */
|
||||
#define OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG 0x2000
|
||||
|
||||
/*
|
||||
* backup superblock flag is used to indicate that this volume
|
||||
* has backup superblocks.
|
||||
|
@ -504,7 +508,10 @@ struct ocfs2_extent_block
|
|||
block group */
|
||||
__le32 h_fs_generation; /* Must match super block */
|
||||
__le64 h_blkno; /* Offset on disk, in blocks */
|
||||
/*20*/ __le64 h_reserved3;
|
||||
/*20*/ __le64 h_suballoc_loc; /* Suballocator block group this
|
||||
eb belongs to. Only valid
|
||||
if allocated from a
|
||||
discontiguous block group */
|
||||
__le64 h_next_leaf_blk; /* Offset on disk, in blocks,
|
||||
of next leaf header pointing
|
||||
to data */
|
||||
|
@ -671,7 +678,11 @@ struct ocfs2_dinode {
|
|||
/*80*/ struct ocfs2_block_check i_check; /* Error checking */
|
||||
/*88*/ __le64 i_dx_root; /* Pointer to dir index root block */
|
||||
/*90*/ __le64 i_refcount_loc;
|
||||
__le64 i_reserved2[4];
|
||||
__le64 i_suballoc_loc; /* Suballocator block group this
|
||||
inode belongs to. Only valid
|
||||
if allocated from a
|
||||
discontiguous block group */
|
||||
/*A0*/ __le64 i_reserved2[3];
|
||||
/*B8*/ union {
|
||||
__le64 i_pad1; /* Generic way to refer to this
|
||||
64bit union */
|
||||
|
@ -806,7 +817,12 @@ struct ocfs2_dx_root_block {
|
|||
__le32 dr_reserved2;
|
||||
__le64 dr_free_blk; /* Pointer to head of free
|
||||
* unindexed block list. */
|
||||
__le64 dr_reserved3[15];
|
||||
__le64 dr_suballoc_loc; /* Suballocator block group
|
||||
this root belongs to.
|
||||
Only valid if allocated
|
||||
from a discontiguous
|
||||
block group */
|
||||
__le64 dr_reserved3[14];
|
||||
union {
|
||||
struct ocfs2_extent_list dr_list; /* Keep this aligned to 128
|
||||
* bits for maximum space
|
||||
|
@ -831,6 +847,13 @@ struct ocfs2_dx_leaf {
|
|||
struct ocfs2_dx_entry_list dl_list;
|
||||
};
|
||||
|
||||
/*
|
||||
* Largest bitmap for a block (suballocator) group in bytes. This limit
|
||||
* does not affect cluster groups (global allocator). Cluster group
|
||||
* bitmaps run to the end of the block.
|
||||
*/
|
||||
#define OCFS2_MAX_BG_BITMAP_SIZE 256
|
||||
|
||||
/*
|
||||
* On disk allocator group structure for OCFS2
|
||||
*/
|
||||
|
@ -852,7 +875,29 @@ struct ocfs2_group_desc
|
|||
__le64 bg_blkno; /* Offset on disk, in blocks */
|
||||
/*30*/ struct ocfs2_block_check bg_check; /* Error checking */
|
||||
__le64 bg_reserved2;
|
||||
/*40*/ __u8 bg_bitmap[0];
|
||||
/*40*/ union {
|
||||
__u8 bg_bitmap[0];
|
||||
struct {
|
||||
/*
|
||||
* Block groups may be discontiguous when
|
||||
* OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG is set.
|
||||
* The extents of a discontigous block group are
|
||||
* stored in bg_list. It is a flat list.
|
||||
* l_tree_depth must always be zero. A
|
||||
* discontiguous group is signified by a non-zero
|
||||
* bg_list->l_next_free_rec. Only block groups
|
||||
* can be discontiguous; Cluster groups cannot.
|
||||
* We've never made a block group with more than
|
||||
* 2048 blocks (256 bytes of bg_bitmap). This
|
||||
* codifies that limit so that we can fit bg_list.
|
||||
* bg_size of a discontiguous block group will
|
||||
* be 256 to match bg_bitmap_filler.
|
||||
*/
|
||||
__u8 bg_bitmap_filler[OCFS2_MAX_BG_BITMAP_SIZE];
|
||||
/*140*/ struct ocfs2_extent_list bg_list;
|
||||
};
|
||||
};
|
||||
/* Actual on-disk size is one block */
|
||||
};
|
||||
|
||||
struct ocfs2_refcount_rec {
|
||||
|
@ -897,7 +942,11 @@ struct ocfs2_refcount_block {
|
|||
/*40*/ __le32 rf_generation; /* generation number. all be the same
|
||||
* for the same refcount tree. */
|
||||
__le32 rf_reserved0;
|
||||
__le64 rf_reserved1[7];
|
||||
__le64 rf_suballoc_loc; /* Suballocator block group this
|
||||
refcount block belongs to. Only
|
||||
valid if allocated from a
|
||||
discontiguous block group */
|
||||
/*50*/ __le64 rf_reserved1[6];
|
||||
/*80*/ union {
|
||||
struct ocfs2_refcount_list rf_records; /* List of refcount
|
||||
records */
|
||||
|
@ -1009,7 +1058,10 @@ struct ocfs2_xattr_block {
|
|||
real xattr or a xattr tree. */
|
||||
__le16 xb_reserved0;
|
||||
__le32 xb_reserved1;
|
||||
__le64 xb_reserved2;
|
||||
__le64 xb_suballoc_loc; /* Suballocator block group this
|
||||
xattr block belongs to. Only
|
||||
valid if allocated from a
|
||||
discontiguous block group */
|
||||
/*30*/ union {
|
||||
struct ocfs2_xattr_header xb_header; /* xattr header if this
|
||||
block contains xattr */
|
||||
|
@ -1246,6 +1298,16 @@ static inline u16 ocfs2_extent_recs_per_eb(struct super_block *sb)
|
|||
return size / sizeof(struct ocfs2_extent_rec);
|
||||
}
|
||||
|
||||
static inline u16 ocfs2_extent_recs_per_gd(struct super_block *sb)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = sb->s_blocksize -
|
||||
offsetof(struct ocfs2_group_desc, bg_list.l_recs);
|
||||
|
||||
return size / sizeof(struct ocfs2_extent_rec);
|
||||
}
|
||||
|
||||
static inline int ocfs2_dx_entries_per_leaf(struct super_block *sb)
|
||||
{
|
||||
int size;
|
||||
|
@ -1276,13 +1338,23 @@ static inline u16 ocfs2_local_alloc_size(struct super_block *sb)
|
|||
return size;
|
||||
}
|
||||
|
||||
static inline int ocfs2_group_bitmap_size(struct super_block *sb)
|
||||
static inline int ocfs2_group_bitmap_size(struct super_block *sb,
|
||||
int suballocator,
|
||||
u32 feature_incompat)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = sb->s_blocksize -
|
||||
int size = sb->s_blocksize -
|
||||
offsetof(struct ocfs2_group_desc, bg_bitmap);
|
||||
|
||||
/*
|
||||
* The cluster allocator uses the entire block. Suballocators have
|
||||
* never used more than OCFS2_MAX_BG_BITMAP_SIZE. Unfortunately, older
|
||||
* code expects bg_size set to the maximum. Thus we must keep
|
||||
* bg_size as-is unless discontig_bg is enabled.
|
||||
*/
|
||||
if (suballocator &&
|
||||
(feature_incompat & OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG))
|
||||
size = OCFS2_MAX_BG_BITMAP_SIZE;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -1394,6 +1466,16 @@ static inline int ocfs2_extent_recs_per_eb(int blocksize)
|
|||
return size / sizeof(struct ocfs2_extent_rec);
|
||||
}
|
||||
|
||||
static inline int ocfs2_extent_recs_per_gd(int blocksize)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = blocksize -
|
||||
offsetof(struct ocfs2_group_desc, bg_list.l_recs);
|
||||
|
||||
return size / sizeof(struct ocfs2_extent_rec);
|
||||
}
|
||||
|
||||
static inline int ocfs2_local_alloc_size(int blocksize)
|
||||
{
|
||||
int size;
|
||||
|
@ -1404,13 +1486,23 @@ static inline int ocfs2_local_alloc_size(int blocksize)
|
|||
return size;
|
||||
}
|
||||
|
||||
static inline int ocfs2_group_bitmap_size(int blocksize)
|
||||
static inline int ocfs2_group_bitmap_size(int blocksize,
|
||||
int suballocator,
|
||||
uint32_t feature_incompat)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = blocksize -
|
||||
int size = sb->s_blocksize -
|
||||
offsetof(struct ocfs2_group_desc, bg_bitmap);
|
||||
|
||||
/*
|
||||
* The cluster allocator uses the entire block. Suballocators have
|
||||
* never used more than OCFS2_MAX_BG_BITMAP_SIZE. Unfortunately, older
|
||||
* code expects bg_size set to the maximum. Thus we must keep
|
||||
* bg_size as-is unless discontig_bg is enabled.
|
||||
*/
|
||||
if (suballocator &&
|
||||
(feature_incompat & OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG))
|
||||
size = OCFS2_MAX_BG_BITMAP_SIZE;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -1483,5 +1575,19 @@ static inline void ocfs2_set_de_type(struct ocfs2_dir_entry *de,
|
|||
de->file_type = ocfs2_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
|
||||
}
|
||||
|
||||
static inline int ocfs2_gd_is_discontig(struct ocfs2_group_desc *gd)
|
||||
{
|
||||
if ((offsetof(struct ocfs2_group_desc, bg_bitmap) +
|
||||
le16_to_cpu(gd->bg_size)) !=
|
||||
offsetof(struct ocfs2_group_desc, bg_list))
|
||||
return 0;
|
||||
/*
|
||||
* Only valid to check l_next_free_rec if
|
||||
* bg_bitmap + bg_size == bg_list.
|
||||
*/
|
||||
if (!gd->bg_list.l_next_free_rec)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
#endif /* _OCFS2_FS_H */
|
||||
|
||||
|
|
|
@ -571,7 +571,7 @@ static int ocfs2_create_refcount_tree(struct inode *inode,
|
|||
struct ocfs2_refcount_tree *new_tree = NULL, *tree = NULL;
|
||||
u16 suballoc_bit_start;
|
||||
u32 num_got;
|
||||
u64 first_blkno;
|
||||
u64 suballoc_loc, first_blkno;
|
||||
|
||||
BUG_ON(oi->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL);
|
||||
|
||||
|
@ -597,7 +597,7 @@ static int ocfs2_create_refcount_tree(struct inode *inode,
|
|||
goto out_commit;
|
||||
}
|
||||
|
||||
ret = ocfs2_claim_metadata(osb, handle, meta_ac, 1,
|
||||
ret = ocfs2_claim_metadata(handle, meta_ac, 1, &suballoc_loc,
|
||||
&suballoc_bit_start, &num_got,
|
||||
&first_blkno);
|
||||
if (ret) {
|
||||
|
@ -627,6 +627,7 @@ static int ocfs2_create_refcount_tree(struct inode *inode,
|
|||
memset(rb, 0, inode->i_sb->s_blocksize);
|
||||
strcpy((void *)rb, OCFS2_REFCOUNT_BLOCK_SIGNATURE);
|
||||
rb->rf_suballoc_slot = cpu_to_le16(meta_ac->ac_alloc_slot);
|
||||
rb->rf_suballoc_loc = cpu_to_le64(suballoc_loc);
|
||||
rb->rf_suballoc_bit = cpu_to_le16(suballoc_bit_start);
|
||||
rb->rf_fs_generation = cpu_to_le32(osb->fs_generation);
|
||||
rb->rf_blkno = cpu_to_le64(first_blkno);
|
||||
|
@ -791,7 +792,10 @@ int ocfs2_remove_refcount_tree(struct inode *inode, struct buffer_head *di_bh)
|
|||
if (le32_to_cpu(rb->rf_count) == 1) {
|
||||
blk = le64_to_cpu(rb->rf_blkno);
|
||||
bit = le16_to_cpu(rb->rf_suballoc_bit);
|
||||
bg_blkno = ocfs2_which_suballoc_group(blk, bit);
|
||||
if (rb->rf_suballoc_loc)
|
||||
bg_blkno = le64_to_cpu(rb->rf_suballoc_loc);
|
||||
else
|
||||
bg_blkno = ocfs2_which_suballoc_group(blk, bit);
|
||||
|
||||
alloc_inode = ocfs2_get_system_file_inode(osb,
|
||||
EXTENT_ALLOC_SYSTEM_INODE,
|
||||
|
@ -1283,7 +1287,7 @@ static int ocfs2_expand_inline_ref_root(handle_t *handle,
|
|||
int ret;
|
||||
u16 suballoc_bit_start;
|
||||
u32 num_got;
|
||||
u64 blkno;
|
||||
u64 suballoc_loc, blkno;
|
||||
struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
|
||||
struct buffer_head *new_bh = NULL;
|
||||
struct ocfs2_refcount_block *new_rb;
|
||||
|
@ -1297,7 +1301,7 @@ static int ocfs2_expand_inline_ref_root(handle_t *handle,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = ocfs2_claim_metadata(OCFS2_SB(sb), handle, meta_ac, 1,
|
||||
ret = ocfs2_claim_metadata(handle, meta_ac, 1, &suballoc_loc,
|
||||
&suballoc_bit_start, &num_got,
|
||||
&blkno);
|
||||
if (ret) {
|
||||
|
@ -1329,6 +1333,7 @@ static int ocfs2_expand_inline_ref_root(handle_t *handle,
|
|||
|
||||
new_rb = (struct ocfs2_refcount_block *)new_bh->b_data;
|
||||
new_rb->rf_suballoc_slot = cpu_to_le16(meta_ac->ac_alloc_slot);
|
||||
new_rb->rf_suballoc_loc = cpu_to_le64(suballoc_loc);
|
||||
new_rb->rf_suballoc_bit = cpu_to_le16(suballoc_bit_start);
|
||||
new_rb->rf_blkno = cpu_to_le64(blkno);
|
||||
new_rb->rf_cpos = cpu_to_le32(0);
|
||||
|
@ -1523,7 +1528,7 @@ static int ocfs2_new_leaf_refcount_block(handle_t *handle,
|
|||
int ret;
|
||||
u16 suballoc_bit_start;
|
||||
u32 num_got, new_cpos;
|
||||
u64 blkno;
|
||||
u64 suballoc_loc, blkno;
|
||||
struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
|
||||
struct ocfs2_refcount_block *root_rb =
|
||||
(struct ocfs2_refcount_block *)ref_root_bh->b_data;
|
||||
|
@ -1547,7 +1552,7 @@ static int ocfs2_new_leaf_refcount_block(handle_t *handle,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = ocfs2_claim_metadata(OCFS2_SB(sb), handle, meta_ac, 1,
|
||||
ret = ocfs2_claim_metadata(handle, meta_ac, 1, &suballoc_loc,
|
||||
&suballoc_bit_start, &num_got,
|
||||
&blkno);
|
||||
if (ret) {
|
||||
|
@ -1575,6 +1580,7 @@ static int ocfs2_new_leaf_refcount_block(handle_t *handle,
|
|||
memset(new_rb, 0, sb->s_blocksize);
|
||||
strcpy((void *)new_rb, OCFS2_REFCOUNT_BLOCK_SIGNATURE);
|
||||
new_rb->rf_suballoc_slot = cpu_to_le16(meta_ac->ac_alloc_slot);
|
||||
new_rb->rf_suballoc_loc = cpu_to_le64(suballoc_loc);
|
||||
new_rb->rf_suballoc_bit = cpu_to_le16(suballoc_bit_start);
|
||||
new_rb->rf_fs_generation = cpu_to_le32(OCFS2_SB(sb)->fs_generation);
|
||||
new_rb->rf_blkno = cpu_to_le64(blkno);
|
||||
|
@ -2105,6 +2111,7 @@ static int ocfs2_remove_refcount_extent(handle_t *handle,
|
|||
*/
|
||||
ret = ocfs2_cache_block_dealloc(dealloc, EXTENT_ALLOC_SYSTEM_INODE,
|
||||
le16_to_cpu(rb->rf_suballoc_slot),
|
||||
le64_to_cpu(rb->rf_suballoc_loc),
|
||||
le64_to_cpu(rb->rf_blkno),
|
||||
le16_to_cpu(rb->rf_suballoc_bit));
|
||||
if (ret) {
|
||||
|
@ -3262,7 +3269,7 @@ static int ocfs2_make_clusters_writable(struct super_block *sb,
|
|||
} else {
|
||||
delete = 1;
|
||||
|
||||
ret = __ocfs2_claim_clusters(osb, handle,
|
||||
ret = __ocfs2_claim_clusters(handle,
|
||||
context->data_ac,
|
||||
1, set_len,
|
||||
&new_bit, &new_len);
|
||||
|
|
|
@ -315,7 +315,8 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters)
|
|||
BUG_ON(!OCFS2_IS_VALID_DINODE(fe));
|
||||
|
||||
if (le16_to_cpu(fe->id2.i_chain.cl_cpg) !=
|
||||
ocfs2_group_bitmap_size(osb->sb) * 8) {
|
||||
ocfs2_group_bitmap_size(osb->sb, 0,
|
||||
osb->s_feature_incompat) * 8) {
|
||||
mlog(ML_ERROR, "The disk is too old and small. "
|
||||
"Force to do offline resize.");
|
||||
ret = -EINVAL;
|
||||
|
@ -496,7 +497,8 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input)
|
|||
fe = (struct ocfs2_dinode *)main_bm_bh->b_data;
|
||||
|
||||
if (le16_to_cpu(fe->id2.i_chain.cl_cpg) !=
|
||||
ocfs2_group_bitmap_size(osb->sb) * 8) {
|
||||
ocfs2_group_bitmap_size(osb->sb, 0,
|
||||
osb->s_feature_incompat) * 8) {
|
||||
mlog(ML_ERROR, "The disk is too old and small."
|
||||
" Force to do offline resize.");
|
||||
ret = -EINVAL;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,13 +26,14 @@
|
|||
#ifndef _CHAINALLOC_H_
|
||||
#define _CHAINALLOC_H_
|
||||
|
||||
struct ocfs2_suballoc_result;
|
||||
typedef int (group_search_t)(struct inode *,
|
||||
struct buffer_head *,
|
||||
u32, /* bits_wanted */
|
||||
u32, /* min_bits */
|
||||
u64, /* max_block */
|
||||
u16 *, /* *bit_off */
|
||||
u16 *); /* *bits_found */
|
||||
struct ocfs2_suballoc_result *);
|
||||
/* found bits */
|
||||
|
||||
struct ocfs2_alloc_context {
|
||||
struct inode *ac_inode; /* which bitmap are we allocating from? */
|
||||
|
@ -82,22 +83,21 @@ int ocfs2_reserve_clusters(struct ocfs2_super *osb,
|
|||
u32 bits_wanted,
|
||||
struct ocfs2_alloc_context **ac);
|
||||
|
||||
int ocfs2_claim_metadata(struct ocfs2_super *osb,
|
||||
handle_t *handle,
|
||||
int ocfs2_claim_metadata(handle_t *handle,
|
||||
struct ocfs2_alloc_context *ac,
|
||||
u32 bits_wanted,
|
||||
u64 *suballoc_loc,
|
||||
u16 *suballoc_bit_start,
|
||||
u32 *num_bits,
|
||||
u64 *blkno_start);
|
||||
int ocfs2_claim_new_inode(struct ocfs2_super *osb,
|
||||
handle_t *handle,
|
||||
int ocfs2_claim_new_inode(handle_t *handle,
|
||||
struct inode *dir,
|
||||
struct buffer_head *parent_fe_bh,
|
||||
struct ocfs2_alloc_context *ac,
|
||||
u64 *suballoc_loc,
|
||||
u16 *suballoc_bit,
|
||||
u64 *fe_blkno);
|
||||
int ocfs2_claim_clusters(struct ocfs2_super *osb,
|
||||
handle_t *handle,
|
||||
int ocfs2_claim_clusters(handle_t *handle,
|
||||
struct ocfs2_alloc_context *ac,
|
||||
u32 min_clusters,
|
||||
u32 *cluster_start,
|
||||
|
@ -106,8 +106,7 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb,
|
|||
* Use this variant of ocfs2_claim_clusters to specify a maxiumum
|
||||
* number of clusters smaller than the allocation reserved.
|
||||
*/
|
||||
int __ocfs2_claim_clusters(struct ocfs2_super *osb,
|
||||
handle_t *handle,
|
||||
int __ocfs2_claim_clusters(handle_t *handle,
|
||||
struct ocfs2_alloc_context *ac,
|
||||
u32 min_clusters,
|
||||
u32 max_clusters,
|
||||
|
|
|
@ -2277,7 +2277,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
|
|||
osb->osb_clusters_at_boot = OCFS2_I(inode)->ip_clusters;
|
||||
iput(inode);
|
||||
|
||||
osb->bitmap_cpg = ocfs2_group_bitmap_size(sb) * 8;
|
||||
osb->bitmap_cpg = ocfs2_group_bitmap_size(sb, 0,
|
||||
osb->s_feature_incompat) * 8;
|
||||
|
||||
status = ocfs2_init_slot_info(osb);
|
||||
if (status < 0) {
|
||||
|
|
|
@ -2466,7 +2466,10 @@ static int ocfs2_xattr_free_block(struct inode *inode,
|
|||
xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
|
||||
blk = le64_to_cpu(xb->xb_blkno);
|
||||
bit = le16_to_cpu(xb->xb_suballoc_bit);
|
||||
bg_blkno = ocfs2_which_suballoc_group(blk, bit);
|
||||
if (xb->xb_suballoc_loc)
|
||||
bg_blkno = le64_to_cpu(xb->xb_suballoc_loc);
|
||||
else
|
||||
bg_blkno = ocfs2_which_suballoc_group(blk, bit);
|
||||
|
||||
xb_alloc_inode = ocfs2_get_system_file_inode(osb,
|
||||
EXTENT_ALLOC_SYSTEM_INODE,
|
||||
|
@ -2829,9 +2832,8 @@ static int ocfs2_create_xattr_block(struct inode *inode,
|
|||
int ret;
|
||||
u16 suballoc_bit_start;
|
||||
u32 num_got;
|
||||
u64 first_blkno;
|
||||
u64 suballoc_loc, first_blkno;
|
||||
struct ocfs2_dinode *di = (struct ocfs2_dinode *)inode_bh->b_data;
|
||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||
struct buffer_head *new_bh = NULL;
|
||||
struct ocfs2_xattr_block *xblk;
|
||||
|
||||
|
@ -2842,9 +2844,9 @@ static int ocfs2_create_xattr_block(struct inode *inode,
|
|||
goto end;
|
||||
}
|
||||
|
||||
ret = ocfs2_claim_metadata(osb, ctxt->handle, ctxt->meta_ac, 1,
|
||||
&suballoc_bit_start, &num_got,
|
||||
&first_blkno);
|
||||
ret = ocfs2_claim_metadata(ctxt->handle, ctxt->meta_ac, 1,
|
||||
&suballoc_loc, &suballoc_bit_start,
|
||||
&num_got, &first_blkno);
|
||||
if (ret < 0) {
|
||||
mlog_errno(ret);
|
||||
goto end;
|
||||
|
@ -2866,8 +2868,10 @@ static int ocfs2_create_xattr_block(struct inode *inode,
|
|||
memset(xblk, 0, inode->i_sb->s_blocksize);
|
||||
strcpy((void *)xblk, OCFS2_XATTR_BLOCK_SIGNATURE);
|
||||
xblk->xb_suballoc_slot = cpu_to_le16(ctxt->meta_ac->ac_alloc_slot);
|
||||
xblk->xb_suballoc_loc = cpu_to_le64(suballoc_loc);
|
||||
xblk->xb_suballoc_bit = cpu_to_le16(suballoc_bit_start);
|
||||
xblk->xb_fs_generation = cpu_to_le32(osb->fs_generation);
|
||||
xblk->xb_fs_generation =
|
||||
cpu_to_le32(OCFS2_SB(inode->i_sb)->fs_generation);
|
||||
xblk->xb_blkno = cpu_to_le64(first_blkno);
|
||||
if (indexed) {
|
||||
struct ocfs2_xattr_tree_root *xr = &xblk->xb_attrs.xb_root;
|
||||
|
@ -4229,7 +4233,6 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
|
|||
u32 bit_off, len;
|
||||
u64 blkno;
|
||||
handle_t *handle = ctxt->handle;
|
||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||
struct ocfs2_inode_info *oi = OCFS2_I(inode);
|
||||
struct buffer_head *xb_bh = xs->xattr_bh;
|
||||
struct ocfs2_xattr_block *xb =
|
||||
|
@ -4257,7 +4260,7 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = __ocfs2_claim_clusters(osb, handle, ctxt->data_ac,
|
||||
ret = __ocfs2_claim_clusters(handle, ctxt->data_ac,
|
||||
1, 1, &bit_off, &len);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
|
@ -5078,7 +5081,7 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
|
|||
goto leave;
|
||||
}
|
||||
|
||||
ret = __ocfs2_claim_clusters(osb, handle, ctxt->data_ac, 1,
|
||||
ret = __ocfs2_claim_clusters(handle, ctxt->data_ac, 1,
|
||||
clusters_to_add, &bit_off, &num_bits);
|
||||
if (ret < 0) {
|
||||
if (ret != -ENOSPC)
|
||||
|
@ -6906,7 +6909,7 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = ocfs2_claim_clusters(osb, handle, data_ac,
|
||||
ret = ocfs2_claim_clusters(handle, data_ac,
|
||||
len, &p_cluster, &num_clusters);
|
||||
if (ret) {
|
||||
mlog_errno(ret);
|
||||
|
|
Loading…
Reference in New Issue