Hello,

When calculating the size of inline extent,  inode->i_size should also
be take into consideration, otherwise sys_write may drop some data
silently.  You can test this bug by:

#dd if=/dev/zero bs=4k count=1 of=test_file
#dd if=/dev/zero bs=2k count=1 of=test_file conv=notrunc

Previous patch is included in this one, please ignore it.

Regards
YZ
---
diff -r 2456df534a5f file.c
--- a/file.c    Thu Nov 01 19:45:34 2007 -0400
+++ b/file.c    Mon Nov 05 18:44:36 2007 +0800
@@ -239,7 +239,7 @@ static int dirty_and_release_pages(struc
        u64 start_pos;
        u64 end_of_last_block;
        u64 end_pos = pos + write_bytes;
-       u32 inline_size;
+       u64 inline_size;
        loff_t isize = i_size_read(inode);

        em = alloc_extent_map(GFP_NOFS);
@@ -328,9 +328,11 @@ static int dirty_and_release_pages(struc
                                         aligned_end, aligned_end, &hint_byte);
                if (err)
                        goto failed;
+               if (isize > inline_size)
+                       inline_size = min_t(u64, isize, aligned_end);
+               inline_size -= start_pos;
                err = insert_inline_extent(trans, root, inode, start_pos,
-                                          end_pos - start_pos, pages, 0,
-                                          num_pages);
+                                          inline_size, pages, 0, num_pages);
                BUG_ON(err);
        }
        if (end_pos > isize) {

_______________________________________________
Btrfs-devel mailing list
[email protected]
http://oss.oracle.com/mailman/listinfo/btrfs-devel

Reply via email to