aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2012-08-18 23:58:27 +0900
committerDaniel Phillips <daniel@tux3.org>2012-08-18 23:58:27 +0900
commit69e19da0db655f36f578611056f2ab05d30ed6b5 (patch)
treede94001998cef38957e205d4fe7aa8f59fc9e927
parent4f05bd545ff072e42efd1ae0a7f08d1c5e49d755 (diff)
downloadlinux-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.c108
-rw-r--r--fs/tux3/tux3.h1
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;