openwrt/staging/blogic.git
12 years agoBtrfs: fix memory leak in btrfs_quota_enable()
Tsutomu Itoh [Tue, 16 Oct 2012 05:44:21 +0000 (05:44 +0000)]
Btrfs: fix memory leak in btrfs_quota_enable()

We should free quota_root before returning from the error
handling code.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
12 years agoBtrfs: send correct rdev and mode in btrfs-send
Arne Jansen [Mon, 15 Oct 2012 18:28:46 +0000 (18:28 +0000)]
Btrfs: send correct rdev and mode in btrfs-send

When sending a device file, the stream was missing the mode. Also the
rdev was encoded wrongly.

Signed-off-by: Arne Jansen <sensille@gmx.net>
12 years agoBtrfs: extended inode refs support for send mechanism
Jan Schmidt [Mon, 15 Oct 2012 08:30:45 +0000 (08:30 +0000)]
Btrfs: extended inode refs support for send mechanism

This adds support for the new extended inode refs to btrfs send.

Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
12 years agoBtrfs: Fix wrong error handling code
Stefan Behrens [Thu, 11 Oct 2012 13:25:16 +0000 (07:25 -0600)]
Btrfs: Fix wrong error handling code

gcc says "warning: comparison of unsigned expression >= 0 is always
true" because i is an unsigned long. And gcc is right this time.

Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
12 years agoFix a sign bug causing invalid memory access in the ino_paths ioctl.
Gabriel de Perthuis [Wed, 10 Oct 2012 14:50:47 +0000 (08:50 -0600)]
Fix a sign bug causing invalid memory access in the ino_paths ioctl.

To see the problem, create many hardlinks to the same file (120 should do it),
then look up paths by inode with:

  ls -i
  btrfs inspect inode-resolve -v $ino /mnt/btrfs

I noticed the memory layout of the fspath->val data had some irregularities
(some unnecessary gaps that stop appearing about halfway),
so I'm not sure there aren't any bugs left in it.

12 years agobtrfs: init ref_index to zero in add_inode_ref
Chris Mason [Tue, 9 Oct 2012 15:17:20 +0000 (11:17 -0400)]
btrfs: init ref_index to zero in add_inode_ref

Signed-off-by: Chris Mason <chris.mason@fusionio.com>
12 years agoBtrfs: remove repeated eb->pages check in, disk-io.c/csum_dirty_buffer
Wang Sheng-Hui [Mon, 8 Oct 2012 13:26:15 +0000 (07:26 -0600)]
Btrfs: remove repeated eb->pages check in, disk-io.c/csum_dirty_buffer

In csum_dirty_buffer, we first get eb from page->private.
Then we check if the page is the first page of eb. Later
we check it again. Remove the repeated check here.

Signed-off-by: Wang Sheng-Hui <shhuiw@gmail.com>
12 years agoBtrfs: fix page leakage
Josef Bacik [Fri, 5 Oct 2012 20:53:34 +0000 (16:53 -0400)]
Btrfs: fix page leakage

Alloc_dummy_extent_buffer will not free the first page in the eb array if we
fail to allocate a page, fix this.  Thanks,

Reported-by: David Sterba <dave@jikos.cz>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: do not warn_on when we cannot alloc a page for an extent buffer
Josef Bacik [Fri, 5 Oct 2012 20:43:45 +0000 (16:43 -0400)]
Btrfs: do not warn_on when we cannot alloc a page for an extent buffer

It's just annoying and the user will have gotten a nice OOM killer message
so they are already fully aware they are screwed :).  Thanks,

Reported-by: Jérôme Poulin <jeromepoulin@gmail.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: don't bug on enomem in readpage
Josef Bacik [Fri, 5 Oct 2012 20:40:32 +0000 (16:40 -0400)]
Btrfs: don't bug on enomem in readpage

Get rid of the BUG_ON(ret == -ENOMEM) in __extent_read_full_page.  Thanks,

Reported-by: Jérôme Poulin <jeromepoulin@gmail.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: cleanup pages properly when ENOMEM in compression
Josef Bacik [Fri, 5 Oct 2012 17:39:50 +0000 (13:39 -0400)]
Btrfs: cleanup pages properly when ENOMEM in compression

We were freeing non-existent pages which was causing a panic for a user who
was suffering from ENOMEM.  This patch fixes the problem.  Thanks,

Reported-by: Jérôme Poulin <jeromepoulin@gmail.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: make filesystem read-only when submitting barrier fails
Stefan Behrens [Wed, 1 Aug 2012 16:56:49 +0000 (18:56 +0200)]
Btrfs: make filesystem read-only when submitting barrier fails

So far the return code of barrier_all_devices() is ignored, which
means that errors are ignored. The result can be a corrupt
filesystem which is not consistent.
This commit adds code to evaluate the return code of
barrier_all_devices(). The normal btrfs_error() mechanism is used to
switch the filesystem into read-only mode when errors are detected.

In order to decide whether barrier_all_devices() should return
error or success, the number of disks that are allowed to fail the
barrier submission is calculated. This calculation accounts for the
worst RAID level of metadata, system and data. If single, dup or
RAID0 is in use, a single disk error is already considered to be
fatal. Otherwise a single disk error is tolerated.

The calculation of the number of disks that are tolerated to fail
the barrier operation is performed when the filesystem gets mounted,
when a balance operation is started and finished, and when devices
are added or removed.

Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
12 years agoBtrfs: detect corrupted filesystem after write I/O errors
Stefan Behrens [Tue, 31 Jul 2012 17:09:44 +0000 (11:09 -0600)]
Btrfs: detect corrupted filesystem after write I/O errors

In check-integrity, detect when a superblock is written that points
to blocks that have not been written to disk due to I/O write errors.

Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
12 years agoBtrfs: make compress and nodatacow mount options mutually exclusive
Andrei Popa [Thu, 20 Sep 2012 14:42:11 +0000 (08:42 -0600)]
Btrfs: make compress and nodatacow mount options mutually exclusive

If a filesystem is mounted with compression and then remounted by adding nodatacow,
the compression is disabled but the compress flag is still visible.
Also, if a filesystem is mounted with nodatacow and then remounted with compression,
nodatacow flag is still present but it's not active.
This patch:
- removes compress flags and notifies that the compression has been disabled if the
  filesystem is mounted with nodatacow
- removes nodatacow and nodatasum flags if mounted with compress.

Signed-off-by: Andrei Popa <andrei.popa@i-neo.ro>
12 years agobtrfs: fix message printing
Daniel J Blueman [Mon, 7 May 2012 12:35:38 +0000 (06:35 -0600)]
btrfs: fix message printing

Fix various messages to include newline and module prefix.

Signed-off-by: Daniel J Blueman <daniel@quora.org>
12 years agoBtrfs: don't bother committing delayed inode updates when fsyncing
Josef Bacik [Tue, 25 Sep 2012 18:56:25 +0000 (14:56 -0400)]
Btrfs: don't bother committing delayed inode updates when fsyncing

We can just copy the in memory inode into the tree log directly, no sense in
updating the fs tree so we can copy it into the tree log tree.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agobtrfs: move inline function code to header file
Robin Dong [Sat, 29 Sep 2012 08:07:47 +0000 (02:07 -0600)]
btrfs: move inline function code to header file

When building btrfs from kernel code, it will report:

fs/btrfs/extent_io.h:281: warning: 'extent_buffer_page' declared inline after being called
fs/btrfs/extent_io.h:281: warning: previous declaration of 'extent_buffer_page' was here
fs/btrfs/extent_io.h:280: warning: 'num_extent_pages' declared inline after being called
fs/btrfs/extent_io.h:280: warning: previous declaration of 'num_extent_pages' was here

because of the wrong declaration of inline functions.

Signed-off-by: Robin Dong <sanbai@taobao.com>
12 years agoBtrfs: remove unnecessary IS_ERR in bio_readpage_error()
Tsutomu Itoh [Mon, 1 Oct 2012 09:07:15 +0000 (03:07 -0600)]
Btrfs: remove unnecessary IS_ERR in bio_readpage_error()

Because the value of extent_map is only a correct value or NULL,
so IS_ERR is unnecessary.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
12 years agobtrfs: remove unused function btrfs_insert_some_items()
Robin Dong [Sat, 29 Sep 2012 08:07:46 +0000 (02:07 -0600)]
btrfs: remove unused function btrfs_insert_some_items()

The function btrfs_insert_some_items() would not be called by any other functions,
so remove it.

