Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
[pandora-kernel.git] / fs / btrfs / inode.c
index 5440bab..8cd1099 100644 (file)
@@ -483,7 +483,8 @@ again:
                nr_pages_ret = 0;
 
                /* flag the file so we don't compress in the future */
-               BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
+               if (!btrfs_test_opt(root, FORCE_COMPRESS))
+                       BTRFS_I(inode)->flags |= BTRFS_INODE_NOCOMPRESS;
        }
        if (will_compress) {
                *num_added += 1;
@@ -3995,7 +3996,11 @@ skip:
 
        /* Reached end of directory/root. Bump pos past the last item. */
        if (key_type == BTRFS_DIR_INDEX_KEY)
-               filp->f_pos = INT_LIMIT(off_t);
+               /*
+                * 32-bit glibc will use getdents64, but then strtol -
+                * so the last number we can serve is this.
+                */
+               filp->f_pos = 0x7fffffff;
        else
                filp->f_pos++;
 nopos:
@@ -5789,7 +5794,7 @@ out_fail:
 }
 
 static int prealloc_file_range(struct inode *inode, u64 start, u64 end,
-                              u64 alloc_hint, int mode)
+                       u64 alloc_hint, int mode, loff_t actual_len)
 {
        struct btrfs_trans_handle *trans;
        struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -5798,6 +5803,7 @@ static int prealloc_file_range(struct inode *inode, u64 start, u64 end,
        u64 cur_offset = start;
        u64 num_bytes = end - start;
        int ret = 0;
+       u64 i_size;
 
        while (num_bytes > 0) {
                alloc_size = min(num_bytes, root->fs_info->max_extent);
@@ -5836,8 +5842,12 @@ static int prealloc_file_range(struct inode *inode, u64 start, u64 end,
                BTRFS_I(inode)->flags |= BTRFS_INODE_PREALLOC;
                if (!(mode & FALLOC_FL_KEEP_SIZE) &&
                    cur_offset > inode->i_size) {
-                       i_size_write(inode, cur_offset);
-                       btrfs_ordered_update_i_size(inode, cur_offset, NULL);
+                       if (cur_offset > actual_len)
+                               i_size  = actual_len;
+                       else
+                               i_size = cur_offset;
+                       i_size_write(inode, i_size);
+                       btrfs_ordered_update_i_size(inode, i_size, NULL);
                }
 
                ret = btrfs_update_inode(trans, root, inode);
@@ -5930,7 +5940,7 @@ static long btrfs_fallocate(struct inode *inode, int mode,
                     !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
                        ret = prealloc_file_range(inode,
                                                  cur_offset, last_byte,
-                                                 alloc_hint, mode);
+                                               alloc_hint, mode, offset+len);
                        if (ret < 0) {
                                free_extent_map(em);
                                break;