summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2010-07-22 09:51:23 -0400
committerTheodore Ts'o <tytso@mit.edu>2010-07-30 15:40:53 -0400
commit27a0e958e619c3ca105e575670416a964fa2678f (patch)
tree540884025cc84e3610a65f91aaaec8121f94d893 /lib
parent6dc058bd126ba2f631e38233d899f58a04e0c74f (diff)
downloade2fsprogs-27a0e958e619c3ca105e575670416a964fa2678f.tar.gz
libext2fs: Add ext2fs_file_size_size2() and truncate the file if necessary
This adds a 64-bit interface for ext2fs_file_size_size() and enhances it to trunate the file if necessary. Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'lib')
-rw-r--r--lib/ext2fs/ext2fs.h1
-rw-r--r--lib/ext2fs/fileio.c30
2 files changed, 23 insertions, 8 deletions
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 96dc54ba..f2f9ac8c 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1028,6 +1028,7 @@ extern errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
errcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size);
extern ext2_off_t ext2fs_file_get_size(ext2_file_t file);
extern errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size);
+extern errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size);
/* finddev.c */
extern char *ext2fs_find_block_device(dev_t device);
diff --git a/lib/ext2fs/fileio.c b/lib/ext2fs/fileio.c
index f3a4d706..4b62c2d4 100644
--- a/lib/ext2fs/fileio.c
+++ b/lib/ext2fs/fileio.c
@@ -365,24 +365,38 @@ ext2_off_t ext2fs_file_get_size(ext2_file_t file)
/*
* This function sets the size of the file, truncating it if necessary
*
- * XXX still need to call truncate
*/
-errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size)
+errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size)
{
+ ext2_off64_t old_size;
errcode_t retval;
+ blk64_t old_truncate, truncate_block;
+
EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
- file->inode.i_size = size;
- file->inode.i_size_high = 0;
+ truncate_block = ((size + file->fs->blocksize - 1) >>
+ EXT2_BLOCK_SIZE_BITS(file->fs->super)) + 1;
+ old_size = file->inode.i_size +
+ ((blk64_t) file->inode.i_size_high) << 32;
+ old_truncate = ((old_size + file->fs->blocksize - 1) >>
+ EXT2_BLOCK_SIZE_BITS(file->fs->super)) + 1;
+
+ file->inode.i_size = size & 0xffffffff;
+ file->inode.i_size_high = (size >> 32);
if (file->ino) {
retval = ext2fs_write_inode(file->fs, file->ino, &file->inode);
if (retval)
return retval;
}
- /*
- * XXX truncate inode if necessary
- */
+ if (truncate_block <= old_truncate)
+ return 0;
- return 0;
+ return ext2fs_punch(file->fs, file->ino, &file->inode, 0,
+ truncate_block, ~0ULL);
+}
+
+errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size)
+{
+ return ext2fs_file_set_size2(file, size);
}