Signed-off-by: Robin Dong <sanbai@taobao.com>
12 years agoBtrfs: don't commit instead of overcommitting
Josef Bacik [Fri, 28 Sep 2012 20:04:19 +0000 (16:04 -0400)]
Btrfs: don't commit instead of overcommitting

I don't think we have the same problem that this was supposed to fix
originally since we can allocate chunks in the enospc path now.  This code
is causing us to constantly commit the transaction as we get close to using
all of our available space in our currently allocated chunks, instead of
allocating another chunk and carrying on with life, which is not nice for
performance.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: confirmation of value is added before trace_btrfs_get_extent() is called
Tsutomu Itoh [Mon, 1 Oct 2012 09:08:37 +0000 (03:08 -0600)]
Btrfs: confirmation of value is added before trace_btrfs_get_extent() is called

We should confirm the value of extent_map before calling
trace_btrfs_get_extent() because the value of extent_map has the
possibility of NULL.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
12 years agoBtrfs: be smarter about dropping things from the tree log
Josef Bacik [Fri, 28 Sep 2012 15:56:28 +0000 (11:56 -0400)]
Btrfs: be smarter about dropping things from the tree log

When we truncate existing items in the tree log we've been searching for
each individual item and removing them.  This is unnecessary churn and
searching, just keep track of the slot we are on and how many items we need
to delete and delete them all at once.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: don't lookup csums for prealloc extents
Josef Bacik [Wed, 26 Sep 2012 15:07:06 +0000 (11:07 -0400)]
Btrfs: don't lookup csums for prealloc extents

The tree logging stuff was looking up csums to copy over for prealloc
extents which is just work we don't need to be doing.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: cache extent state when writing out dirty metadata pages
Josef Bacik [Thu, 27 Sep 2012 21:07:30 +0000 (17:07 -0400)]
Btrfs: cache extent state when writing out dirty metadata pages

Everytime we write out dirty pages we search for an offset in the tree,
convert the bits in the state, and then when we wait we search for the
offset again and clear the bits.  So for every dirty range in the io tree we
are doing 4 rb searches, which is suboptimal.  With this patch we are only
doing 2 searches for every cycle (modulo weird things happening).  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: do not hold the file extent leaf locked when adding extent item
Josef Bacik [Tue, 25 Sep 2012 19:26:16 +0000 (15:26 -0400)]
Btrfs: do not hold the file extent leaf locked when adding extent item

For some reason we unlock everything except the leaf we are on, set the path
blocking and then add the extent item for the extent we just finished
writing.  I can't for the life of me figure out why we would want to do
this, and the history doesn't really indicate that there was a real reason
for it, so just remove it.  This will reduce our tree lock contention on
heavy writes.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: do not async metadata csumming in certain situations
Josef Bacik [Tue, 25 Sep 2012 18:25:58 +0000 (14:25 -0400)]
Btrfs: do not async metadata csumming in certain situations

There are a coule scenarios where farming metadata csumming off to an async
thread doesn't help.  The first is if our processor supports crc32c, in
which case the csumming will be fast and so the overhead of the async model
is not worth the cost.  The other case is for our tree log.  We will be
making that stuff dirty and writing it out and waiting for it immediately.
Even with software crc32c this gives me a ~15% increase in speed with O_SYNC
workloads.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agobtrfs: fix min csum item size warnings in 32bit
Zach Brown [Thu, 20 Sep 2012 20:33:00 +0000 (14:33 -0600)]
btrfs: fix min csum item size warnings in 32bit

commit 7ca4be45a0255ac8f08c05491c6add2dd87dd4f8 limited csum items to
PAGE_CACHE_SIZE.  It used min() with incompatible types in 32bit which
generates warnings:

fs/btrfs/file-item.c: In function ‘btrfs_csum_file_blocks’:
fs/btrfs/file-item.c:717: warning: comparison of distinct pointer types lacks a cast

This uses min_t(u32,) to fix the warnings.  u32 seemed reasonable
because btrfs_root->leafsize is u32 and PAGE_CACHE_SIZE is unsigned
long.

Signed-off-by: Zach Brown <zab@zabbo.net>
12 years agoBtrfs: run delayed refs first when out of space
Josef Bacik [Mon, 24 Sep 2012 17:42:00 +0000 (13:42 -0400)]
Btrfs: run delayed refs first when out of space

Running delayed refs is faster than running delalloc, so lets do that first
to try and reclaim space.  This makes my fs_mark test about 20% faster.
Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: fix orphan transaction on the freezed filesystem
Miao Xie [Thu, 20 Sep 2012 07:54:00 +0000 (01:54 -0600)]
Btrfs: fix orphan transaction on the freezed filesystem

With the following debug patch:

 static int btrfs_freeze(struct super_block *sb)
 {
+  struct btrfs_fs_info *fs_info = btrfs_sb(sb);
+ struct btrfs_transaction *trans;
+
+ spin_lock(&fs_info->trans_lock);
+ trans = fs_info->running_transaction;
+ if (trans) {
+ printk("Transid %llu, use_count %d, num_writer %d\n",
+ trans->transid, atomic_read(&trans->use_count),
+ atomic_read(&trans->num_writers));
+ }
+ spin_unlock(&fs_info->trans_lock);
  return 0;
 }

I found there was a orphan transaction after the freeze operation was done.

It is because the transaction may not be committed when the transaction handle
end even though it is the last handle of the current transaction. This design
avoid committing the transaction frequently, but also introduce the above
problem.

So I add btrfs_attach_transaction() which can catch the current transaction
and commit it. If there is no transaction, it will return ENOENT, and do not
anything.

This function also can be used to instead of btrfs_join_transaction_freeze()
because it don't increase the writer counter and don't start a new transaction,
so it also can fix the deadlock between sync and freeze.

Besides that, it is used to instead of btrfs_join_transaction() in
transaction_kthread(), because if there is no transaction, the transaction
kthread needn't anything.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: add a type field for the transaction handle
Miao Xie [Thu, 20 Sep 2012 07:51:59 +0000 (01:51 -0600)]
Btrfs: add a type field for the transaction handle

This patch add a type field into the transaction handle structure,
in this way, we needn't implement various end-transaction functions
and can make the code more simple and readable.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: fix memory leak in start_transaction()
Miao Xie [Thu, 20 Sep 2012 04:14:29 +0000 (22:14 -0600)]
Btrfs: fix memory leak in start_transaction()

This patch fixes memory leak of the transaction handle which happened
when starting transaction failed on a freezed fs.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agobtrfs: extended inode ref iteration
Mark Fasheh [Wed, 8 Aug 2012 18:33:54 +0000 (11:33 -0700)]
btrfs: extended inode ref iteration

The iterate_irefs in backref.c is used to build path components from inode
refs. This patch adds code to iterate extended refs as well.

I had modify the callback function signature to abstract out some of the
differences between ref structures. iref_to_path() also needed similar
changes.

Signed-off-by: Mark Fasheh <mfasheh@suse.de>
12 years agobtrfs: extended inode refs
Mark Fasheh [Wed, 8 Aug 2012 18:32:27 +0000 (11:32 -0700)]
btrfs: extended inode refs

This patch adds basic support for extended inode refs. This includes support
for link and unlink of the refs, which basically gets us support for rename
as well.

Inode creation does not need changing - extended refs are only added after
the ref array is full.

Signed-off-by: Mark Fasheh <mfasheh@suse.de>
12 years agobtrfs: improved readablity for add_inode_ref
Jan Schmidt [Fri, 17 Aug 2012 21:04:41 +0000 (14:04 -0700)]
btrfs: improved readablity for add_inode_ref

Moved part of the code into a sub function and replaced most of the gotos
by ifs, hoping that it will be easier to read now.

Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Signed-off-by: Mark Fasheh <mfasheh@suse.de>
12 years agoBtrfs: handle not finding the extent exactly when logging changed extents
Josef Bacik [Wed, 19 Sep 2012 19:42:38 +0000 (15:42 -0400)]
Btrfs: handle not finding the extent exactly when logging changed extents

I started hitting warnings when running xfstest 68 in a loop because there
were EM's that were not lined up properly with the physical extents.  This
is ok, if we do something like punch a hole or write to a preallocated space
or something like that we can have an EM that doesn't cover the entire
physical extent.  So fix the tree logging stuff to cope with this case so we
don't just commit the transaction.  With this patch I no longer see the
warnings from the tree logging code.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agobtrfs: move transaction aborts to the point of failure
David Sterba [Tue, 18 Sep 2012 13:52:32 +0000 (07:52 -0600)]
btrfs: move transaction aborts to the point of failure

