8 years agoBtrfs: check return value of alloc_extent_map()
Tsutomu Itoh [Mon, 14 Feb 2011 00:45:29 +0000]
Btrfs: check return value of alloc_extent_map()

I add the check on the return value of alloc_extent_map() to several places.
In addition, alloc_extent_map() returns only the address or NULL.
Therefore, check by IS_ERR() is unnecessary. So, I remove IS_ERR() checking.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs - Fix memory leak in btrfs_init_new_device()
Ilya Dryomov [Sun, 6 Feb 2011 19:58:21 +0000]
Btrfs - Fix memory leak in btrfs_init_new_device()

Memory allocated by calling kstrdup() should be freed.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: prevent heap corruption in btrfs_ioctl_space_info()
Dan Rosenberg [Mon, 14 Feb 2011 21:04:23 +0000]
btrfs: prevent heap corruption in btrfs_ioctl_space_info()

Commit bf5fc093c5b625e4259203f1cee7ca73488a5620 refactored
btrfs_ioctl_space_info() and introduced several security issues.

space_args.space_slots is an unsigned 64-bit type controlled by a
possibly unprivileged caller.  The comparison as a signed int type
allows providing values that are treated as negative and cause the
subsequent allocation size calculation to wrap, or be truncated to 0.
By providing a size that's truncated to 0, kmalloc() will return
ZERO_SIZE_PTR.  It's also possible to provide a value smaller than the
slot count.  The subsequent loop ignores the allocation size when
copying data in, resulting in a heap overflow or write to ZERO_SIZE_PTR.

The fix changes the slot count type and comparison typecast to u64,
which prevents truncation or signedness errors, and also ensures that we
don't copy more data than we've allocated in the subsequent loop.  Note
that zero-size allocations are no longer possible since there is already
an explicit check for space_args.space_slots being 0 and truncation of
this value is no longer an issue.

Signed-off-by: Dan Rosenberg <drosenberg@vsecurity.com>
Signed-off-by: Josef Bacik <josef@redhat.com>
Reviewed-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: Fix balance panic
Yan, Zheng [Mon, 14 Feb 2011 21:00:03 +0000]
Btrfs: Fix balance panic

Mark the cloned backref_node as checked in clone_backref_node()

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: don't release pages when we can't clear the uptodate bits
Chris Mason [Mon, 14 Feb 2011 17:52:08 +0000]
Btrfs: don't release pages when we can't clear the uptodate bits

Btrfs tracks uptodate state in an rbtree as well as in the
page bits.  This is supposed to enable us to use block sizes other than
the page size, but there are a few parts still missing before that
completely works.

But, our readpage routine trusts this additional range based tracking
of uptodateness, much in the same way the buffer head up to date bits
are trusted for the other filesystems.

The problem is that sometimes we need to allocate memory in order to
split records in the rbtree, even when we are just clearing bits.  This
can be difficult when our clearing function is called GFP_ATOMIC, which
can happen in the releasepage path.

So, what happens today looks like this:

releasepage called with GFP_ATOMIC
btrfs_releasepage calls clear_extent_bit
clear_extent_bit fails to allocate ram, leaving the up to date bit set
btrfs_releasepage returns success

The end result is the page being gone, but btrfs thinking the range is
up to date.   Later on if someone tries to read that same page, the
btrfs readpage code will return immediately thinking the page is already
up to date.

This commit fixes things to fail the releasepage when we can't clear the
extent state bits.  It covers both data pages and metadata tree blocks.

Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: fix page->private races
Chris Mason [Thu, 10 Feb 2011 17:35:00 +0000]
Btrfs: fix page->private races

There is a race where btrfs_releasepage can drop the
page->private contents just as alloc_extent_buffer is setting
up pages for metadata.  Because of how the Btrfs page flags work,
this results in us skipping the crc on the page during IO.

This patch sovles the race by waiting until after the extent buffer
is inserted into the radix tree before it sets page private.

Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: Fix page count calculation
Yan, Zheng [Tue, 18 Jan 2011 05:34:40 +0000]
Btrfs: Fix page count calculation

take offset of start position into account when calculating page count.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: Drop __exit attribute on btrfs_exit_compress
Alexey Charkov [Wed, 2 Feb 2011 21:15:35 +0000]
btrfs: Drop __exit attribute on btrfs_exit_compress

As this function is called in some error paths while not
removing the module, the __exit attribute prevents the kernel
image from linking when btrfs is compiled in statically.

Signed-off-by: Alexey Charkov <alchark@gmail.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: cleanup error handling in btrfs_unlink_inode()
Tsutomu Itoh [Thu, 3 Feb 2011 03:16:25 +0000]
btrfs: cleanup error handling in btrfs_unlink_inode()

When btrfs_alloc_path() fails, btrfs_free_path() need not be called.
Therefore, it changes the branch ahead.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: exclude super blocks when we read in block groups
Josef Bacik [Wed, 2 Feb 2011 15:53:47 +0000]
Btrfs: exclude super blocks when we read in block groups

This has been resulting in a BUT_ON(ret) after btrfs_reserve_extent in
btrfs_cow_file_range.  The reason is we don't actually calculate the bytes_super
for a block group until we go to cache it, which means that the space_info can
hand out reservations for space that it doesn't actually have, and we can run
out of data space.  This is also a problem if you are using space caching since
we don't ever calculate bytes_super for the block groups.  So instead everytime
we read a block group call exclude_super_stripes, which calculates the
bytes_super for the block group so it can be left out of the space_info.  Then
whenever caching completes we just call free_excluded_extents so that the super
excluded extents are freed up.  Also if we are unmounting and we hit any block
groups that haven't been cached we still need to call free_excluded_extents to
make sure things are cleaned up properly.  Thanks,

Reported-by: Arne Jansen <sensille@gmx.net>
Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: make sure search_bitmap finds something in remove_from_bitmap
Josef Bacik [Thu, 3 Feb 2011 02:39:52 +0000]
Btrfs: make sure search_bitmap finds something in remove_from_bitmap

When we're cleaning up the tree log we need to be able to remove free space from
the block group.  The problem is if that free space spans bitmaps we would not
find the space since we're looking for too many bytes.  So make sure the amount
of bytes we search for is limited to either the number of bytes we want, or the
number of bytes left in the bitmap.  This was tested by a user who was hitting
the BUG() after search_bitmap.  With this patch he can now mount his fs.

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: fix return value check of btrfs_start_transaction()
Tsutomu Itoh [Thu, 20 Jan 2011 06:19:37 +0000]
btrfs: fix return value check of btrfs_start_transaction()

