Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 101115
b: refs/heads/master
c: d2a1763
h: refs/heads/master
i:
  101113: 10812c8
  101111: d6dcda9
v: v3
  • Loading branch information
Mingming Cao authored and Theodore Ts'o committed Jul 14, 2008
1 parent e7247c2 commit f04cc28
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 51 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e8ced39d5e8911c662d4d69a342b9d053eaaac4e
refs/heads/master: d2a1763791a634e315ec926b62829c1e88842c86
49 changes: 32 additions & 17 deletions trunk/fs/ext4/balloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1701,7 +1701,12 @@ ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode,
}

sbi = EXT4_SB(sb);
*count = ext4_has_free_blocks(sbi, *count);
if (!EXT4_I(inode)->i_delalloc_reserved_flag) {
/*
* With delalloc we already reserved the blocks
*/
*count = ext4_has_free_blocks(sbi, *count);
}
if (*count == 0) {
*errp = -ENOSPC;
return 0; /*return with ENOSPC error */
Expand Down Expand Up @@ -1902,7 +1907,8 @@ ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode,
le16_add_cpu(&gdp->bg_free_blocks_count, -num);
gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp);
spin_unlock(sb_bgl_lock(sbi, group_no));
percpu_counter_sub(&sbi->s_freeblocks_counter, num);
if (!EXT4_I(inode)->i_delalloc_reserved_flag)
percpu_counter_sub(&sbi->s_freeblocks_counter, num);

if (sbi->s_log_groups_per_flex) {
ext4_group_t flex_group = ext4_flex_group(sbi, group_no);
Expand Down Expand Up @@ -1976,40 +1982,49 @@ static ext4_fsblk_t do_blk_alloc(handle_t *handle, struct inode *inode,
}

/*
* ext4_new_meta_block() -- allocate block for meta data (indexing) blocks
* ext4_new_meta_blocks() -- allocate block for meta data (indexing) blocks
*
* @handle: handle to this transaction
* @inode: file inode
* @goal: given target block(filesystem wide)
* @count: total number of blocks need
* @errp: error code
*
* Return allocated block number on success
* Return 1st allocated block numberon success, *count stores total account
* error stores in errp pointer
*/
ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode,
ext4_fsblk_t goal, int *errp)
ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode,
ext4_fsblk_t goal, unsigned long *count, int *errp)
{
unsigned long count = 1;
return do_blk_alloc(handle, inode, 0, goal,
&count, errp, EXT4_META_BLOCK);
ext4_fsblk_t ret;
ret = do_blk_alloc(handle, inode, 0, goal,
count, errp, EXT4_META_BLOCK);
/*
* Account for the allocated meta blocks
*/
if (!(*errp)) {
spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
EXT4_I(inode)->i_allocated_meta_blocks += *count;
spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
}
return ret;
}

/*
* ext4_new_meta_blocks() -- allocate block for meta data (indexing) blocks
* ext4_new_meta_block() -- allocate block for meta data (indexing) blocks
*
* @handle: handle to this transaction
* @inode: file inode
* @goal: given target block(filesystem wide)
* @count: total number of blocks need
* @errp: error code
*
* Return 1st allocated block numberon success, *count stores total account
* error stores in errp pointer
* Return allocated block number on success
*/
ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode,
ext4_fsblk_t goal, unsigned long *count, int *errp)
ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode,
ext4_fsblk_t goal, int *errp)
{
return do_blk_alloc(handle, inode, 0, goal,
count, errp, EXT4_META_BLOCK);
unsigned long count = 1;
return ext4_new_meta_blocks(handle, inode, goal, &count, errp);
}