Call btrfs_abort_transaction as early as possible when an error
condition is detected, that way the line number reported is useful
and we're not clueless anymore which error path led to the abort.

Signed-off-by: David Sterba <dsterba@suse.cz>
12 years agoBtrfs: fix the missing error information in create_pending_snapshot()
Miao Xie [Tue, 18 Sep 2012 05:52:38 +0000 (23:52 -0600)]
Btrfs: fix the missing error information in create_pending_snapshot()

The macro btrfs_abort_transaction() can get the line number of the code
where the problem happens, so we should invoke it in the place that the
error occurs, or we will lose the line number.

Reported-by: David Sterba <dave@jikos.cz>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: fix off-by-one in file clone
Liu Bo [Tue, 18 Sep 2012 09:52:23 +0000 (03:52 -0600)]
Btrfs: fix off-by-one in file clone

Btrfs uses inclusive range end for lock_extent(), unlock_extent() and
related functions, so we made off-by-one errors in file clone.

This fixes it and also fixes some style problems.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agobtrfs: allow setting NOCOW for a zero sized file via ioctl
David Sterba [Fri, 7 Sep 2012 11:56:55 +0000 (05:56 -0600)]
btrfs: allow setting NOCOW for a zero sized file via ioctl

Hi,

the patch si simple, but it has user visible impact and I'm not quite sure how
to resolve it.

In short, $subj says it, chattr -C supports it and we want to use it.

The conditions that acutally allow to change the NOCOW flag are clear. What if
I try to set the flag on a file that is not empty? Options:

1) whole ioctl will fail, EINVAL
2.1) ioctl will succeed, the NOCOW flag will be silently removed, but the file
     will stay COW-ed and checksummed
2.2) ioctl will succeed, flag will not be removed and a syslog message will
     warn that the COW flag has not been changed
2.2.1) dtto, no syslog message

Man page of chattr states that

 "If it is set on a file which already has data blocks, it is undefined when
 the blocks assigned to the file will be fully stable."

Yes, it's undefined and with current implementation it'll never happen. So from
this end, the user cannot expect anything. I'm trying to find a reasonable
behaviour, so that a command like 'chattr -R -aijS +C' to tweak a broad set of
flags in a deep directory does not fail unnecessarily and does not pollute the
log.

My personal preference is 2.2.1, but my dev's oppinion is skewed, not counting
the fact that I know the code and otherwise would look there before consulting
the documentation.

The patch implements 2.2.1.

david

-------------8<-------------------
From: David Sterba <dsterba@suse.cz>

It's safe to turn off checksums for a zero sized file.

http://thread.gmane.org/gmane.comp.file-systems.btrfs/18030

"We cannot switch on NODATASUM for a file that already has extents that
are checksummed. The invariant here is that either all the extents or
none are checksummed.

Theoretically it's possible to add/remove all checksums from a given
file, but it's a potentially longtime operation, the file has to be in
some intermediate state where the checksums partially exist but have to
be ignored (for the csum->nocsum) until the file is fully converted,
this brings more special cases to extent handling, it has to survive
power failure and remain consistent, and probably needs to be restarted
after next mount."

Signed-off-by: David Sterba <dsterba@suse.cz>
12 years agoBtrfs: fix punch hole when no extent exists
Josef Bacik [Fri, 14 Sep 2012 18:51:22 +0000 (14:51 -0400)]
Btrfs: fix punch hole when no extent exists

I saw the warning in btrfs_drop_extent_cache where our end is less than our
start while running xfstests 68 in a loop.  This is because we
unconditionally do drop_end = min(end, extent_end) in
__btrfs_drop_extents(), even though we may not have found an extent in the
range we were looking to drop.  So keep track of wether or not we found
something, and if we didn't just use our end.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: don't do anything in our ->freeze_fs and ->unfreeze_fs
Josef Bacik [Fri, 14 Sep 2012 17:58:59 +0000 (13:58 -0400)]
Btrfs: don't do anything in our ->freeze_fs and ->unfreeze_fs

We do not need to do anything special to freeze or unfreeze, it's all taken
care of by the generic work, and what we currently have is wrong anyway
since we shouldn't be returnning to userspace with mutexes held anyway.
Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: remove unused write cache pages hook
Josef Bacik [Fri, 14 Sep 2012 17:51:53 +0000 (13:51 -0400)]
Btrfs: remove unused write cache pages hook

The btree inode has it's own write cache pages so we can remove this write
cache pages hook as it's not used.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: fix race when getting the eb out of page->private
Josef Bacik [Fri, 14 Sep 2012 17:43:01 +0000 (13:43 -0400)]
Btrfs: fix race when getting the eb out of page->private

We can race when checking wether PagePrivate is set on a page and we
actually have an eb saved in the pages private pointer.  We could have
easily written out this page and released it in the time that we did the
pagevec lookup and actually got around to looking at this page.  So use
mapping->private_lock to ensure we get a consistent view of the
page->private pointer.  This is inline with the alloc and releasepage paths
which use private_lock when manipulating page->private.  Thanks,

Reported-by: David Sterba <dave@jikos.cz>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: do not hold the write_lock on the extent tree while logging
Josef Bacik [Fri, 14 Sep 2012 16:59:20 +0000 (12:59 -0400)]
Btrfs: do not hold the write_lock on the extent tree while logging

Dave Sterba pointed out a sleeping while atomic bug while doing fsync.  This
is because I'm an idiot and didn't realize that rwlock's were spin locks, so
we've been holding this thing while doing allocations and such which is not
good.  This patch fixes this by dropping the write lock before we do
anything heavy and re-acquire it when it is done.  We also need to take a
ref on the em's in case their corresponding pages are evicted and mark them
as being logged so that releasepage does not remove them and doesn't remove
them from our local list.  Thanks,

Reported-by: Dave Sterba <dave@jikos.cz>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: fix race with freeze and free space inodes
Josef Bacik [Fri, 14 Sep 2012 15:22:38 +0000 (11:22 -0400)]
Btrfs: fix race with freeze and free space inodes

So we start our freeze, somebody comes in and does an fsync() on a file
where we have to commit a transaction for whatever reason, and we will
deadlock because the freeze is waiting on FS_FREEZE people to stop writing
to the file system, but the transaction is waiting for its free space inodes
to be written out, which are in turn waiting on sb_start_intwrite while
trying to write the file extents.  To fix this we'll just skip the
sb_start_intwrite() if we TRANS_JOIN_NOLOCK since we're being waited on by a
transaction commit so we're safe wrt to freeze and this will keep us from
deadlocking.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: kill obsolete arguments in btrfs_wait_ordered_extents
Liu Bo [Fri, 14 Sep 2012 08:58:07 +0000 (02:58 -0600)]
Btrfs: kill obsolete arguments in btrfs_wait_ordered_extents

nocow_only is now an obsolete argument.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agoBtrfs: cleanup fs_info->hashers
Liu Bo [Fri, 14 Sep 2012 08:58:06 +0000 (02:58 -0600)]
Btrfs: cleanup fs_info->hashers

fs_info->hashers is now an obsolete one.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agoBtrfs: cleanup for duplicated code in find_free_extent
Liu Bo [Fri, 14 Sep 2012 08:58:05 +0000 (02:58 -0600)]
Btrfs: cleanup for duplicated code in find_free_extent

There is already an 'add free space' phrase in front of this one, we
needn't to redo it.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agoBtrfs: fix race in sync and freeze again
Josef Bacik [Fri, 14 Sep 2012 14:34:40 +0000 (10:34 -0400)]
Btrfs: fix race in sync and freeze again

I screwed this up, there is a race between checking if there is a running
transaction and actually starting a transaction in sync where we could race
with a freezer and get ourselves into trouble.  To fix this we need to make
a new join type to only do the try lock on the freeze stuff.  If it fails
we'll return EPERM and just return from sync.  This fixes a hang Liu Bo
reported when running xfstest 68 in a loop.  Thanks,

Reported-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agobtrfs: return EPERM upon rmdir on a subvolume
David Sterba [Thu, 13 Sep 2012 22:04:34 +0000 (16:04 -0600)]
btrfs: return EPERM upon rmdir on a subvolume

A subvolume cannot be deleted via rmdir, but the error code ENOTEMPTY
is confusing. Return EPERM instead, as this is not permitted.