The error check of btrfs_start_transaction() is added, and the mistake
of the error check on several places is corrected.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: checking NULL or not in some functions
Tsutomu Itoh [Tue, 1 Feb 2011 09:17:35 +0000]
btrfs: checking NULL or not in some functions

Because NULL is returned when the memory allocation fails,
it is checked whether it is NULL.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: avoid uninit variable warnings in ordered-data.c
Chris Mason [Tue, 1 Feb 2011 00:54:59 +0000]
Btrfs: avoid uninit variable warnings in ordered-data.c

This one isn't really an uninit variable, but for pretty
obscure reasons.  Let's make it clearly correct.

Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: catch errors from btrfs_sync_log
Chris Mason [Mon, 31 Jan 2011 21:48:24 +0000]
Btrfs: catch errors from btrfs_sync_log

btrfs_sync_log returns -EAGAIN when we need full transaction commits
instead of small log commits, but sometimes we were dropping the return

In practice, we check for this a few different ways, but this is still a
bug that can leave off full log commits when we really need them.

Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: make shrink_delalloc a little friendlier
Josef Bacik [Fri, 21 Jan 2011 21:10:01 +0000]
Btrfs: make shrink_delalloc a little friendlier

Xfstests 224 will just sit there and spin for ever until eventually we give up
flushing delalloc and exit.  On my box this took several hours.  I could not
interrupt this process either, even though we use INTERRUPTIBLE.  So do 2 things

1) Keep us from looping over and over again without reclaiming anything
2) If we get interrupted exit the loop

I tested this and the test now exits in a reasonable amount of time, and can be
interrupted with ctrl+c.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: handle no memory properly in prepare_pages
Josef Bacik [Tue, 25 Jan 2011 22:11:54 +0000]
Btrfs: handle no memory properly in prepare_pages

Instead of doing a BUG_ON(1) in prepare_pages if grab_cache_page() fails, just
loop through the pages we've already grabbed and unlock and release them, then
return -ENOMEM like we should.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: do error checking in btrfs_del_csums
Josef Bacik [Fri, 28 Jan 2011 18:44:44 +0000]
Btrfs: do error checking in btrfs_del_csums

Got a report of a box panicing because we got a NULL eb in read_extent_buffer.
His fs was borked and btrfs_search_path returned EIO, but we don't check for
errors so the box paniced.  Yes I know this will just make something higher up
the stack panic, but that's a problem for future Josef.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: use the global block reserve if we cannot reserve space
Josef Bacik [Mon, 24 Jan 2011 21:43:20 +0000]
Btrfs: use the global block reserve if we cannot reserve space

We call use_block_rsv right before we make an allocation in order to make sure
we have enough space.  Now normally people have called btrfs_start_transaction()
with the appropriate amount of space that we need, so we just use some of that
pre-reserved space and move along happily.  The problem is where people use
btrfs_join_transaction(), which doesn't actually reserve any space.  So we try
and reserve space here, but we cannot flush delalloc, so this forces us to
return -ENOSPC when in reality we have plenty of space.  The most common symptom
is seeing a bunch of "couldn't dirty inode" messages in syslog.  With
xfstests 224 we end up falling back to start_transaction and then doing all the
flush delalloc stuff which causes to hang for a very long time.

So instead steal from the global reserve, which is what this is meant for
anyway.  With this patch and the other 2 I have sent xfstests 224 now passes
successfully.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: do not release more reserved bytes to the global_block_rsv than we need
Josef Bacik [Mon, 24 Jan 2011 21:43:19 +0000]
Btrfs: do not release more reserved bytes to the global_block_rsv than we need

When we do btrfs_block_rsv_release, if global_block_rsv is not full we will
release all the extra bytes to global_block_rsv, even if it's only a little
short of the amount of space that we need to reserve.  This causes us to starve
ourselves of reservable space during the transaction which will force us to
shrink delalloc bytes and commit the transaction more often than we should.  So
instead just add the amount of bytes we need to add to the global reserve so
reserved == size, and then add the rest back into the space_info for general
use.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: fix check_path_shared so it returns the right value
Josef Bacik [Mon, 24 Jan 2011 21:43:18 +0000]
Btrfs: fix check_path_shared so it returns the right value

When running xfstests 224 I kept getting ENOSPC when trying to remove the files,
and this is because we were returning ret from check_path_shared while it was
uninitalized, which isn't right.  Fix this to return 0 properly, and now
xfstests 224 doesn't freak out when it tries to clean itself up.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: check return value of btrfs_start_ioctl_transaction() properly
Tsutomu Itoh [Mon, 24 Jan 2011 00:57:10 +0000]
btrfs: check return value of btrfs_start_ioctl_transaction() properly

btrfs_start_ioctl_transaction() returns ERR_PTR(), not NULL.
So, it is necessary to use IS_ERR() to check the return value.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: fix return value check of btrfs_join_transaction()
Tsutomu Itoh [Tue, 25 Jan 2011 02:51:38 +0000]
btrfs: fix return value check of btrfs_join_transaction()

The error check of btrfs_join_transaction()/btrfs_join_transaction_nolock()
is added, and the mistake of the error check in several places is

For more stable Btrfs, I think that we should reduce BUG_ON().
But, I think that long time is necessary for this.
So, I propose this patch as a short-term solution.

With this patch:
 - To more stable Btrfs, the part that should be corrected is clarified.
 - The panic isn't done by the NULL pointer reference etc. (even if
   BUG_ON() is increased temporarily)
 - The error code is returned in the place where the error can be easily

As a long-term plan:
 - BUG_ON() is reduced by using the forced-readonly framework, etc.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agofs/btrfs/inode.c: Add missing IS_ERR test
Julia Lawall [Mon, 24 Jan 2011 19:55:19 +0000]
fs/btrfs/inode.c: Add missing IS_ERR test

After the conditional that precedes the following code, inode may be an
ERR_PTR value.  This can eg result from a memory allocation failure via the
call to btrfs_iget, and thus does not imply that root is different than
sub_root.  Thus, an IS_ERR check is added to ensure that there is no
dereference of inode in this case.

The semantic match that finds this problem is as follows:

// <smpl>
identifier f;
f(...) { ... return ERR_PTR(...); }

identifier r.f, fld;
expression x;
statement S1,S2;
 x = f(...)
 ... when != IS_ERR(x)
 if (IS_ERR(x) ||...) S1 else S2
// </smpl>

