summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamjae Jeon <namjae.jeon@samsung.com>2014-10-03 09:31:29 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2014-10-14 14:46:35 +1100
commita6ecf401553406160342306f1e32ea73c0a65ba4 (patch)
tree129cf1af424da132bc0a8b2a4eb32c8dfd4e1752
parent689c05d39fde968034744f0a35878721f3622570 (diff)
fat: add i_disksize to represent uninitialized size
This patchset provides support for doing fallocate operation on FAT filesystem. This patch (of 5): Add i_disksize to represent uninitialized allocated size. And mmu_private represent initialized allocated size. i_disksize - is always kept cluster size aligned mmu_private - is normally block size aligned 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>
-rw-r--r--fs/fat/fat.h3
-rw-r--r--fs/fat/file.c5
-rw-r--r--fs/fat/inode.c11
3 files changed, 15 insertions, 4 deletions
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index e0c4ba39a377..f6bcaa7f1a10 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -119,7 +119,8 @@ struct msdos_inode_info {
unsigned int cache_valid_id;
/* NOTE: mmu_private is 64bits, so must hold ->i_mutex to access */
- loff_t mmu_private; /* physically allocated size */
+ loff_t mmu_private; /* physically allocated size (initialized) */
+ loff_t i_disksize; /* physically allocated size (uninitialized) */
int i_start; /* first cluster or 0 */
int i_logstart; /* logical first cluster */
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 85f79a89e747..288cf1ffae0d 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -300,8 +300,11 @@ void fat_truncate_blocks(struct inode *inode, loff_t offset)
* This protects against truncating a file bigger than it was then
* trying to write into the hole.
*/
- if (MSDOS_I(inode)->mmu_private > offset)
+ if (MSDOS_I(inode)->mmu_private > offset) {
MSDOS_I(inode)->mmu_private = offset;
+ MSDOS_I(inode)->i_disksize = round_up(offset,
+ sbi->cluster_size);
+ }
nr_clusters = (offset + (cluster_size - 1)) >> sbi->cluster_bits;
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 756aead10d96..21c244289d2f 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -104,6 +104,7 @@ static struct fat_floppy_defaults {
static int fat_add_cluster(struct inode *inode)
{
int err, cluster;
+ struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
err = fat_alloc_clusters(inode, &cluster, 1);
if (err)
@@ -113,6 +114,9 @@ static int fat_add_cluster(struct inode *inode)
err = fat_chain_add(inode, cluster, 1);
if (err)
fat_free_clusters(inode, cluster);
+ else
+ MSDOS_I(inode)->i_disksize += sbi->cluster_size;
+
return err;
}
@@ -469,7 +473,6 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
error = fat_calc_dir_size(inode);
if (error < 0)
return error;
- MSDOS_I(inode)->mmu_private = inode->i_size;
set_nlink(inode, fat_subdirs(inode));
} else { /* not a directory */
@@ -484,8 +487,11 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
inode->i_op = &fat_file_inode_operations;
inode->i_fop = &fat_file_operations;
inode->i_mapping->a_ops = &fat_aops;
- MSDOS_I(inode)->mmu_private = inode->i_size;
}
+
+ MSDOS_I(inode)->mmu_private = inode->i_size;
+ MSDOS_I(inode)->i_disksize = round_up(inode->i_size, sbi->cluster_size);
+
if (de->attr & ATTR_SYS) {
if (sbi->options.sys_immutable)
inode->i_flags |= S_IMMUTABLE;
@@ -1293,6 +1299,7 @@ static int fat_read_root(struct inode *inode)
& ~((loff_t)sbi->cluster_size - 1)) >> 9;
MSDOS_I(inode)->i_logstart = 0;
MSDOS_I(inode)->mmu_private = inode->i_size;
+ MSDOS_I(inode)->i_disksize = round_up(inode->i_size, sbi->cluster_size);
fat_save_attrs(inode, ATTR_DIR);
inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = 0;