Signed-off-by: David Sterba <dsterba@suse.cz>
12 years agoBtrfs: using for_each_set_bit_from to simplify the code
Wei Yongjun [Fri, 14 Sep 2012 02:29:02 +0000 (20:29 -0600)]
Btrfs: using for_each_set_bit_from to simplify the code

Using for_each_set_bit_from() to simplify the code.

spatch with a semantic match is used to found this.
(http://coccinelle.lip6.fr/)

Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
12 years agoBtrfs: write_buf is now callable outside send.c
Anand Jain [Fri, 14 Sep 2012 06:04:21 +0000 (00:04 -0600)]
Btrfs: write_buf is now callable outside send.c

Developing service cmds needs it.

Signed-off-by: Anand Jain <anand.jain@oracle.com>
12 years agoBtrfs: remove unnecessary code in btree_get_extent()
Tsutomu Itoh [Thu, 13 Sep 2012 09:32:54 +0000 (03:32 -0600)]
Btrfs: remove unnecessary code in btree_get_extent()

Unnecessary lookup_extent_mapping() is removed because an error is
returned to the caller.
This patch was made based on the advice from Stefan Behrens, thanks.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
12 years agoBtrfs: cleanup of error processing in btree_get_extent()
Tsutomu Itoh [Thu, 13 Sep 2012 09:32:32 +0000 (03:32 -0600)]
Btrfs: cleanup of error processing in btree_get_extent()

This patch simplifies a little complex error processing in
btree_get_extent().

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
12 years agoRevert "Btrfs: do not do filemap_write_and_wait_range in fsync"
Miao Xie [Thu, 13 Sep 2012 10:53:47 +0000 (04:53 -0600)]
Revert "Btrfs: do not do filemap_write_and_wait_range in fsync"

This reverts commit 0885ef5b5601e9b007c383e77c172769b1f214fd

After applying the above patch, the performance slowed down because the dirty
page flush can only be done by one task, so revert it.

The following is the test result of sysbench:
Before After
24MB/s 39MB/s

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: remove bytes argument from do_chunk_alloc
Josef Bacik [Wed, 12 Sep 2012 18:08:47 +0000 (14:08 -0400)]
Btrfs: remove bytes argument from do_chunk_alloc

Everybody is just making stuff up, and it's just used to see if we really do
need to alloc a chunk, and since we do this when we already know we really
do it's just a waste of space.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: delay block group item insertion
Josef Bacik [Tue, 11 Sep 2012 20:57:25 +0000 (16:57 -0400)]
Btrfs: delay block group item insertion

So we have lots of places where we try to preallocate chunks in order to
make sure we have enough space as we make our allocations.  This has
historically meant that we're constantly tweaking when we should allocate a
new chunk, and historically we have gotten this horribly wrong so we way
over allocate either metadata or data.  To try and keep this from happening
we are going to make it so that the block group item insertion is done out
of band at the end of a transaction.  This will allow us to create chunks
even if we are trying to make an allocation for the extent tree.  With this
patch my enospc tests run faster (didn't expect this) and more efficiently
use the disk space (this is what I wanted).  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agobtrfs: Kill some bi_idx references
Kent Overstreet [Tue, 11 Sep 2012 20:23:05 +0000 (14:23 -0600)]
btrfs: Kill some bi_idx references

For immutable bio vecs, I've been auditing and removing bi_idx
references. These were harmless, but removing them will make auditing
easier.

scrub_bio_end_io_worker() was open coding a bio_reset() - but this
doesn't appear to have been needed for anything as right after it does a
bio_put(), and perusing the code it doesn't appear anything else was
holding a reference to the bio.

The other use end_bio_extent_readpage() was just for a pr_debug() -
changed it to something that might be a bit more useful.

Signed-off-by: Kent Overstreet <koverstreet@google.com>
CC: Chris Mason <chris.mason@oracle.com>
CC: Stefan Behrens <sbehrens@giantdisaster.de>
12 years agoBtrfs: fix unnecessary warning when the fragments make the space alloc fail
Miao Xie [Wed, 12 Sep 2012 05:27:35 +0000 (23:27 -0600)]
Btrfs: fix unnecessary warning when the fragments make the space alloc fail

When we wrote some data by compress mode into a btrfs filesystem which was full
of the fragments, the kernel will report:
BTRFS warning (device xxx): Aborting unused transaction.

The reason is:
We can not find a long enough free space to store the compressed data because
of the fragmentary free space, and the compressed data can not be splited,
so the kernel outputed the above message.

In fact, btrfs can deal with this problem very well: it fall back to
uncompressed IO, split the uncompressed data into small ones, and then
store them into to the fragmentary free space. So we shouldn't output the
above warning message.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: create a pinned em when writing to a prealloc range in DIO
Josef Bacik [Tue, 11 Sep 2012 19:40:07 +0000 (15:40 -0400)]
Btrfs: create a pinned em when writing to a prealloc range in DIO

Wade Cline reported a problem where he was getting garbage and warnings when
writing to a preallocated range via O_DIRECT.  This is because we weren't
creating our normal pinned extent_map for the range we were writing to,
which was causing all sorts of issues.  This patch fixes the problem and
makes his testcase much happier.  Thanks,

Reported-by: Wade Cline <clinew@linux.vnet.ibm.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: move the sb_end_intwrite until after the throttle logic
Josef Bacik [Wed, 5 Sep 2012 14:08:30 +0000 (08:08 -0600)]
Btrfs: move the sb_end_intwrite until after the throttle logic

Sage reported the following lockdep backtrace

=====================================
[ BUG: bad unlock balance detected! ]
3.6.0-rc2-ceph-00171-gc7ed62d #1 Not tainted
-------------------------------------
btrfs-cleaner/7607 is trying to release lock (sb_internal) at:
[<ffffffffa00422ae>] btrfs_commit_transaction+0xa6e/0xb20 [btrfs]
but there are no more locks to release!

other info that might help us debug this:
1 lock held by btrfs-cleaner/7607:
 #0:  (&fs_info->cleaner_mutex){+.+...}, at: [<ffffffffa003b405>] cleaner_kthread+0x95/0x120 [btrfs]

stack backtrace:
Pid: 7607, comm: btrfs-cleaner Not tainted 3.6.0-rc2-ceph-00171-gc7ed62d #1
Call Trace:
 [<ffffffffa00422ae>] ? btrfs_commit_transaction+0xa6e/0xb20 [btrfs]
 [<ffffffff810afa9e>] print_unlock_inbalance_bug+0xfe/0x110
 [<ffffffff810b289e>] lock_release_non_nested+0x1ee/0x310
 [<ffffffff81172f9b>] ? kmem_cache_free+0x7b/0x160
 [<ffffffffa004106c>] ? put_transaction+0x8c/0x130 [btrfs]
 [<ffffffffa00422ae>] ? btrfs_commit_transaction+0xa6e/0xb20 [btrfs]
 [<ffffffff810b2a95>] lock_release+0xd5/0x220
 [<ffffffff81173071>] ? kmem_cache_free+0x151/0x160
 [<ffffffff8117d9ed>] __sb_end_write+0x7d/0x90
 [<ffffffffa00422ae>] btrfs_commit_transaction+0xa6e/0xb20 [btrfs]
 [<ffffffff81079850>] ? __init_waitqueue_head+0x60/0x60
 [<ffffffff81634c6b>] ? _raw_spin_unlock+0x2b/0x40
 [<ffffffffa0042758>] __btrfs_end_transaction+0x368/0x3c0 [btrfs]
 [<ffffffffa0042808>] btrfs_end_transaction_throttle+0x18/0x20 [btrfs]
 [<ffffffffa00318f0>] btrfs_drop_snapshot+0x410/0x600 [btrfs]
 [<ffffffff8132babd>] ? do_raw_spin_unlock+0x5d/0xb0
 [<ffffffffa00430ef>] btrfs_clean_old_snapshots+0xaf/0x150 [btrfs]
 [<ffffffffa003b405>] ? cleaner_kthread+0x95/0x120 [btrfs]
 [<ffffffffa003b419>] cleaner_kthread+0xa9/0x120 [btrfs]
 [<ffffffffa003b370>] ? btrfs_destroy_delayed_refs.isra.102+0x220/0x220 [btrfs]
 [<ffffffff810791ee>] kthread+0xae/0xc0
 [<ffffffff810b379d>] ? trace_hardirqs_on+0xd/0x10
 [<ffffffff8163e744>] kernel_thread_helper+0x4/0x10
 [<ffffffff81635430>] ? retint_restore_args+0x13/0x13
 [<ffffffff81079140>] ? flush_kthread_work+0x1a0/0x1a0
 [<ffffffff8163e740>] ? gs_change+0x13/0x13

This is because the throttle stuff can commit the transaction, which expects to
be the one stopping the intwrite stuff, but we've already done it in the
__btrfs_end_transaction.  Moving the sb_end_intewrite after this logic makes the
lockdep go away.  Thanks,

Tested-by: Sage Weil <sage@inktank.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: use larger limit for translation of logical to inode
Liu Bo [Sat, 8 Sep 2012 02:01:30 +0000 (20:01 -0600)]
Btrfs: use larger limit for translation of logical to inode

This is the change of the kernel side.

Translation of logical to inode used to have an upper limit 4k on
inode container's size, but the limit is not large enough for a data
with a great many of refs, so when resolving logical address,
we can end up with
"ioctl ret=0, bytes_left=0, bytes_missing=19944, cnt=510, missed=2493"

This changes to regard 64k as the upper limit and use vmalloc instead of
kmalloc to get memory more easily.

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agoBtrfs: use helper for logical resolve
Liu Bo [Sat, 8 Sep 2012 02:01:29 +0000 (20:01 -0600)]
Btrfs: use helper for logical resolve

We already have a helper, iterate_inodes_from_logical(), for logical resolve,
so just use it.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agoBtrfs: fix a bug in parsing return value in logical resolve
Liu Bo [Sat, 8 Sep 2012 02:01:28 +0000 (20:01 -0600)]
Btrfs: fix a bug in parsing return value in logical resolve

In logical resolve, we parse extent_from_logical()'s 'ret' as a kind of flag.

It is possible to lose our errors because
(-EXXXX & BTRFS_EXTENT_FLAG_TREE_BLOCK) is true.

I'm not sure if it is on purpose, it just looks too hacky if it is.
I'd rather use a real flag and a 'ret' to catch errors.

Acked-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Signed-off-by: Liu Bo <liub.liubo@gmail.com>
12 years agoBtrfs: update delayed ref's tracepoints to show sequence
Liu Bo [Sat, 8 Sep 2012 02:01:27 +0000 (20:01 -0600)]
Btrfs: update delayed ref's tracepoints to show sequence

We've added a new field 'sequence' to delayed ref node, so update related
tracepoints.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agoBtrfs: cleanup for unused ref cache stuff
liubo [Sat, 8 Sep 2012 02:01:26 +0000 (20:01 -0600)]
Btrfs: cleanup for unused ref cache stuff

As ref cache has been removed from btrfs, there is no user on
its lock and its check.

Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agoBtrfs: fix corrupted metadata in the snapshot
Miao Xie [Fri, 7 Sep 2012 07:43:32 +0000 (01:43 -0600)]
Btrfs: fix corrupted metadata in the snapshot

When we delete a inode, we will remove all the delayed items including delayed
inode update, and then truncate all the relative metadata. If there is lots of
metadata, we will end the current transaction, and start a new transaction to
truncate the left metadata. In this way, we will leave a inode item that its
link counter is > 0, and also may leave some directory index items in fs/file tree
after the current transaction ends. In other words, the metadata in this fs/file tree
is inconsistent. If we create a snapshot for this tree now, we will find a inode with
corrupted metadata in the new snapshot, and we won't continue to drop the left metadata,
because its link counter is not 0.

We fix this problem by updating the inode item before the current transaction ends.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agobtrfs: polish names of kmem caches
David Sterba [Fri, 7 Sep 2012 09:00:48 +0000 (03:00 -0600)]
btrfs: polish names of kmem caches

Usecase:

  watch 'grep btrfs < /proc/slabinfo'

easy to watch all caches in one go.

Signed-off-by: David Sterba <dsterba@suse.cz>
12 years agoBtrfs: fix our overcommit math
Josef Bacik [Thu, 6 Sep 2012 20:59:33 +0000 (16:59 -0400)]
Btrfs: fix our overcommit math

I noticed I was seeing large lags when running my torrent test in a vm on my
laptop.  While trying to make it lag less I noticed that our overcommit math
was taking into account the number of bytes we wanted to reclaim, not the
number of bytes we actually wanted to allocate, which means we wouldn't
overcommit as often.  This patch fixes the overcommit math and makes
shrink_delalloc() use that logic so that it will stop looping faster.  We
still have pretty high spikes of latency, but the test now takes 3 minutes
less time (about 5% faster).  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: wait on async pages when shrinking delalloc
Josef Bacik [Thu, 6 Sep 2012 20:47:00 +0000 (16:47 -0400)]
Btrfs: wait on async pages when shrinking delalloc

Mitch reported a problem where you could get an ENOSPC error when untarring
a kernel git tree onto a 16gb file system with compress-force=zlib.  This is
because compression is a huge pain, it will return from ->writepages()
without having actually created any ordered extents.  To get around this we
check to see if the async submit counter is up, and if it is wait until it
drops to 0 before doing our normal ordered wait dance.  With this patch I
can now untar a kernel git tree onto a 16gb file system without getting
ENOSPC errors.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: use flag EXTENT_DEFRAG for snapshot-aware defrag
Liu Bo [Thu, 6 Sep 2012 01:10:51 +0000 (19:10 -0600)]
Btrfs: use flag EXTENT_DEFRAG for snapshot-aware defrag

We're going to use this flag EXTENT_DEFRAG to indicate which range
belongs to defragment so that we can implement snapshow-aware defrag:

We set the EXTENT_DEFRAG flag when dirtying the extents that need
defragmented, so later on writeback thread can differentiate between
normal writeback and writeback started by defragmentation.

Original-Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agoBtrfs: check return value of ulist_alloc() properly
Tsutomu Itoh [Thu, 6 Sep 2012 06:18:10 +0000 (00:18 -0600)]
Btrfs: check return value of ulist_alloc() properly

ulist_alloc() has the possibility of returning NULL.
So, it is necessary to check the return value.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
12 years agoBtrfs: fix error handling in delete_block_group_cache()
Tsutomu Itoh [Thu, 6 Sep 2012 09:08:59 +0000 (03:08 -0600)]
Btrfs: fix error handling in delete_block_group_cache()

btrfs_iget() never return NULL.
So, NULL check is unnecessary.

Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
12 years agoBtrfs: fix wrong size for the reservation when doing, file pre-allocation.
Miao Xie [Thu, 6 Sep 2012 10:04:57 +0000 (04:04 -0600)]
Btrfs: fix wrong size for the reservation when doing, file pre-allocation.

When we ran fsstress(a program in xfstests), the filesystem hung up when it
is full. It was because the space reserved in btrfs_fallocate() was wrong,
btrfs_fallocate() just used the size of the pre-allocation to reserve the
space, didn't took the block size aligning into account, so the size of
the reserved space was less than the allocated space, it caused the over
reserve problem and made the filesystem hung up when invoking cow_file_range().
Fix it.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: output more information when aborting a unused transaction handle
Miao Xie [Thu, 6 Sep 2012 10:04:44 +0000 (04:04 -0600)]
Btrfs: output more information when aborting a unused transaction handle

Though we dump the stack information when aborting a unused transaction
handle, we don't know the correct place where we decide to abort the
transaction handle if one function has several place where the transaction
abort function is invoked and jumps to the same place after this call.
And beside that we also don't know the reason why we jump to abort
the current handle. So I modify the transaction abort function and make
it output the function name, line and error information.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: fix unprotected ->log_batch
Miao Xie [Thu, 6 Sep 2012 10:04:27 +0000 (04:04 -0600)]
Btrfs: fix unprotected ->log_batch

We forget to protect ->log_batch when syncing a file, this patch fix
this problem by atomic operation. And ->log_batch is used to check
if there are parallel sync operations or not, so it is unnecessary to
reset it to 0 after the sync operation of the current log tree complete.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: fix wrong size for the reservation of the, snapshot creation
Miao Xie [Thu, 6 Sep 2012 10:03:56 +0000 (04:03 -0600)]
Btrfs: fix wrong size for the reservation of the, snapshot creation

We should insert/update 6 items(root ref, root backref, dir item, dir index,
root item and parent inode) when creating a snapshot, not 5 items, fix it.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: fix the snapshot that should not exist
Miao Xie [Thu, 6 Sep 2012 10:03:32 +0000 (04:03 -0600)]
Btrfs: fix the snapshot that should not exist

The snapshot should be the image of the fs tree before it was created,
so the metadata of the snapshot should not exist in the its tree. But now, we
found the directory item and directory name index is in both the snapshot tree
and the fs tree. It introduces some problems and makes the users feel strange:

 # mkfs.btrfs /dev/sda1
 # mount /dev/sda1 /mnt
 # mkdir /mnt/1
 # cd /mnt/1
 # btrfs subvolume snapshot /mnt snap0
 # ls -a /mnt/1/snap0/1
 . .. [no other file/dir]

 # ll /mnt/1/snap0/
 total 0
 drwxr-xr-x 1 root root 10 Ju1 24 12:11 1
^^^
There is no file/dir in it, but it's size is 10

 # cd /mnt/1/snap0/1/snap0
 [Enter a unexisted directory successfully...]

There is nothing in the directory 1 in snap0, but btrfs told the length of
this directory is 10. Beside that, we can enter an unexisted directory, it is
very strange to the users.

 # btrfs subvolume snapshot /mnt/1/snap0 /mnt/snap1
 # ll /mnt/1/snap0/1/
 total 0
 [None]
 # ll /mnt/snap1/1/
 total 0
 drwxr-xr-x 1 root root 0 Ju1 24 12:14 snap0

And the source of snap1 did have any directory in Directory 1, but snap1 have
a snap0, it is different between the source and the snapshot.

So I think we should insert directory item and directory name index and update
the parent inode as the last step of snapshot creation, and do not leave the
useless metadata in the file tree.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: add a new "type" field into the block reservation structure
Miao Xie [Thu, 6 Sep 2012 10:02:28 +0000 (04:02 -0600)]
Btrfs: add a new "type" field into the block reservation structure

Sometimes we need choose the method of the reservation according to the type
of the block reservation, such as the reservation for the delayed inode update.
Now we identify the type just by comparing the address of the reservation
variants, it is very ugly if it is a temporary one because we need compare it
with all the common reservation variants. So we add a new "type" field to keep
the type the reservation variants.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: use a slab for ordered extents allocation
Miao Xie [Thu, 6 Sep 2012 10:01:51 +0000 (04:01 -0600)]
Btrfs: use a slab for ordered extents allocation

The ordered extent allocation is in the fast path of the IO, so use a slab
to improve the speed of the allocation.

 "Size of the struct is 280, so this will fall into the size-512 bucket,
  giving 8 objects per page, while own slab will pack 14 objects into a page.

  Another benefit I see is to check for leaked objects when the module is
  removed (and the cache destroy takes place)."
-- David Sterba

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: fix file extent discount problem in the, snapshot
Miao Xie [Thu, 6 Sep 2012 10:01:21 +0000 (04:01 -0600)]
Btrfs: fix file extent discount problem in the, snapshot

If a snapshot is created while we are writing some data into the file,
the i_size of the corresponding file in the snapshot will be wrong, it will
be beyond the end of the last file extent. And btrfsck will report:
  root 256 inode 257 errors 100

Steps to reproduce:
 # mkfs.btrfs <partition>
 # mount <partition> <mnt>
 # cd <mnt>
 # dd if=/dev/zero of=tmpfile bs=4M count=1024 &
 # for ((i=0; i<4; i++))
 > do
 > btrfs sub snap . $i
 > done

This because the algorithm of disk_i_size update is wrong. Though there are
some ordered extents behind the current one which we use to update disk_i_size,
it doesn't mean those extents will be dealt with in the same transaction. So
We shouldn't use the offset of those extents to update disk_i_size. Or we will
get the wrong i_size in the snapshot.

We fix this problem by recording the max real i_size. If we find there is a
ordered extent which is in front of the current one and doesn't complete, we
will record the end of the current one into that ordered extent. Surely, if
the current extent holds the end of other extent(it must be greater than
the current one because it is behind the current one), we will record the
number that the current extent holds. In this way, we can exclude the ordered
extents that may not be dealth with in the same transaction, and be easy to
know the real disk_i_size.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: fix full backref problem when inserting shared block reference
Miao Xie [Thu, 6 Sep 2012 10:00:57 +0000 (04:00 -0600)]
Btrfs: fix full backref problem when inserting shared block reference

If we create several snapshots at the same time, the following BUG_ON() will be
triggered.

kernel BUG at fs/btrfs/extent-tree.c:6047!

Steps to reproduce:
 # mkfs.btrfs <partition>
 # mount <partition> <mnt>
 # cd <mnt>
 # for ((i=0;i<2400;i++)); do touch long_name_to_make_tree_more_deep$i; done
 # for ((i=0; i<4; i++))
 > do
 > mkdir $i
 > for ((j=0; j<200; j++))
 > do
 > btrfs sub snap . $i/$j
 > done &
 > done

The reason is:
Before transaction commit, some operations changed the fs tree and new tree
blocks were allocated because of COW. We used the implicit non-shared back
reference for those newly allocated tree blocks because they were not shared by
two or more trees.

And then we created the first snapshot for the fs tree, according to the back
reference rules, we also used implicit back refs for the child tree blocks of
the root node of the fs tree, now those child nodes/leaves were shared by two
trees.

Then We didn't deal with the delayed references, and continued to change the fs
tree(created the second snapshot and inserted the dir item of the new snapshot
into the fs tree). According to the rules of the back reference, we added full
back refs for those tree blocks whose parents have be shared by two trees.
Now some newly allocated tree blocks had two types of the references.

As we know, the delayed reference system handles these delayed references from
back to front, and the full delayed reference is inserted after the implicit
ones. So when we dealt with the back references of those newly allocated tree
blocks, the full references was dealt with at first. And if the first reference
is a shared back reference and the tree block that the reference points to is
newly allocated, It would be considered as a tree block which is shared by two
or more trees when it is allocated and should be a full back reference not a
implicit one, the flag of its reference also should be set to FULL_BACKREF.
But in fact, it was a non-shared tree block with a implicit reference at
beginning, so it was not compulsory to set the flags to FULL_BACKREF. So BUG_ON
was triggered.

We have several methods to fix this bug:
1. deal with delayed references after the snapshot is created and before we
   change the source tree of the snapshot. This is the easiest and safest way.
2. modify the sort method of the delayed reference tree, make the full delayed
   references be inserted before the implicit ones. It is also very easy, but
   I don't know if it will introduce some problems or not.
3. modify select_delayed_ref() and make it select the implicit delayed reference
   at first. This way is not so good because it may wastes CPU time if we have
   lots of delayed references.
4. set the flags to FULL_BACKREF, this method is a little complex comparing with
   the 1st way.

I chose the 1st way to fix it.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: fix error path in create_pending_snapshot()
Miao Xie [Thu, 6 Sep 2012 10:00:32 +0000 (04:00 -0600)]
Btrfs: fix error path in create_pending_snapshot()

This patch fixes the following problem:
- If we failed to deal with the delayed dir items, we should abort transaction,
  just as its comment said. Fix it.
- If root reference or root back reference insertion failed, we should
  abort transaction. Fix it.
- Fix the double free problem of pending->inherit.
- Do not restore the trans->rsv if we doesn't change it.
- make the error path more clearly.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: fix possible memory leak in scrub_setup_recheck_block()
Wei Yongjun [Sun, 2 Sep 2012 13:44:51 +0000 (07:44 -0600)]
Btrfs: fix possible memory leak in scrub_setup_recheck_block()

bbio has been malloced in btrfs_map_block() and should be
freed before leaving from the error handling cases.

spatch with a semantic match is used to found this problem.
(http://coccinelle.lip6.fr/)

Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
12 years agoBtrfs: btrfs_drop_extent_cache should never fail
Josef Bacik [Fri, 31 Aug 2012 00:06:49 +0000 (20:06 -0400)]
Btrfs: btrfs_drop_extent_cache should never fail

I noticed this when I was doing the fsync stuff, we allocate split extents if we
drop an extent range that is in the middle of an existing extent.  This BUG()'s
if we fail to allocate memory, but the fact is this is just a cache, we will
just regenerate the cache if we need it, the important part is that we free the
range we are given.  This can be done without allocations, so if we fail to
allocate splits just skip the splitting stage and free our em and look for more
extents to drop.  This also makes btrfs_drop_extent_cache a void since nobody
was checking the return value anyway.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: do not take cleanup_work_sem in btrfs_run_delayed_iputs()
Sage Weil [Thu, 30 Aug 2012 22:26:17 +0000 (16:26 -0600)]
Btrfs: do not take cleanup_work_sem in btrfs_run_delayed_iputs()

Josef has suggested that this is not necessary.  Removing it also avoids
this lockdep splat (after the new sb_internal locking stuff was added):

[  604.090449] ======================================================
[  604.114819] [ INFO: possible circular locking dependency detected ]
[  604.139262] 3.6.0-rc2-ceph-00144-g463b030 #1 Not tainted
[  604.162193] -------------------------------------------------------
[  604.186139] btrfs-cleaner/6669 is trying to acquire lock:
[  604.209555]  (sb_internal#2){.+.+..}, at: [<ffffffffa0042b84>] start_transaction+0x124/0x430 [btrfs]
[  604.257100]
[  604.257100] but task is already holding lock:
[  604.300366]  (&fs_info->cleanup_work_sem){.+.+..}, at: [<ffffffffa0048002>] btrfs_run_delayed_iputs+0x72/0x130 [btrfs]
[  604.352989]
[  604.352989] which lock already depends on the new lock.
[  604.352989]
[  604.427104]
[  604.427104] the existing dependency chain (in reverse order) is:
[  604.478493]
[  604.478493] -> #1 (&fs_info->cleanup_work_sem){.+.+..}:
[  604.529313]        [<ffffffff810b2c82>] lock_acquire+0xa2/0x140
[  604.559621]        [<ffffffff81632b69>] down_read+0x39/0x4e
[  604.589382]        [<ffffffffa004db98>] btrfs_lookup_dentry+0x218/0x550 [btrfs]
[  604.596161] btrfs: unlinked 1 orphans
[  604.675002]        [<ffffffffa006aadd>] create_subvol+0x62d/0x690 [btrfs]
[  604.708859]        [<ffffffffa006d666>] btrfs_mksubvol.isra.52+0x346/0x3a0 [btrfs]
[  604.772466]        [<ffffffffa006d7f2>] btrfs_ioctl_snap_create_transid+0x132/0x190 [btrfs]
[  604.842245]        [<ffffffffa006d8ae>] btrfs_ioctl_snap_create+0x5e/0x80 [btrfs]
[  604.912852]        [<ffffffffa00708ae>] btrfs_ioctl+0x138e/0x1990 [btrfs]
[  604.951888]        [<ffffffff8118e9b8>] do_vfs_ioctl+0x98/0x560
[  604.989961]        [<ffffffff8118ef11>] sys_ioctl+0x91/0xa0
[  605.026628]        [<ffffffff8163d569>] system_call_fastpath+0x16/0x1b
[  605.064404]
[  605.064404] -> #0 (sb_internal#2){.+.+..}:
[  605.126832]        [<ffffffff810b25e8>] __lock_acquire+0x1ac8/0x1b90
[  605.163671]        [<ffffffff810b2c82>] lock_acquire+0xa2/0x140
[  605.200228]        [<ffffffff8117dac6>] __sb_start_write+0xc6/0x1b0
[  605.236818]        [<ffffffffa0042b84>] start_transaction+0x124/0x430 [btrfs]
[  605.274029]        [<ffffffffa00431a3>] btrfs_start_transaction+0x13/0x20 [btrfs]
[  605.340520]        [<ffffffffa004ccfa>] btrfs_evict_inode+0x19a/0x330 [btrfs]
[  605.378720]        [<ffffffff811972c8>] evict+0xb8/0x1c0
[  605.416057]        [<ffffffff811974d5>] iput+0x105/0x210
[  605.452373]        [<ffffffffa0048082>] btrfs_run_delayed_iputs+0xf2/0x130 [btrfs]
[  605.521627]        [<ffffffffa003b5e1>] cleaner_kthread+0xa1/0x120 [btrfs]
[  605.560520]        [<ffffffff810791ee>] kthread+0xae/0xc0
[  605.598094]        [<ffffffff8163e744>] kernel_thread_helper+0x4/0x10
[  605.636499]
[  605.636499] other info that might help us debug this:
[  605.636499]
[  605.736504]  Possible unsafe locking scenario:
[  605.736504]
[  605.801931]        CPU0                    CPU1
[  605.835126]        ----                    ----
[  605.867093]   lock(&fs_info->cleanup_work_sem);
[  605.898594]                                lock(sb_internal#2);
[  605.931954]                                lock(&fs_info->cleanup_work_sem);
[  605.965359]   lock(sb_internal#2);
[  605.994758]
[  605.994758]  *** DEADLOCK ***
[  605.994758]
[  606.075281] 2 locks held by btrfs-cleaner/6669:
[  606.104528]  #0:  (&fs_info->cleaner_mutex){+.+...}, at: [<ffffffffa003b5d5>] cleaner_kthread+0x95/0x120 [btrfs]
[  606.165626]  #1:  (&fs_info->cleanup_work_sem){.+.+..}, at: [<ffffffffa0048002>] btrfs_run_delayed_iputs+0x72/0x130 [btrfs]
[  606.231297]
[  606.231297] stack backtrace:
[  606.287723] Pid: 6669, comm: btrfs-cleaner Not tainted 3.6.0-rc2-ceph-00144-g463b030 #1
[  606.347823] Call Trace:
[  606.376184]  [<ffffffff8162a77c>] print_circular_bug+0x1fb/0x20c
[  606.409243]  [<ffffffff810b25e8>] __lock_acquire+0x1ac8/0x1b90
[  606.441343]  [<ffffffffa0042b84>] ? start_transaction+0x124/0x430 [btrfs]
[  606.474583]  [<ffffffff810b2c82>] lock_acquire+0xa2/0x140
[  606.505934]  [<ffffffffa0042b84>] ? start_transaction+0x124/0x430 [btrfs]
[  606.539429]  [<ffffffff8132babd>] ? do_raw_spin_unlock+0x5d/0xb0
[  606.571719]  [<ffffffff8117dac6>] __sb_start_write+0xc6/0x1b0
[  606.603498]  [<ffffffffa0042b84>] ? start_transaction+0x124/0x430 [btrfs]
[  606.637405]  [<ffffffffa0042b84>] ? start_transaction+0x124/0x430 [btrfs]
[  606.670165]  [<ffffffff81172e75>] ? kmem_cache_alloc+0xb5/0x160
[  606.702144]  [<ffffffffa0042b84>] start_transaction+0x124/0x430 [btrfs]
[  606.735562]  [<ffffffffa00256a6>] ? block_rsv_add_bytes+0x56/0x80 [btrfs]
[  606.769861]  [<ffffffffa00431a3>] btrfs_start_transaction+0x13/0x20 [btrfs]
[  606.804575]  [<ffffffffa004ccfa>] btrfs_evict_inode+0x19a/0x330 [btrfs]
[  606.838756]  [<ffffffff81634c6b>] ? _raw_spin_unlock+0x2b/0x40
[  606.872010]  [<ffffffff811972c8>] evict+0xb8/0x1c0
[  606.903800]  [<ffffffff811974d5>] iput+0x105/0x210
[  606.935416]  [<ffffffffa0048082>] btrfs_run_delayed_iputs+0xf2/0x130 [btrfs]
[  606.970510]  [<ffffffffa003b5d5>] ? cleaner_kthread+0x95/0x120 [btrfs]
[  607.005648]  [<ffffffffa003b5e1>] cleaner_kthread+0xa1/0x120 [btrfs]
[  607.040724]  [<ffffffffa003b540>] ? btrfs_destroy_delayed_refs.isra.102+0x220/0x220 [btrfs]
[  607.104740]  [<ffffffff810791ee>] kthread+0xae/0xc0
[  607.137119]  [<ffffffff810b379d>] ? trace_hardirqs_on+0xd/0x10
[  607.169797]  [<ffffffff8163e744>] kernel_thread_helper+0x4/0x10
[  607.202472]  [<ffffffff81635430>] ? retint_restore_args+0x13/0x13
[  607.235884]  [<ffffffff81079140>] ? flush_kthread_work+0x1a0/0x1a0
[  607.268731]  [<ffffffff8163e740>] ? gs_change+0x13/0x13

Signed-off-by: Sage Weil <sage@inktank.com>
12 years agoBtrfs: set journal_info in async trans commit worker
Sage Weil [Thu, 30 Aug 2012 22:26:16 +0000 (16:26 -0600)]
Btrfs: set journal_info in async trans commit worker

We expect current->journal_info to point to the trans handle we are
committing.

Signed-off-by: Sage Weil <sage@inktank.com>
12 years agoBtrfs: pass lockdep rwsem metadata to async commit transaction
Sage Weil [Thu, 30 Aug 2012 22:26:15 +0000 (16:26 -0600)]
Btrfs: pass lockdep rwsem metadata to async commit transaction

The freeze rwsem is taken by sb_start_intwrite() and dropped during the
commit_ or end_transaction().  In the async case, that happens in a worker
thread.  Tell lockdep the calling thread is releasing ownership of the
rwsem and the async thread is picking it up.

XFS plays the same trick in fs/xfs/xfs_aops.c.

Signed-off-by: Sage Weil <sage@inktank.com>
12 years agoBtrfs: add hole punching
Josef Bacik [Wed, 29 Aug 2012 18:27:18 +0000 (14:27 -0400)]
Btrfs: add hole punching

This patch adds hole punching via fallocate.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: remove unused hint byte argument for btrfs_drop_extents
Josef Bacik [Wed, 29 Aug 2012 16:24:27 +0000 (12:24 -0400)]
Btrfs: remove unused hint byte argument for btrfs_drop_extents

I audited all users of btrfs_drop_extents and found that nobody actually uses
the hint_byte argument.  I'm sure it was used for something at some point but
it's not used now, and the way the pinning works the disk bytenr would never be
immediately useful anyway so lets just remove it.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: check if an inode has no checksum when logging it
Liu Bo [Wed, 29 Aug 2012 07:07:56 +0000 (01:07 -0600)]
Btrfs: check if an inode has no checksum when logging it

This is based on Josef's "Btrfs: turbo charge fsync".

If an inode is a BTRFS_INODE_NODATASUM one, we don't need to look for csum
items any more.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agoBtrfs: fix a bug in checking whether a inode is already in log
Liu Bo [Wed, 29 Aug 2012 07:07:55 +0000 (01:07 -0600)]
Btrfs: fix a bug in checking whether a inode is already in log

This is based on Josef's "Btrfs: turbo charge fsync".

The current btrfs checks if an inode is in log by comparing
root's last_log_commit to inode's last_sub_trans[2].

But the problem is that this root->last_log_commit is shared among
inodes.

Say we have N inodes to be logged, after the first inode,
root's last_log_commit is updated and the N-1 remained files will
be skipped.

This fixes the bug by keeping a local copy of root's last_log_commit
inside each inode and this local copy will be maintained itself.

[1]: we regard each log transaction as a subset of btrfs's transaction,
i.e. sub_trans

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agoBtrfs: fix wrong orphan count of the fs/file tree
Miao Xie [Wed, 29 Aug 2012 04:13:02 +0000 (22:13 -0600)]
Btrfs: fix wrong orphan count of the fs/file tree

If we add a new orphan item, we should increase the atomic counter,
not decrease it. Fix it.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
12 years agoBtrfs: improve fsync by filtering extents that we want
Liu Bo [Mon, 27 Aug 2012 16:52:20 +0000 (10:52 -0600)]
Btrfs: improve fsync by filtering extents that we want

This is based on Josef's "Btrfs: turbo charge fsync".

The above Josef's patch performs very good in random sync write test,
because we won't have too much extents to merge.

However, it does not performs good on the test:
dd if=/dev/zero of=foobar bs=4k count=12500 oflag=sync

The reason is when we do sequencial sync write, we need to merge the
current extent just with the previous one, so that we can get accumulated
extents to log:

A(4k) --> AA(8k) --> AAA(12k) --> AAAA(16k) ...

So we'll have to flush more and more checksum into log tree, which is the
bottleneck according to my tests.

But we can avoid this by telling fsync the real extents that are needed
to be logged.

With this, I did the above dd sync write test (size=50m),

         w/o (orig)   w/ (josef's)   w/ (this)
SATA      104KB/s       109KB/s       121KB/s
ramdisk   1.5MB/s       1.5MB/s       10.7MB/s (613%)

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agoBtrfs: do not needlessly restart the transaction for enospc
Josef Bacik [Mon, 27 Aug 2012 21:48:15 +0000 (17:48 -0400)]
Btrfs: do not needlessly restart the transaction for enospc

We will stop and restart a transaction every time we move to a different leaf
when truncating a file.  This is for enospc reasons, but really we could
probably get away with doing this a little better by actually working until we
hit an ENOSPC.  So add a ->failfast flag to the block_rsv and set it when we do
truncates which will fail as soon as the block rsv runs out of space, and then
at that point we can stop and restart the transaction and refill the block rsv
and carry on.  This will make rm'ing of a file with lots of extents a bit
faster.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: cleanup extents after we finish logging inode
Liu Bo [Mon, 27 Aug 2012 16:52:19 +0000 (10:52 -0600)]
Btrfs: cleanup extents after we finish logging inode

This is based on Josef's "Btrfs: turbo charge fsync".

We should cleanup those extents after we've finished logging inode,
otherwise we may do redundant work on them.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
12 years agoBtrfs: only warn if we hit an error when doing the tree logging
Josef Bacik [Fri, 24 Aug 2012 18:48:11 +0000 (14:48 -0400)]
Btrfs: only warn if we hit an error when doing the tree logging

I hit this a couple times while working on my fsync patch (all my bugs, not
normal operation), but with my new stuff we could have new errors from cases
I have not encountered, so instead of BUG()'ing we should be WARN()'ing so
that we are notified there is a problem but the user doesn't lose their
data.  We can easily commit the transaction in the case that the tree
logging fails and still be fine, so let's try and be as nice to the user as
possible.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: turbo charge fsync
Josef Bacik [Fri, 17 Aug 2012 17:14:17 +0000 (13:14 -0400)]
Btrfs: turbo charge fsync

At least for the vm workload.  Currently on fsync we will

1) Truncate all items in the log tree for the given inode if they exist

and

2) Copy all items for a given inode into the log

The problem with this is that for things like VMs you can have lots of
extents from the fragmented writing behavior, and worst yet you may have
only modified a few extents, not the entire thing.  This patch fixes this
problem by tracking which transid modified our extent, and then when we do
the tree logging we find all of the extents we've modified in our current
transaction, sort them and commit them.  We also only truncate up to the
xattrs of the inode and copy that stuff in normally, and then just drop any
extents in the range we have that exist in the log already.  Here are some
numbers of a 50 meg fio job that does random writes and fsync()s after every
write

Original Patched
SATA drive 82KB/s 140KB/s
Fusion drive 431KB/s 2532KB/s

So around 2-6 times faster depending on your hardware.  There are a few
corner cases, for example if you truncate at all we have to do it the old
way since there is no way to be sure what is in the log is ok.  This
probably could be done smarter, but if you write-fsync-truncate-write-fsync
you deserve what you get.  All this work is in RAM of course so if your
inode gets evicted from cache and you read it in and fsync it we'll do it
the slow way if we are still in the same transaction that we last modified
the inode in.

The biggest cool part of this is that it requires no changes to the recovery
code, so if you fsync with this patch and crash and load an old kernel, it
will run the recovery and be a-ok.  I have tested this pretty thoroughly
with an fsync tester and everything comes back fine, as well as xfstests.
Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: fix possible corruption when fsyncing written prealloced extents
Josef Bacik [Thu, 16 Aug 2012 20:32:06 +0000 (16:32 -0400)]
Btrfs: fix possible corruption when fsyncing written prealloced extents

While working on my fsync patch my fsync tester kept hitting mismatching
md5sums when I would randomly write to a prealloc'ed region, syncfs() and
then write to the prealloced region some more and then fsync() and then
immediately reboot.  This is because the tree logging code will skip writing
csums for file extents who's generation is less than the current running
transaction.  When we mark extents as written we haven't been updating their
generation so they were always being skipped.  This wouldn't happen if you
were to preallocate and then write in the same transaction, but if you for
example prealloced a VM you could definitely run into this problem.  This
patch makes my fsync tester happy again.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
12 years agoBtrfs: do not allocate chunks as agressively
Josef Bacik [Tue, 14 Aug 2012 20:20:52 +0000 (16:20 -0400)]
Btrfs: do not allocate chunks as agressively

Swinging this pendulum back the other way.  We've been allocating chunks up
to 2% of the disk no matter how much we actually have allocated.  So instead
fix this calculation to only allocate chunks if we have more than 80% of the
space available allocated.  Please test this as it will likely cause all
sorts of ENOSPC problems to pop up suddenly.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>