Signed-off-by: Julia Lawall <julia@diku.dk>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: fix missing break in switch phrase
liubo [Wed, 26 Jan 2011 06:22:33 +0000]
btrfs: fix missing break in switch phrase

There is a missing break in switch, fix it.

Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: fix several uncheck memory allocations
liubo [Wed, 26 Jan 2011 06:22:08 +0000]
btrfs: fix several uncheck memory allocations

To make btrfs more stable, add several missing necessary memory allocation
checks, and when no memory, return proper errno.

We've checked that some of those -ENOMEM errors will be returned to
userspace, and some will be catched by BUG_ON() in the upper callers,
and none will be ignored silently.

Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: fix uncheck memory allocation in btrfs_submit_compressed_read
liubo [Wed, 26 Jan 2011 06:21:39 +0000]
btrfs: fix uncheck memory allocation in btrfs_submit_compressed_read

btrfs_submit_compressed_read() is lack of memory allocation checks and
corresponding error route.

After this fix, if it comes to "no memory" case, errno will be returned
to userland step by step, and tell users this operation cannot go on.

Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoMerge branch 'bug-fixes' of git://repo.or.cz/linux-btrfs-devel into btrfs-38
Chris Mason [Fri, 28 Jan 2011 21:24:59 +0000]
Merge branch 'bug-fixes' of git://repo.or.cz/linux-btrfs-devel into btrfs-38

8 years agoBtrfs: Fix file clone when source offset is not 0
Li Zefan [Wed, 26 Jan 2011 06:10:43 +0000]
Btrfs: Fix file clone when source offset is not 0

- the source extent is: [0, 100]
- the src offset is 10
- the clone length is 90
- the dest offset is 0

This statement:

new_key.offset = key.offset + destoff - off

will produce such an extent for the dest file:


, which is obviously wrong.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agoBtrfs: Fix memory leak in writepage fixup work
Miao Xie [Wed, 26 Jan 2011 08:19:22 +0000]
Btrfs: Fix memory leak in writepage fixup work

fixup, which is allocated when starting page write to fix up the
extent without ORDERED bit set, should be freed after this work
is done.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agoBtrfs: Don't return acl info when mounting with noacl option
Miao Xie [Tue, 25 Jan 2011 07:46:17 +0000]
Btrfs: Don't return acl info when mounting with noacl option

Steps to reproduce:

  # mkfs.btrfs /dev/sda2
  # mount /dev/sda2 /mnt
  # touch /mnt/file0
  # setfacl -m 'u:root:x,g::x,o::x' /mnt/file0
  # umount /mnt
  # mount /dev/sda2 -o noacl /mnt
  # getfacl /mnt/file0

The output should be:


Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agoBtrfs: Free correct pointer after using strsep
Tero Roponen [Mon, 27 Dec 2010 08:43:13 +0000]
Btrfs: Free correct pointer after using strsep

We must save and free the original kstrdup()'ed pointer
because strsep() modifies its first argument.

Signed-off-by: Tero Roponen <tero.roponen@gmail.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agoBtrfs: Fix memory leak on finding existing super
Ian Kent [Mon, 27 Dec 2010 08:33:15 +0000]
Btrfs: Fix memory leak on finding existing super

We missed a memory deallocation in commit 450ba0ea.

If an existing super block is found at mount and there is no
error condition then the pre-allocated tree_root and fs_info
are no not used and are not freeded.

Signed-off-by: Ian Kent <raven@themaw.net>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agoBtrfs: Fix memory leak at umount
Li Zefan [Mon, 27 Dec 2010 08:19:53 +0000]
Btrfs: Fix memory leak at umount

fs_info, which is allocated in open_ctree(), should be freed
in close_ctree().

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agobtrfs: Check mergeable free space when removing a cluster
Li Zefan [Tue, 9 Nov 2010 06:57:39 +0000]
btrfs: Check mergeable free space when removing a cluster

After returing extents from a cluster to the block group, some
extents in the block group may be mergeable.

Reviewed-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agobtrfs: Add a helper try_merge_free_space()
Li Zefan [Tue, 9 Nov 2010 06:56:50 +0000]
btrfs: Add a helper try_merge_free_space()

When adding a new extent, we'll firstly see if we can merge
this extent to the left or/and right extent. Extract this as
a helper try_merge_free_space().

As a side effect, we fix a small bug that if the new extent
has non-bitmap left entry but is unmergeble, we'll directly
link the extent without trying to drop it into bitmap.

This also prepares for the next patch.

Reviewed-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agobtrfs: Update stats when allocating from a cluster
Li Zefan [Tue, 9 Nov 2010 06:55:34 +0000]
btrfs: Update stats when allocating from a cluster

When allocating extent entry from a cluster, we should update
the free_space and free_extents fields of the block group.

Reviewed-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agobtrfs: Free fully occupied bitmap in cluster
Li Zefan [Tue, 9 Nov 2010 06:51:45 +0000]
btrfs: Free fully occupied bitmap in cluster

If there's no more free space in a bitmap, we should free it.

Reviewed-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agobtrfs: Add helper function free_bitmap()
Li Zefan [Tue, 9 Nov 2010 06:50:07 +0000]
btrfs: Add helper function free_bitmap()

Remove some duplicated code.

This prepares for the next patch.

Reviewed-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agobtrfs: Fix threshold calculation for block groups smaller than 1GB
Li Zefan [Tue, 9 Nov 2010 06:48:01 +0000]
btrfs: Fix threshold calculation for block groups smaller than 1GB

If a block group is smaller than 1GB, the extent entry threadhold
calculation will always set the threshold to 0.

So as free space gets fragmented, btrfs will switch to use bitmap
to manage free space, but then will never switch back to extents
due to this bug.

Reviewed-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agoBtrfs: forced readonly mounts on errors
liubo [Thu, 6 Jan 2011 11:30:25 +0000]
Btrfs: forced readonly mounts on errors

This patch comes from "Forced readonly mounts on errors" ideas.

As we know, this is the first step in being more fault tolerant of disk
corruptions instead of just using BUG() statements.

The major content:
- add a framework for generating errors that should result in filesystems
  going readonly.
- keep FS state in disk super block.
- make sure that all of resource will be freed and released at umount time.
- make sure that fter FS is forced readonly on error, there will be no more
  disk change before FS is corrected. For this, we should stop write operation.

After this patch is applied, the conversion from BUG() to such a framework can
happen incrementally.

Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: Require CAP_SYS_ADMIN for filesystem rebalance
Ben Hutchings [Wed, 29 Dec 2010 14:55:03 +0000]
btrfs: Require CAP_SYS_ADMIN for filesystem rebalance