/*
Expand Down
3 changes: 2 additions & 1 deletion trunk/fs/ext4/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ static int ext4_readdir(struct file * filp,
struct buffer_head *bh = NULL;

map_bh.b_state = 0;
err = ext4_get_blocks_wrap(NULL, inode, blk, 1, &map_bh, 0, 0);
err = ext4_get_blocks_wrap(NULL, inode, blk, 1, &map_bh,
0, 0, 0);
if (err > 0) {
pgoff_t index = map_bh.b_blocknr >>
(PAGE_CACHE_SHIFT - inode->i_blkbits);
Expand Down
6 changes: 5 additions & 1 deletion trunk/fs/ext4/ext4.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@
#define EXT4_MB_HINT_GOAL_ONLY 256
/* goal is meaningful */
#define EXT4_MB_HINT_TRY_GOAL 512
/* blocks already pre-reserved by delayed allocation */
#define EXT4_MB_DELALLOC_RESERVED 1024


struct ext4_allocation_request {
/* target inode for block we're allocating */
Expand Down Expand Up @@ -1041,6 +1044,7 @@ extern void ext4_mb_update_group_info(struct ext4_group_info *grp,


/* inode.c */
void ext4_da_release_space(struct inode *inode, int used, int to_free);
int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode,
struct buffer_head *bh, ext4_fsblk_t blocknr);
struct buffer_head *ext4_getblk(handle_t *, struct inode *,
Expand Down Expand Up @@ -1234,7 +1238,7 @@ extern long ext4_fallocate(struct inode *inode, int mode, loff_t offset,
extern int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode,
sector_t block, unsigned long max_blocks,
struct buffer_head *bh, int create,
int extend_disksize);
int extend_disksize, int flag);
#endif /* __KERNEL__ */

#endif /* _EXT4_H */
1 change: 1 addition & 0 deletions trunk/fs/ext4/ext4_extents.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ static inline int ext4_ext_get_actual_len(struct ext4_extent *ext)
(le16_to_cpu(ext->ee_len) - EXT_INIT_MAX_LEN));
}

extern int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks);
extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *);
extern void ext4_ext_store_pblock(struct ext4_extent *, ext4_fsblk_t);
extern int ext4_extent_tree_init(handle_t *, struct inode *);
Expand Down
7 changes: 7 additions & 0 deletions trunk/fs/ext4/ext4_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ struct ext4_inode_info {
/* mballoc */
struct list_head i_prealloc_list;
spinlock_t i_prealloc_lock;

/* allocation reservation info for delalloc */
unsigned long i_reserved_data_blocks;
unsigned long i_reserved_meta_blocks;
unsigned long i_allocated_meta_blocks;
unsigned short i_delalloc_reserved_flag;
spinlock_t i_block_reservation_lock;
};

#endif /* _EXT4_I */
32 changes: 31 additions & 1 deletion trunk/fs/ext4/extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,36 @@ static int ext4_ext_space_root_idx(struct inode *inode)
return size;
}

/*
* Calculate the number of metadata blocks needed
* to allocate @blocks
* Worse case is one block per extent
*/
int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks)
{
int lcap, icap, rcap, leafs, idxs, num;
int newextents = blocks;

rcap = ext4_ext_space_root_idx(inode);
lcap = ext4_ext_space_block(inode);
icap = ext4_ext_space_block_idx(inode);

/* number of new leaf blocks needed */
num = leafs = (newextents + lcap - 1) / lcap;

/*
* Worse case, we need separate index block(s)
* to link all new leaf blocks
*/
idxs = (leafs + icap - 1) / icap;
do {
num += idxs;
idxs = (idxs + icap - 1) / icap;
} while (idxs > rcap);

return num;
}

static int
ext4_ext_max_entries(struct inode *inode, int depth)
{
Expand Down Expand Up @@ -2910,7 +2940,7 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
}
ret = ext4_get_blocks_wrap(handle, inode, block,
max_blocks, &map_bh,
EXT4_CREATE_UNINITIALIZED_EXT, 0);
EXT4_CREATE_UNINITIALIZED_EXT, 0, 0);
if (ret <= 0) {
#ifdef EXT4FS_DEBUG
WARN_ON(ret <= 0);
Expand Down
Loading

0 comments on commit f04cc28

Please sign in to comment.