diff options
author | Namjae Jeon <namjae.jeon@samsung.com> | 2014-01-10 12:41:58 +1100 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2014-01-10 12:41:58 +1100 |
commit | f07180d29c505aeff51f2bff855e5d3bd72f40d6 (patch) | |
tree | b4b90d65346427d2c647d830e8f78ed3ff211400 /fs | |
parent | 04a80f788260fd704135980a7a95aac07ab3aff7 (diff) |
fat: permit to return phy block number by fibmap in fallocated region
Make the fibmap call the return the proper physical block number for any
offset request in the fallocated range.
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
Signed-off-by: Amit Sahrawat <a.sahrawat@samsung.com>
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fat/cache.c | 13 | ||||
-rw-r--r-- | fs/fat/fat.h | 3 | ||||
-rw-r--r-- | fs/fat/inode.c | 3 |
3 files changed, 16 insertions, 3 deletions
diff --git a/fs/fat/cache.c b/fs/fat/cache.c index a132666920e6..d22c1a209808 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c @@ -325,19 +325,26 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys, last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits; if (sector >= last_block) { - if (!create) - return 0; - /* * Both ->mmu_private and ->i_disksize can access * on only allocation path. (caller must hold ->i_mutex) */ last_block = (MSDOS_I(inode)->i_disksize + (blocksize - 1)) >> blocksize_bits; + if (!create) { + /* Map a block in fallocated region */ + if (atomic_read(&MSDOS_I(inode)->beyond_isize)) + if (sector < last_block) + goto out_map_cluster; + + return 0; + } + if (sector >= last_block) return 0; } +out_map_cluster: cluster = sector >> (sbi->cluster_bits - sb->s_blocksize_bits); offset = sector & (sbi->sec_per_clus - 1); cluster = fat_bmap_cluster(inode, cluster); diff --git a/fs/fat/fat.h b/fs/fat/fat.h index 7b5851f7a733..b8842769b0c5 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -129,6 +129,9 @@ struct msdos_inode_info { struct hlist_node i_dir_hash; /* hash by i_logstart */ struct rw_semaphore truncate_lock; /* protect bmap against truncate */ struct inode vfs_inode; + + /* for getting block number beyond file size in case of fallocate */ + atomic_t beyond_isize; }; struct fat_slot_info { diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 6b3e203ff126..ba9831d9f648 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -256,7 +256,10 @@ static sector_t _fat_bmap(struct address_space *mapping, sector_t block) /* fat_get_cluster() assumes the requested blocknr isn't truncated. */ down_read(&MSDOS_I(mapping->host)->truncate_lock); + /* To get block number beyond file size in fallocated region */ + atomic_set(&MSDOS_I(mapping->host)->beyond_isize, 1); blocknr = generic_block_bmap(mapping, block, fat_get_block); + atomic_set(&MSDOS_I(mapping->host)->beyond_isize, 0); up_read(&MSDOS_I(mapping->host)->truncate_lock); return blocknr; |