Filesystem rebalancing (BTRFS_IOC_BALANCE) affects the entire
filesystem and may run uninterruptibly for a long time.  This does not
seem to be something that an unprivileged user should be able to do.

Reported-by: Aron Xu <happyaron.xu@gmail.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: don't warn if we get ENOSPC in btrfs_block_rsv_check
Josef Bacik [Wed, 12 Jan 2011 21:04:22 +0000]
Btrfs: don't warn if we get ENOSPC in btrfs_block_rsv_check

If we run low on space we could get a bunch of warnings out of
btrfs_block_rsv_check, but this is mostly just called via the transaction code
to see if we need to end the transaction, it expects to see failures, so let's
not WARN and freak everybody out for no reason.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: Fix memory leak in btrfs_read_fs_root_no_radix()
Tsutomu Itoh [Mon, 27 Dec 2010 06:53:10 +0000]
btrfs: Fix memory leak in btrfs_read_fs_root_no_radix()

In btrfs_read_fs_root_no_radix(), 'root' is not freed if
btrfs_search_slot() returns error.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: check NULL or not
Tsutomu Itoh [Wed, 5 Jan 2011 02:32:22 +0000]
btrfs: check NULL or not

Should check if functions returns NULL or not.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: Don't pass NULL ptr to func that may deref it.
Jesper Juhl [Sat, 25 Dec 2010 21:22:30 +0000]
btrfs: Don't pass NULL ptr to func that may deref it.


