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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
Josef Bacik [Mon, 13 Aug 2012 19:43:26 +0000 (15:43 -0400)]
Btrfs: update last trans if we don't update the inode
There is a completely impossible situation to hit where you can preallocate
a file, fsync it, write into the preallocated region, have the transaction
commit twice and then fsync and then immediately lose power and lose all of
the contents of the write. This patch fixes this just so I feel better
about the situation and because it is lightweight, we just update the
last_trans when we finish an ordered IO and we don't update the inode
itself. This way we are completely safe and I feel better. Thanks,
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Jan Schmidt [Mon, 13 Aug 2012 08:52:38 +0000 (02:52 -0600)]
Btrfs: fix gcc warnings for 32bit compiles
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Chris Mason [Tue, 7 Aug 2012 20:25:13 +0000 (16:25 -0400)]
Btrfs: fix btrfs send for inline items and compression
The btrfs send code was assuming the offset of the file item into the
extent translated to bytes on disk. If we're compressed, this isn't
true, and so it was off into extents owned by other files.
It was also improperly handling inline extents. This solves a crash
where we may have gone past the end of the file extent item by not
testing early enough for an inline extent. It also solves problems
where we have a whole between the end of the inline item and the start
of the full extent.
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Alexander Block [Wed, 1 Aug 2012 12:48:59 +0000 (14:48 +0200)]
Btrfs: don't treat top/root directory inode as deleted/reused
We can't do the deleted/reused logic for top/root inodes as it would
create a stream that tries to delete and recreate the root dir.
Reported-by: Alex Lyakas <alex.bolshoy.btrfs@gmail.com>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Wed, 1 Aug 2012 12:47:03 +0000 (14:47 +0200)]
Btrfs: ignore non-FS inodes for send/receive
We have to ignore inode/space cache objects in send/receive.
Reported-by: Alex Lyakas <alex.bolshoy.btrfs@gmail.com>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Wed, 1 Aug 2012 12:42:14 +0000 (14:42 +0200)]
Btrfs: pass root instead of parent_root to iterate_inode_ref
We need to pass the root that we determined earlier to iterate_inode_ref.
Reported-by: Alex Lyakas <alex.bolshoy.btrfs@gmail.com>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Wed, 1 Aug 2012 10:49:15 +0000 (12:49 +0200)]
Btrfs: use <= instead of < in is_extent_unchanged
Used the wrong compare operator here.
Reported-by: Alex Lyakas <alex.bolshoy.btrfs@gmail.com>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Wed, 1 Aug 2012 10:46:05 +0000 (12:46 +0200)]
Btrfs: fix check for changed extent in is_extent_unchanged
The previous check was working fine, but this check should be
easier to read. Also, we could theoritically have some exotic
bugs with the previous checks.
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Wed, 1 Aug 2012 10:07:43 +0000 (12:07 +0200)]
Btrfs: free nce and nce_head on error in name_cache_insert
Both were leaked in case of error.
Reported-by: Alex Lyakas <alex.bolshoy.btrfs@gmail.com>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Wed, 1 Aug 2012 10:03:09 +0000 (12:03 +0200)]
Btrfs: remove unused tmp_path from iterate_dir_item
A leftover from older code and unused now.
Reported-by: Alex Lyakas <alex.bolshoy.btrfs@gmail.com>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 14:33:49 +0000 (16:33 +0200)]
Btrfs: code cleanups for send/receive
Doing some code cleanups as suggested by Arne.
Changes do not change any logic.
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 12:11:31 +0000 (14:11 +0200)]
Btrfs: add/fix comments/documentation for send/receive
As the subject already said, add/fix comments.
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 14:09:35 +0000 (16:09 +0200)]
Btrfs: update send_progress at correct places
Updating send_progress in process_recorded_refs was not correct.
It got updated too early in the cur_inode_new_gen case.
Reported-by: Alex Lyakas <alex.bolshoy.btrfs@gmail.com>
Reported-by: Arne Jansen <sensille@gmx.net>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 14:18:58 +0000 (16:18 +0200)]
Btrfs: make aux field of ulist 64 bit
Btrfs send/receive uses the aux field to store inode numbers. On
32 bit machines this may become a problem.
Also fix all users of ulist_add and ulist_add_merged.
Reported-by: Arne Jansen <sensille@gmx.net>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 12:20:58 +0000 (14:20 +0200)]
Btrfs: fix use of radix_tree for name_cache in send/receive
We can't easily use the index of the radix tree for inums as the
radix tree uses 32bit indexes on 32bit kernels. For 32bit kernels,
we now use the lower 32bit of the inum as index and an additional
list to store multiple entries per radix tree entry.
Reported-by: Arne Jansen <sensille@gmx.net>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 12:13:35 +0000 (14:13 +0200)]
Btrfs: fix memory leak for name_cache in send/receive
When everything is done, name_cache_free is called which however
forgot to call kfree on the cache entries.
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 10:51:32 +0000 (12:51 +0200)]
Btrfs: don't break in the final loop of find_extent_clone
If we break, we may miss the clone from send_root which we prefer
over all other clones.
Commit is a result of Arne's review.
Reported-by: Arne Jansen <sensille@gmx.net>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 14:32:45 +0000 (16:32 +0200)]
Btrfs: use normal return path for root == send_root case
Don't have a seperate return path for the mentioned case. Now
we do the same "take lowest inode/offset" logic for all found clones.
Commit is a result of Arne's review.
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 10:44:34 +0000 (12:44 +0200)]
Btrfs: use kmalloc instead of stack for backref_ctx
Make sure to never get in trouble due to the backref_ctx
which was on the stack before.
Commit is a result of Arne's review.
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 10:42:05 +0000 (12:42 +0200)]
Btrfs: rename backref_ctx::found_in_send_root to found_itself
The new name should be easier to understand/read.
Commit is a result of Arne's review.
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 10:04:16 +0000 (12:04 +0200)]
Btrfs: remove unused use_list from send/receive code
use_list is a leftover and unused.
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 09:46:29 +0000 (11:46 +0200)]
Btrfs: add correct parent to check_dirs when dir got moved
We only added the parent for the new position of a moved dir.
We also need to add the old parent of the moved dir.
Reported-by: Alex Lyakas <alex.bolshoy.btrfs@gmail.com>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 09:08:09 +0000 (11:08 +0200)]
Btrfs: remove unused code with #if 0
fs_path_remove is not used at the moment due to a previous patch.
Remove it for now (with #if 0) to avoid compile warnings.
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 09:07:18 +0000 (11:07 +0200)]
Btrfs: add missing check for dir != tmp_dir to is_first_ref
We missed that check which resultet in all refs with the same name
being reported as first_ref.
Reported-by: Alex Lyakas <alex.bolshoy.btrfs@gmail.com>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Sat, 28 Jul 2012 08:42:24 +0000 (10:42 +0200)]
Btrfs: fix cur_ino < parent_ino case for send/receive
When the current inodes inum is smaller then the inum of the
parent directory strange things were happending due to wrong
path resolution and other bugs. Fix this with a new approach
for the problem.
Reported-by: Alex Lyakas <alex.bolshoy.btrfs@gmail.com>
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Alexander Block [Thu, 26 Jul 2012 21:39:10 +0000 (23:39 +0200)]
Btrfs: add rdev to get_inode_info in send/receive
We need rdev in the next commit.
Signed-off-by: Alexander Block <ablock84@googlemail.com>
Linus Torvalds [Sun, 30 Sep 2012 23:47:46 +0000 (16:47 -0700)]
Linux 3.6
Miklos Szeredi [Mon, 17 Sep 2012 20:23:30 +0000 (22:23 +0200)]
vfs: dcache: fix deadlock in tree traversal
IBM reported a deadlock in select_parent(). This was found to be caused
by taking rename_lock when already locked when restarting the tree
traversal.
There are two cases when the traversal needs to be restarted:
1) concurrent d_move(); this can only happen when not already locked,
since taking rename_lock protects against concurrent d_move().
2) racing with final d_put() on child just at the moment of ascending
to parent; rename_lock doesn't protect against this rare race, so it
can happen when already locked.
Because of case 2, we need to be able to handle restarting the traversal
when rename_lock is already held. This patch fixes all three callers of
try_to_ascend().
IBM reported that the deadlock is gone with this patch.
[ I rewrote the patch to be smaller and just do the "goto again" if the
lock was already held, but credit goes to Miklos for the real work.
- Linus ]
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: stable@vger.kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>