basic delayed allocation in ext4
Subsystems (2)
RFC 1/1 basic delayed allocation in ext4
Good day,
please review ...
thanks, Alex
Basic delayed allocation in ext4
Two special ->get_block() methods are introduced:
* ext4_da_get_block_prep()
to be used with ->prepare_write(), defers allocation till flush
* ext4_da_get_block_write()
to be used with mpage_da_writepages(), allocate blocks and correct on-disk size
Current implementation works with data=writeback only, you should mount filesystem with delalloc,data=writeback options.
TODO:
* reservation
* data=ordered
* quota
* bmap
include/linux/ext4_fs.h +1 -0
@@ -488,6 +488,7 @@ do { \#define EXT4_MOUNT_EXTENTS 0x400000/* Extents support */ #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000/* Journal checksums */ #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000/* Journal Async Commit */ +#define EXT4_MOUNT_DELALLOC 0x2000000/* Delalloc support */ /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */ #ifndef _LINUX_EXT2_FS_H#define clear_opt (o, opt) o &= ~EXT4_MOUNT_##opt
fs/ext4/super.c +5 -1
@@ -728,7 +728,7 @@ enum { Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota, Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota, - Opt_grpquota, Opt_extents, Opt_noextents, + Opt_grpquota, Opt_extents, Opt_noextents, Opt_delalloc, }; static match_table_t tokens = {
@@ -782,6 +782,7 @@ static match_table_t tokens = { {Opt_barrier, "barrier=%u"}, {Opt_extents, "extents"}, {Opt_noextents, "noextents"}, + {Opt_delalloc, "delalloc"}, {Opt_err, NULL}, {Opt_resize, "resize"}, };
@@ -1127,6 +1128,9 @@ clear_qf_name:case Opt_noextents:clear_opt (sbi->s_mount_opt,EXTENTS );break ; +case Opt_delalloc: +set_opt (sbi->s_mount_opt,DELALLOC ); +break ;default :printk (KERN_ERR "EXT4-fs: Unrecognized mount option \"%s\" "
fs/ext4/inode.c +156 -0
178 lines not on this page · raw message
Quoted 27 lines · Alex Tomas
Good day,
please review ...
thanks, Alex
Basic delayed allocation in ext4
Two special ->get_block() methods are introduced:
*
ext4_da_get_block_prep()
to be used with ->prepare_write(), defers allocation till flush
*ext4_da_get_block_write()
to be used withmpage_da_writepages(), allocate blocks and correct
on-disk sizeCurrent implementation works with data=writeback only, you should mount filesystem with delalloc,data=writeback options.
TODO:
* reservation
* data=ordered
* quota
* bmapSigned-off-by Alex Tomas <[email protected]>
[.. snip...]
Quoted 13 lines
/*
* Test whether an inode is a fast symlink.
*/fs/ext4/inode.c +6
-0@@ -1291,6 +1293,142 @@ static int ext4_journalled_commit_write( }/* +* this is a special callback for ->prepare_write() only +* it's intention is to return mapped block or reserve space +*/ +static int ext4_da_get_block_prep (struct inode *inode,sector_t iblock, +struct buffer_head *bh_result,int create) +{
fs/ext4/inode.c static int ext4_journalled_commit_write( · line 1311
Quoted 10 lines
fs/ext4/inode.c +10
-0+int ret =0 ; + +BUG_ON (create ==0 ); +BUG_ON (bh_result->b_size != inode->i_sb->s_blocksize); + +/* first, we need to know whether the block is allocated already +* XXX: when the filesystem has a lot of free blocks, we could +* reserve even allocated blocks to save this lookup */ + ret =ext4_get_blocks_wrap (NULL , inode, iblock,1 , bh_result,0 ,0 ); +if (ret >=0 ) {
I guess this should be (ret > 0)
fs/ext4/inode.c static int ext4_journalled_commit_write( · line 1316
Quoted 5 lines
fs/ext4/inode.c +5
-0+if (buffer_mapped (bh_result)) { + bh_result->b_size = (ret << inode->i_blkbits); + }else { +/* OK, the block isn't allocated yet, let's reserve space */ +/* XXX: call reservation here */
[...snip..]
epare_write(struct file *file, struct page *page,
fs/ext4/inode.c static int ext4_journalled_commit_write( · line 1395
Quoted 13 lines
fs/ext4/inode.c +13
-0+ unsigned from, unsigned to) +{ +return block_prepare_write (page, from, to, ext4_da_get_block_prep); +} + +return ret; +} + +static int ext4_da_writepages (struct address_space *mapping, +struct writeback_control *wbc) +{ +return mpage_da_writepages (mapping, wbc, ext4_da_get_block_write); +}
I was not able to find mpage_da_writepages()..
-aneesh
Quoted 9 lines · Aneesh Kumar K.V
Quoted 6 lines
fs/ext4/inode.c +4
-0+/* first, we need to know whether the block is allocated already +* XXX: when the filesystem has a lot of free blocks, we could +* reserve even allocated blocks to save this lookup */ + ret = ext4_get_blocks_wrap(NULL, inode, iblock, 1, bh_result, 0,0);
+ if (ret >= 0) {I guess this should be (ret > 0)
well, no. it has to catch allocated and non-allocated blocks (though can be written more clear, probably)
Quoted 1 line
I was not able to find
mpage_da_writepages()..
sorry, it's part of vfs delayed allocation patch, should be on the list now.
thanks, Alex