diff options
author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2012-08-18 23:58:27 +0900 |
---|---|---|
committer | Daniel Phillips <daniel@tux3.org> | 2012-08-18 23:58:27 +0900 |
commit | 69e19da0db655f36f578611056f2ab05d30ed6b5 (patch) | |
tree | de94001998cef38957e205d4fe7aa8f59fc9e927 | |
parent | 4f05bd545ff072e42efd1ae0a7f08d1c5e49d755 (diff) | |
download | linux-tux3-69e19da0db655f36f578611056f2ab05d30ed6b5.tar.gz |
tux3: Consolidate tuxtruncate() with tux3_truncate()
Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
-rw-r--r-- | fs/tux3/inode.c | 108 | ||||
-rw-r--r-- | fs/tux3/tux3.h | 1 |
2 files changed, 69 insertions, 40 deletions
diff --git a/fs/tux3/inode.c b/fs/tux3/inode.c index 64d2d1dc87b30e..43d241e7150ef1 100644 --- a/fs/tux3/inode.c +++ b/fs/tux3/inode.c @@ -468,6 +468,74 @@ out: return err; } +static int tux3_truncate_blocks(struct inode *inode, loff_t newsize) +{ + struct sb *sb = tux_sb(inode->i_sb); + tuxkey_t index = (newsize + sb->blockmask) >> sb->blockbits; + + return btree_chop(&tux_inode(inode)->btree, index, TUXKEY_LIMIT); +} + +#ifdef __KERNEL__ +/* Truncate partial block. If partial, we have to update last block. */ +static int tux3_truncate_partial_block(struct inode *inode, loff_t newsize) +{ + return block_truncate_page(inode->i_mapping, newsize, tux3_get_block); +} + +void tux3_write_failed(struct address_space *mapping, loff_t to) +{ + struct inode *inode = mapping->host; + + if (to > inode->i_size) { + truncate_pagecache(inode, to, inode->i_size); + tux3_truncate_blocks(inode, inode->i_size); + } +} +#endif /* !__KERNEL__ */ + +static int tux3_truncate(struct inode *inode, loff_t newsize) +{ + /* FIXME: expanding size is not tested */ + struct sb *sb = tux_sb(inode->i_sb); + int is_expand, err; + + if (newsize == inode->i_size) + return 0; + + /* inode_dio_wait(inode); */ /* FIXME: for direct I/O */ + + err = 0; + is_expand = newsize > inode->i_size; + + change_begin(sb); + + if (!is_expand) { + err = tux3_truncate_partial_block(inode, newsize); + if (err) + goto error; + } + + /* Change i_size, then clean buffers */ + truncate_setsize(inode, newsize); + + if (!is_expand) { + err = tux3_truncate_blocks(inode, newsize); + if (err) + goto error; + } + + /* FIXME: implement i_blocks */ + inode->i_blocks = ((newsize+sb->blockmask) & ~(loff_t)sb->blockmask)>>9; + + inode->i_mtime = inode->i_ctime = gettime(); + mark_inode_dirty(inode); +error: + change_end(sb); + + return err; +} + /* * NOTE: clear_inode() for this inode is already done. This shouldn't * use generic part of inode basically. @@ -489,46 +557,6 @@ static int purge_inode(struct inode *inode) } #ifdef __KERNEL__ -static int tux_can_truncate(struct inode *inode) -{ - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - return 0; - if (S_ISREG(inode->i_mode)) - return 1; - if (S_ISDIR(inode->i_mode)) - return 1; - if (S_ISLNK(inode->i_mode)) - return 1; - return 0; -} - -static void __tux3_truncate(struct inode *inode) -{ - struct sb *sb = tux_sb(inode->i_sb); - tuxkey_t index = (inode->i_size + sb->blockmask) >> sb->blockbits; - int err; - - if (!tux_can_truncate(inode)) - return; - /* FIXME: must fix expand size */ - WARN_ON(inode->i_size); - block_truncate_page(inode->i_mapping, inode->i_size, tux3_get_block); - err = btree_chop(&tux_inode(inode)->btree, index, TUXKEY_LIMIT); - inode->i_blocks = ((inode->i_size + sb->blockmask) - & ~(loff_t)sb->blockmask) >> 9; - inode->i_mtime = inode->i_ctime = gettime(); - mark_inode_dirty(inode); -} - -static void tux3_truncate(struct inode *inode) -{ - struct sb *sb = tux_sb(inode->i_sb); - - change_begin(sb); - __tux3_truncate(inode); - change_end(sb); -} - void tux3_delete_inode(struct inode *inode) { struct sb *sb = tux_sb(inode->i_sb); diff --git a/fs/tux3/tux3.h b/fs/tux3/tux3.h index 9ac8bbb0506501..3abee9e8a5da70 100644 --- a/fs/tux3/tux3.h +++ b/fs/tux3/tux3.h @@ -407,6 +407,7 @@ typedef struct inode { struct sb *i_sb; map_t *map; loff_t i_size; + block_t i_blocks; unsigned i_version; struct timespec i_mtime, i_ctime, i_atime; unsigned i_uid, i_gid, i_nlink; |