]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
libext2fs: Add ext2fs_file_size_size2() and truncate the file if necessary
authorTheodore Ts'o <tytso@mit.edu>
Thu, 22 Jul 2010 13:51:23 +0000 (09:51 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 30 Jul 2010 19:40:53 +0000 (15:40 -0400)
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>
lib/ext2fs/ext2fs.h
lib/ext2fs/fileio.c

index 96dc54ba773f4c9bc44595bc87f28468acc51456..f2f9ac8c585ee4c6439c563e387039b13a3c604b 100644 (file)
@@ -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);
index f3a4d706539efd2d1551ef5acf0ba8f6b814cea9..4b62c2d4945363da8f51c16e0f256aaea36717c4 100644 (file)
@@ -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);
 }