In fs/btrfs/inode.c::fixup_tree_root_location() we have this code:

  if (!path) {
  err = -ENOMEM;
  goto out;
  return err;

btrfs_free_path() passes its argument on to other functions and some of
them end up dereferencing the pointer.
In the code above that pointer is clearly NULL, so btrfs_free_path() will
eventually cause a NULL dereference.

There are many ways to cut this cake (fix the bug). The one I chose was to
make btrfs_free_path() deal gracefully with NULL pointers. If you
disagree, feel free to come up with an alternative patch.

Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: mount failure return value fix
Dave Young [Sat, 8 Jan 2011 10:09:13 +0000]
btrfs: mount failure return value fix

I happened to pass swap partition as root partition in cmdline,
then kernel panic and tell me about "Cannot open root device".
It is not correct, in fact it is a fs type mismatch instead of 'no device'.

Eventually I found btrfs mounting failed with -EIO, it should be -EINVAL.
The logic in init/do_mounts.c:
        for (p = fs_names; *p; p += strlen(p)+1) {
                int err = do_mount_root(name, p, flags, root_mount_data);
                switch (err) {
                        case 0:
                                goto out;
                        case -EACCES:
                                flags |= MS_RDONLY;
                                goto retry;
                        case -EINVAL:
print "Cannot open root device"
SO fs type after btrfs will have no chance to mount

Here fix the return value as -EINVAL

Signed-off-by: Dave Young <hidave.darkstar@gmail.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: Mem leak in btrfs_get_acl()
Jesper Juhl [Thu, 6 Jan 2011 21:45:21 +0000]
btrfs: Mem leak in btrfs_get_acl()

It seems to me that we leak the memory allocated to 'value' in
btrfs_get_acl() if the call to posix_acl_from_xattr() fails.
Here's a patch that attempts to correct that problem.

Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: fix wrong free space information of btrfs
Miao Xie [Wed, 5 Jan 2011 10:07:31 +0000]
btrfs: fix wrong free space information of btrfs

When we store data by raid profile in btrfs with two or more different size
disks, df command shows there is some free space in the filesystem, but the
user can not write any data in fact, df command shows the wrong free space
information of btrfs.

 # mkfs.btrfs -d raid1 /dev/sda9 /dev/sda10
 # btrfs-show
 Label: none  uuid: a95cd49e-6e33-45b8-8741-a36153ce4b64
  Total devices 2 FS bytes used 28.00KB
  devid    1 size 5.01GB used 2.03GB path /dev/sda9
  devid    2 size 10.00GB used 2.01GB path /dev/sda10
 # btrfs device scan /dev/sda9 /dev/sda10
 # mount /dev/sda9 /mnt
 # dd if=/dev/zero of=tmpfile0 bs=4K count=9999999999
   (fill the filesystem)
 # sync
 # df -TH
 Filesystem Type Size Used Avail Use% Mounted on
 /dev/sda9 btrfs 17G 8.6G 5.4G 62% /mnt
 # btrfs-show
 Label: none  uuid: a95cd49e-6e33-45b8-8741-a36153ce4b64
  Total devices 2 FS bytes used 3.99GB
  devid    1 size 5.01GB used 5.01GB path /dev/sda9
  devid    2 size 10.00GB used 4.99GB path /dev/sda10

It is because btrfs cannot allocate chunks when one of the pairing disks has
no space, the free space on the other disks can not be used for ever, and should
be subtracted from the total space, but btrfs doesn't subtract this space from
the total. It is strange to the user.

This patch fixes it by calcing the free space that can be used to allocate

1. get all the devices free space, and align them by stripe length.
2. sort the devices by the free space.
3. check the free space of the devices,
   3.1. if it is not zero, and then check the number of the devices that has
        more free space than this device,
        if the number of the devices is beyond the min stripe number, the free
        space can be used, and add into total free space.
        if the number of the devices is below the min stripe number, we can not
        use the free space, the check ends.
   3.2. if the free space is zero, check the next devices, goto 3.1

This implementation is just likely fake chunk allocation.

After appling this patch, df can show correct space information:
 # df -TH
 Filesystem Type Size Used Avail Use% Mounted on
 /dev/sda9 btrfs 17G 8.6G 0 100% /mnt

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: make the chunk allocator utilize the devices better
Miao Xie [Wed, 5 Jan 2011 10:07:28 +0000]
btrfs: make the chunk allocator utilize the devices better

With this patch, we change the handling method when we can not get enough free
extents with default size.

1. Look up the suitable free extent on each device and keep the search result.
   If not find a suitable free extent, keep the max free extent
2. If we get enough suitable free extents with default size, chunk allocation
3. If we can not get enough free extents, but the number of the extent with
   default size is >= min_stripes, we just change the mapping information
   (reduce the number of stripes in the extent map), and chunk allocation
4. If the number of the extent with default size is < min_stripes, sort the
   devices by its max free extent's size descending
5. Use the size of the max free extent on the (num_stripes - 1)th device as the
   stripe size to allocate the device space

By this way, the chunk allocator can allocate chunks as large as possible when
the devices' space is not enough and make full use of the devices.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: restructure find_free_dev_extent()
Miao Xie [Wed, 5 Jan 2011 10:07:26 +0000]
btrfs: restructure find_free_dev_extent()

- make it return the start position and length of the max free space when it can
  not find a suitable free space.
- make it more readability

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: fix wrong calculation of stripe size
Miao Xie [Wed, 5 Jan 2011 10:07:24 +0000]
btrfs: fix wrong calculation of stripe size

There are two tiny problem:
- One is When we check the chunk size is greater than the max chunk size or not,
  we should take mirrors into account, but the original code didn't.
- The other is btrfs shouldn't use the size of the residual free space as the
  length of of a dup chunk when doing chunk allocation. It is because the device
  space that a dup chunk needs is twice as large as the chunk size, if we use
  the size of the residual free space as the length of a dup chunk, we can not
  get enough free space. Fix it.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Reviewed-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: try to reclaim some space when chunk allocation fails
Miao Xie [Wed, 5 Jan 2011 10:07:18 +0000]
btrfs: try to reclaim some space when chunk allocation fails

We cannot write data into files when when there is tiny space in the filesystem.

Reproduce steps:
 # mkfs.btrfs /dev/sda1
 # mount /dev/sda1 /mnt
 # dd if=/dev/zero of=/mnt/tmpfile0 bs=4K count=1
 # dd if=/dev/zero of=/mnt/tmpfile1 bs=4K count=99999999999999
   (fill the filesystem)
 # umount /mnt
 # mount /dev/sda1 /mnt
 # rm -f /mnt/tmpfile0
 # dd if=/dev/zero of=/mnt/tmpfile0 bs=4K count=1
   (failed with nospec)

But if we do the last step again, we can write data successfully. The reason of
the problem is that btrfs didn't try to commit the current transaction and
reclaim some space when chunk allocation failed.

This patch fixes it by committing the current transaction to reclaim some
space when chunk allocation fails.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Reviewed-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: fix wrong data space statistics
Miao Xie [Wed, 5 Jan 2011 10:07:15 +0000]
btrfs: fix wrong data space statistics

Josef has implemented mixed data/metadata chunks, we must add those chunks'
space just like data chunks.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Reviewed-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agofs/btrfs: Fix build of ctree
Stefan Schmidt [Wed, 12 Jan 2011 09:30:42 +0000]
fs/btrfs: Fix build of ctree

CC [M] fs/btrfs/ctree.o
In file included from fs/btrfs/ctree.c:21:0:
fs/btrfs/ctree.h:1003:17: error: field <91>super_kobj<92> has incomplete type
fs/btrfs/ctree.h:1074:17: error: field <91>root_kobj<92> has incomplete type
make[2]: *** [fs/btrfs/ctree.o] Error 1
make[1]: *** [fs/btrfs] Error 2
make: *** [fs] Error 2

We need to include kobject.h here.

Reported-by: Jeff Garzik <jeff@garzik.org>
Fix-suggested-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoMerge branch 'lzo-support' of git://repo.or.cz/linux-btrfs-devel into btrfs-38
Chris Mason [Sun, 16 Jan 2011 16:25:54 +0000]
Merge branch 'lzo-support' of git://repo.or.cz/linux-btrfs-devel into btrfs-38

8 years agoMerge branch 'readonly-snapshots' of git://repo.or.cz/linux-btrfs-devel into btrfs-38
Chris Mason [Sun, 16 Jan 2011 16:24:45 +0000]
Merge branch 'readonly-snapshots' of git://repo.or.cz/linux-btrfs-devel into btrfs-38

8 years agoBtrfs: fix off by one while setting block groups readonly
Chris Mason [Fri, 24 Dec 2010 11:41:52 +0000]
Btrfs: fix off by one while setting block groups readonly

When we read in block groups, we'll set non-redundant groups
readonly if we find a raid1, DUP or raid10 group.  But the
ro code has an off by one bug in the math around testing to
make sure out accounting doesn't go wrong.

Signed-off-by: Chris Mason <chris.mason@oracle.com>

Li Zefan [Mon, 20 Dec 2010 08:30:25 +0000]

This allows us to set a snapshot or a subvolume readonly or writable
on the fly.


Set BTRFS_SUBVOL_RDONLY of btrfs_ioctl_vol_arg_v2->flags, and then

Changelog for v3:

- Change to pass __u64 as ioctl parameter.

Changelog for v2:

- Add _GETFLAGS ioctl.
- Check if the passed fd is the root of a subvolume.
- Change the name from _SNAP_SETFLAGS to _SUBVOL_SETFLAGS.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agoBtrfs: Add readonly snapshots support
Li Zefan [Mon, 20 Dec 2010 08:04:08 +0000]
Btrfs: Add readonly snapshots support


Set BTRFS_SUBVOL_RDONLY of btrfs_ioctl_vol_arg_v2->flags, and call


- Set readonly bit of btrfs_root_item->flags.
- Add readonly checks in btrfs_permission (inode_permission),
btrfs_setattr, btrfs_set/remove_xattr and some ioctls.

Changelog for v3:

- Eliminate btrfs_root->readonly, but check btrfs_root->root_item.flags.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agoBtrfs: Refactor btrfs_ioctl_snap_create()
Li Zefan [Mon, 20 Dec 2010 07:53:28 +0000]
Btrfs: Refactor btrfs_ioctl_snap_create()

Split it into two functions for two different ioctls, since they
share no common code.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agobtrfs: Extract duplicate decompress code
Li Zefan [Mon, 8 Nov 2010 07:22:19 +0000]
btrfs: Extract duplicate decompress code

Add a common function to copy decompressed data from working buffer
to bio pages.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agobtrfs: Allow to specify compress method when defrag
Li Zefan [Mon, 25 Oct 2010 07:12:50 +0000]
btrfs: Allow to specify compress method when defrag

Update defrag ioctl, so one can choose lzo or zlib when turning
on compression in defrag operation.


v1 -> v2
- Add incompability flag.
- Fix to check invalid compress type.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agobtrfs: Add lzo compression support
Li Zefan [Mon, 25 Oct 2010 07:12:26 +0000]
btrfs: Add lzo compression support

Lzo is a much faster compression algorithm than gzib, so would allow
more users to enable transparent compression, and some users can
choose from compression ratio and speed for different applications


 # mount -t btrfs -o compress[=<zlib,lzo>] dev /mnt
 # mount -t btrfs -o compress-force[=<zlib,lzo>] dev /mnt

"-o compress" without argument is still allowed for compatability.


If we mount a filesystem with lzo compression, it will not be able be
mounted in old kernels. One reason is, otherwise btrfs will directly
dump compressed data, which sits in inline extent, to user.


The test copied a linux source tarball (~400M) from an ext4 partition
to the btrfs partition, and then extracted it.

(time in second)
           lzo        zlib        nocompress
copy:      10.6       21.7        14.9
extract:   70.1       94.4        66.6

(data size in MB)
           lzo        zlib        nocompress
copy:      185.87     108.69      394.49
extract:   193.80     132.36      381.21


v1 -> v2:
- Select LZO_COMPRESS and LZO_DECOMPRESS in btrfs Kconfig.
- Add incompability flag.
- Fix error handling in compress code.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agobtrfs: Allow to add new compression algorithm
Li Zefan [Fri, 17 Dec 2010 06:21:50 +0000]
btrfs: Allow to add new compression algorithm

Make the code aware of compression type, instead of always assuming
zlib compression.

Also make the zlib workspace function as common code for all
compression types.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agobtrfs: Fix error handling in zlib
Li Zefan [Tue, 9 Nov 2010 00:27:27 +0000]
btrfs: Fix error handling in zlib

Return failure if alloc_page() fails to allocate memory,
and the upper code will just give up compression.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agobtrfs: Fix bugs in zlib workspace
Li Zefan [Mon, 25 Oct 2010 07:11:43 +0000]
btrfs: Fix bugs in zlib workspace

- Fix a race that can result in alloc_workspace > cpus.
- Fix to check num_workspace after wakeup.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>

8 years agoBtrfs: prevent RAID level downgrades when space is low
Chris Mason [Mon, 13 Dec 2010 20:06:46 +0000]
Btrfs: prevent RAID level downgrades when space is low

The extent allocator has code that allows us to fill
allocations from any available block group, even if it doesn't
match the raid level we've requested.

This was put in because adding a new drive to a filesystem
made with the default mkfs options actually upgrades the metadata from
single spindle dup to full RAID1.

But, the code also allows us to allocate from a raid0 chunk when we
really want a raid1 or raid10 chunk.  This can cause big trouble because
mkfs creates a small (4MB) raid0 chunk for data and metadata which then
goes unused for raid1/raid10 installs.

The allocator will happily wander in and allocate from that chunk when
things get tight, which is not correct.

The fix here is to make sure that we provide duplication when the
caller has asked for it.  It does all the dups to be any raid level,
which preserves the dup->raid1 upgrade abilities.

Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: account for missing devices in RAID allocation profiles
Chris Mason [Mon, 13 Dec 2010 19:56:23 +0000]
Btrfs: account for missing devices in RAID allocation profiles

When we mount in RAID degraded mode without adding a new device to
replace the failed one, we can end up using the wrong RAID flags for

This results in strange combinations of block groups (raid1 in a raid10
filesystem) and corruptions when we try to allocate blocks from single
spindle chunks on drives that are actually missing.

The first device has two small 4MB chunks in it that mkfs creates and
these are usually unused in a raid1 or raid10 setup.  But, in -o degraded,
the allocator will fall back to these because the mask of desired raid groups
isn't correct.

The fix here is to count the missing devices as we build up the list
of devices in the system.  This count is used when picking the
raid level to make sure we continue using the same levels that were
in place before we lost a drive.

Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: EIO when we fail to read tree roots
Chris Mason [Mon, 13 Dec 2010 19:47:58 +0000]
Btrfs: EIO when we fail to read tree roots

If we just get a plain IO error when we read tree roots, the code
wasn't properly sending that error up the chain.  This allowed mounts to
continue when they should failed, and allowed operations
on partially setup root structs.  The end result was usually oopsen
on spinlocks that hadn't been spun up correctly.

Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: fix compiler warnings
Jan Beulich [Tue, 7 Dec 2010 14:54:09 +0000]
Btrfs: fix compiler warnings

... regarding an unused function when !MIGRATION, and regarding a
printk() format string vs argument mismatch.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: Make async snapshot ioctl more generic
Li Zefan [Fri, 10 Dec 2010 06:41:56 +0000]
Btrfs: Make async snapshot ioctl more generic

If we had reserved some bytes in struct btrfs_ioctl_vol_args, we
wouldn't have to create a new structure for async snapshot creation.

Here we convert async snapshot ioctl to use a more generic ABI, as
we'll add more ioctls for snapshots/subvolumes in the future, readonly
snapshots for example.

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: pwrite blocked when writing from the mmaped buffer of the same page
Xin Zhong [Thu, 9 Dec 2010 09:30:14 +0000]
Btrfs: pwrite blocked when writing from the mmaped buffer of the same page

This problem is found in meego testing:
A file in btrfs is mmaped and the mmaped buffer is passed to pwrite to write to the same page
of the same file. In btrfs_file_aio_write(), the pages is locked by prepare_pages(). So when
btrfs_copy_from_user() is called, page fault happens and the same page needs to be locked again
in filemap_fault(). The fix is to move iov_iter_fault_in_readable() before prepage_pages() to make page
fault happen before pages are locked. And also disable page fault in critical region in

Reviewed-by: Yan, Zheng<zheng.z.yan@intel.com>
Signed-off-by: Zhong, Xin <xin.zhong@intel.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: Fix a crash when mounting a subvolume
Li Zefan [Tue, 7 Dec 2010 01:51:26 +0000]
Btrfs: Fix a crash when mounting a subvolume

We should drop dentry before deactivating the superblock, otherwise
we can hit this bug:

BUG: Dentry f349a690{i=100,n=/} still in use (1) [unmount of btrfs loop1]

Steps to reproduce the bug:

  # mount /dev/loop1 /mnt
  # mkdir save
  # btrfs subvolume snapshot /mnt save/snap1
  # umount /mnt
  # mount -o subvol=save/snap1 /dev/loop1 /mnt

Reported-by: Michael Niederle <mniederle@gmx.at>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: fix sync subvol/snapshot creation
Sage Weil [Fri, 10 Dec 2010 00:36:28 +0000]
Btrfs: fix sync subvol/snapshot creation

We were incorrectly taking the async path even for the sync ioctls by
passing in &transid unconditionally.

There's ample room for further cleanup here, but this keeps the fix simple.

Signed-off-by: Sage Weil <sage@newdream.net>
Reviewed-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: Fix page leak in compressed writeback path
Yan, Zheng [Mon, 6 Dec 2010 07:02:36 +0000]
Btrfs: Fix page leak in compressed writeback path

"start + num_bytes >= actual_end" can happen when compressed page writeback races
with file truncation. In that case we need unlock and release pages past the end
of file.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: do not BUG if we fail to remove the orphan item for dead snapshots
Josef Bacik [Wed, 8 Dec 2010 17:24:01 +0000]
Btrfs: do not BUG if we fail to remove the orphan item for dead snapshots

Not being able to delete an orphan item isn't a horrible thing.  The worst that
happens is the next time around we try and do the orphan cleanup and we can't
find the referenced object and just delete the item and move on.

Signed-off-by: Josef Bacik <josef@redhat.com>

8 years agoBtrfs: fixup return code for btrfs_del_orphan_item
Josef Bacik [Wed, 8 Dec 2010 17:22:34 +0000]
Btrfs: fixup return code for btrfs_del_orphan_item

If the orphan item doesn't exist, we return 1, which doesn't make any sense to
the callers.  Instead return -ENOENT if we didn't find the item.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>

8 years agoBtrfs: do not do fast caching if we are allocating blocks for tree_root
Josef Bacik [Wed, 8 Dec 2010 14:15:11 +0000]
Btrfs: do not do fast caching if we are allocating blocks for tree_root

Since the fast caching uses normal tree locking, we can possibly deadlock if we
get to the caching via a btrfs_search_slot() on the tree_root.  So just check to
see if the root we are on is the tree root, and just don't do the fast caching.

Reported-by: Sage Weil <sage@newdream.net>
Signed-off-by: Josef Bacik <josef@redhat.com>

8 years agoBtrfs: deal with space cache errors better
Josef Bacik [Fri, 3 Dec 2010 18:17:53 +0000]
Btrfs: deal with space cache errors better

Currently if the space cache inode generation number doesn't match the
generation number in the space cache header we will just fail to load the space
cache, but we won't mark the space cache as an error, so we'll keep getting that
error each time somebody tries to cache that block group until we actually clear
the thing.  Fix this by marking the space cache as having an error so we only
get the message once.  This patch also makes it so that we don't try and setup
space cache for a block group that isn't cached, since we won't be able to write
it out anyway.  None of these problems are actual problems, they are just
annoying and sub-optimal.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>

8 years agoBtrfs: fix use after free in O_DIRECT
Josef Bacik [Fri, 19 Nov 2010 14:41:10 +0000]
Btrfs: fix use after free in O_DIRECT

This fixes a bug where we use dip after we have freed it.  Instead just use the
file_offset that was passed to the function.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>

8 years agoBtrfs: don't use migrate page without CONFIG_MIGRATION
Chris Mason [Mon, 29 Nov 2010 14:49:11 +0000]
Btrfs: don't use migrate page without CONFIG_MIGRATION

Fixes compile error

Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: deal with DIO bios that span more than one ordered extent
Chris Mason [Mon, 29 Nov 2010 00:56:33 +0000]
Btrfs: deal with DIO bios that span more than one ordered extent

The new DIO bio splitting code has problems when the bio
spans more than one ordered extent.  This will happen as the
generic DIO code merges our get_blocks calls together into
a bigger single bio.

This fixes things by walking forward in the ordered extent
code finding all the overlapping ordered extents and completing them
all at once.

Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: setup blank root and fs_info for mount time
Josef Bacik [Fri, 19 Nov 2010 19:59:15 +0000]
Btrfs: setup blank root and fs_info for mount time

There is a problem with how we use sget, it searches through the list of supers
attached to the fs_type looking for a super with the same fs_devices as what
we're trying to mount.  This depends on sb->s_fs_info being filled, but we don't
fill that in until we get to btrfs_fill_super, so we could hit supers on the
fs_type super list that have a null s_fs_info.  In order to fix that we need to
go ahead and setup a blank root with a blank fs_info to hold fs_devices, that
way our test will work out right and then we can set s_fs_info in
btrfs_set_super, and then open_ctree will simply use our pre-allocated root and
fs_info when setting everything up.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: fix fiemap
Josef Bacik [Tue, 23 Nov 2010 19:36:57 +0000]
Btrfs: fix fiemap

There are two big problems currently with FIEMAP

1) We return extents for holes.  This isn't supposed to happen, we just don't
return extents for holes and then userspace interprets the lack of an extent as
a hole.

2) We sometimes don't set FIEMAP_EXTENT_LAST properly.  This is because we wait
to see a EXTENT_FLAG_VACANCY flag on the em, but this won't happen if say we ask
fiemap to map up to the last extent in a file, and there is nothing but holes up
to the i_size.  To fix this we need to lookup the last extent in this file and
save the logical offset, so if we happen to try and map that extent we can be

With this patch we now pass xfstest 225, which we never have before.

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs - fix race between btrfs_get_sb() and umount
Ian Kent [Mon, 22 Nov 2010 02:21:38 +0000]
Btrfs - fix race between btrfs_get_sb() and umount

When mounting a btrfs file system btrfs_test_super() may attempt to
use sb->s_fs_info, the btrfs root, of a super block that is going away
and that has had the btrfs root set to NULL in its ->put_super(). But
if the super block is going away it cannot be an existing super block
so we can return false in this case.

Signed-off-by: Ian Kent <raven@themaw.net>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: update inode ctime when using links
Josef Bacik [Tue, 23 Nov 2010 19:50:59 +0000]
Btrfs: update inode ctime when using links

Currently we fail xfstest 236 because we're not updating the inode ctime on
link.  This is a simple fix, and makes it so we pass 236 now.

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: make sure new inode size is ok in fallocate
Josef Bacik [Mon, 22 Nov 2010 18:55:39 +0000]
Btrfs: make sure new inode size is ok in fallocate

We have been failing xfstest 228 forever, because we don't check to make sure
the new inode size is acceptable as far as RLIMIT is concerned.  Just check to
make sure it's ok to create a inode with this new size and error out if not.
With this patch we now pass 228.

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: fix typo in fallocate to make it honor actual size
Josef Bacik [Mon, 22 Nov 2010 18:50:32 +0000]
Btrfs: fix typo in fallocate to make it honor actual size

There is a typo in __btrfs_prealloc_file_range() where we set the i_size to
actual_len/cur_offset, and then just set it to cur_offset again, and do the same
with btrfs_ordered_update_i_size().  This fixes it back to keeping i_size in a
local variable and then updating i_size properly.  Tested this with

xfs_io -F -f -c "falloc 0 1" -c "pwrite 0 1" foo

stat'ing foo gives us a size of 1 instead of 4096 like it was.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: avoid NULL pointer deref in try_release_extent_buffer
Chris Mason [Mon, 22 Nov 2010 03:27:44 +0000]
Btrfs: avoid NULL pointer deref in try_release_extent_buffer

If we fail to find a pointer in the radix tree, don't try
to deref the NULL one we do have.

Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: make btrfs_add_nondir take parent inode as an argument
Josef Bacik [Fri, 19 Nov 2010 20:36:11 +0000]
Btrfs: make btrfs_add_nondir take parent inode as an argument

Everybody who calls btrfs_add_nondir just passes in the dentry of the new file
and then dereference dentry->d_parent->d_inode, but everybody who calls
btrfs_add_nondir() are already passed the parent's inode.  So instead of
dereferencing dentry->d_parent, just make btrfs_add_nondir take the dir inode as
an argument and pass that along so we don't have to worry about d_parent.

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: hold i_mutex when calling btrfs_log_dentry_safe
Josef Bacik [Fri, 19 Nov 2010 20:36:10 +0000]
Btrfs: hold i_mutex when calling btrfs_log_dentry_safe

Since we walk up the path logging all of the parts of the inode's path, we need
to hold i_mutex to make sure that the inode is not renamed while we're logging
everything.  btrfs_log_dentry_safe does dget_parent and all of that jazz, but we
may get unexpected results if the rename changes the inode's location while
we're higher up the path logging those dentries, so do this for safety reasons.

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: use dget_parent where we can UPDATED
Josef Bacik [Sat, 20 Nov 2010 09:48:00 +0000]
Btrfs: use dget_parent where we can UPDATED

There are lots of places where we do dentry->d_parent->d_inode without holding
the dentry->d_lock.  This could cause problems with rename.  So instead we need
to use dget_parent() and hold the reference to the parent as long as we are
going to use it's inode and then dput it at the end.

Signed-off-by: Josef Bacik <josef@redhat.com>
Cc: raven@themaw.net
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: fix more ESTALE problems with NFS
Josef Bacik [Fri, 19 Nov 2010 02:18:02 +0000]
Btrfs: fix more ESTALE problems with NFS

When creating new inodes we don't setup inode->i_generation.  So if we generate
an fh with a newly created inode we save the generation of 0, but if we flush
the inode to disk and have to read it back when getting the inode on the server
we'll have the right i_generation, so gens wont match and we get ESTALE.  This
patch properly sets inode->i_generation when we create the new inode and now I'm
no longer getting ESTALE.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: handle NFS lookups properly
Josef Bacik [Wed, 17 Nov 2010 18:54:54 +0000]
Btrfs: handle NFS lookups properly

People kept reporting NFS issues, specifically getting ESTALE alot.  I figured
out how to reproduce the problem

mkfs.btrfs /dev/sda1
mount /dev/sda1 /mnt/btrfs-test
<add /mnt/btrfs-test to /etc/exports>
btrfs subvol create /mnt/btrfs-test/foo
service nfs start

mount server:/mnt/btrfs /mnt/test
cd /mnt/test/foo

echo 3 > /proc/sys/vm/drop_caches

ls <-- get an ESTALE here

This is because the standard way to lookup a name in nfsd is to use readdir, and
what it does is do a readdir on the parent directory looking for the inode of
the child.  So in this case the parent being / and the child being foo.  Well
subvols all have the same inode number, so doing a readdir of / looking for
inode 256 will return '.', which obviously doesn't match foo.  So instead we
need to have our own .get_name so that we can find the right name.

Our .get_name will either lookup the inode backref or the root backref,
whichever we're looking for, and return the name we find.  Running the above
reproducer with this patch results in everything acting the way its supposed to.

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: make 1-bit signed fileds unsigned
Mariusz Kozlowski [Sat, 20 Nov 2010 12:03:07 +0000]
btrfs: make 1-bit signed fileds unsigned

Fixes these sparse warnings:
fs/btrfs/ctree.h:811:17: error: dubious one-bit signed bitfield
fs/btrfs/ctree.h:812:20: error: dubious one-bit signed bitfield
fs/btrfs/ctree.h:813:19: error: dubious one-bit signed bitfield

Signed-off-by: Mariusz Kozlowski <mk@lab.zgora.pl>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: Show device attr correctly for symlinks
Li Zefan [Fri, 19 Nov 2010 02:05:24 +0000]
btrfs: Show device attr correctly for symlinks

Symlinks and files of other types show different device numbers, though
they are on the same partition:

 $ touch tmp; ln -s tmp tmp2; stat tmp tmp2
   File: `tmp'
   Size: 0          Blocks: 0          IO Block: 4096   regular empty file
 Device: 15h/21d Inode: 984027      Links: 1
 --- snip ---
   File: `tmp2' -> `tmp'
   Size: 3          Blocks: 0          IO Block: 4096   symbolic link
 Device: 13h/19d Inode: 984028      Links: 1

Reported-by: Toke Høiland-Jørgensen <toke@toke.dk>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: Set file size correctly in file clone
Li Zefan [Fri, 19 Nov 2010 01:36:34 +0000]
btrfs: Set file size correctly in file clone

Set src_offset = 0, src_length = 20K, dest_offset = 20K. And the
original filesize of the dest file 'file2' is 30K:

  # ls -l /mnt/file2
  -rw-r--r-- 1 root root 30720 Nov 18 16:42 /mnt/file2

Now clone file1 to file2, the dest file should be 40K, but it
still shows 30K:

  # ls -l /mnt/file2
  -rw-r--r-- 1 root root 30720 Nov 18 16:42 /mnt/file2

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agobtrfs: Check if dest_offset is block-size aligned before cloning file
Li Zefan [Fri, 19 Nov 2010 01:36:10 +0000]
btrfs: Check if dest_offset is block-size aligned before cloning file

We've done the check for src_offset and src_length, and We should
also check dest_offset, otherwise we'll corrupt the destination

  (After cloning file1 to file2 with unaligned dest_offset)
  # cat /mnt/file2
  cat: /mnt/file2: Input/output error

Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>

8 years agoBtrfs: handle the space_cache option properly
Josef Bacik [Fri, 19 Nov 2010 13:40:41 +0000]
Btrfs: handle the space_cache option properly

When I added the clear_cache option I screwed up and took the break out of
the space_cache case statement, so whenever you mount with space_cache you also
get clear_cache, which does you no good if you say set space_cache in fstab so
it always gets set.  This patch adds the break back in properly.

Signed-off-by: Josef Bacik <josef@redhat.com>
Signed-off-by: Chris Mason <chris.mason@oracle.com>