Chris Mason [Thu, 25 Oct 2012 19:53:10 +0000 (15:53 -0400)]
Merge branch 'for-chris-fixed' of git://git.jan-o-sch.net/btrfs-unstable
Josef Bacik [Mon, 22 Oct 2012 19:43:12 +0000 (15:43 -0400)]
Btrfs: Use btrfs_update_inode_fallback when creating a snapshot
On a really full file system I was getting ENOSPC back from
btrfs_update_inode when trying to update the parent inode when creating a
snapshot. Just use the fallback method so we can update the inode and not
have to worry about having a delayed ref. Thanks,
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Alex Lyakas [Wed, 17 Oct 2012 13:52:47 +0000 (13:52 +0000)]
Btrfs: Send: preserve ownership (uid and gid) also for symlinks.
This patch also requires a change in the user-space part of "receive".
We need to use "lchown" instead of "chown". We will do this in the
following patch.
Signed-off-by: Alex Lyakas <alex.btrfs@zadarastorage.com>
if (S_ISREG(sctx->cur_inode_mode)) {
Miao Xie [Tue, 16 Oct 2012 11:26:46 +0000 (11:26 +0000)]
Btrfs: fix deadlock caused by the nested chunk allocation
Steps to reproduce:
# mkfs.btrfs -m raid1 <disk1> <disk2>
# btrfstune -S 1 <disk1>
# mount <disk1> <mnt>
# btrfs device add <disk3> <disk4> <mnt>
# mount -o remount,rw <mnt>
# dd if=/dev/zero of=<mnt>/tmpfile bs=1M count=1
Deadlock happened.
It is because of the nested chunk allocation. When we wrote the data
into the filesystem, we would allocate the data chunk because there was
no data chunk in the filesystem. At the end of the data chunk allocation,
we should insert the metadata of the data chunk into the extent tree, but
there was no raid1 chunk, so we tried to lock the chunk allocation mutex to
allocate the new chunk, but we had held the mutex, the deadlock happened.
By rights, we would allocate the raid1 chunk when we added the second device
because the profile of the seed filesystem is raid1 and we had two devices.
But we didn't do that in fact. It is because the last step of the first device
insertion didn't commit the transaction. So when we added the second device,
we didn't cow the tree, and just inserted the relative metadata into the leaves
which were generated by the first device insertion, and its profile was dup.
So, I fix this problem by commiting the transaction at the end of the first
device insertion.
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Lukas Czerner [Tue, 16 Oct 2012 09:34:36 +0000 (09:34 +0000)]
btrfs: Return EINVAL when length to trim is less than FSB
Currently if len argument in btrfs_ioctl_fitrim() is smaller than
one FSB we will continue and finally return 0 bytes discarded.
However if the length to discard is smaller then file system block
we should really return EINVAL.
Signed-off-by: Lukas Czerner <lczerner@redhat.com>
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>
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>
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>
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>
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.
Jan Schmidt [Tue, 23 Oct 2012 13:02:12 +0000 (15:02 +0200)]
Btrfs: comment for loop in tree_mod_log_insert_move
Emphasis the way tree_mod_log_insert_move avoids adding
MOD_LOG_KEY_REMOVE_WHILE_MOVING operations, depending on the direction of
the move operation.
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Jan Schmidt [Tue, 23 Oct 2012 12:21:05 +0000 (14:21 +0200)]
Btrfs: fix extent buffer reference for tree mod log roots
In get_old_root we grab a lock on the extent buffer before we obtain a
reference on that buffer. That order is changed now.
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Jan Schmidt [Tue, 23 Oct 2012 09:28:27 +0000 (11:28 +0200)]
Btrfs: determine level of old roots
In btrfs_find_all_roots' termination condition, we compare the level of the
old buffer we got from btrfs_search_old_slot to the level of the current
root node. We'd better compare it to the level of the rewinded root node.
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Jan Schmidt [Tue, 23 Oct 2012 09:27:33 +0000 (11:27 +0200)]
Btrfs: tree mod log's old roots could still be part of the tree
Tree mod log treated old root buffers as always empty buffers when starting
the rewind operations. However, the old root may still be part of the
current tree at a lower level, with still some valid entries.
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Jan Schmidt [Mon, 22 Oct 2012 18:02:56 +0000 (20:02 +0200)]
Btrfs: fix a tree mod logging issue for root replacement operations
Avoid the implicit free by tree_mod_log_set_root_pointer, which is wrong in
two places. Where needed, we call tree_mod_log_free_eb explicitly now.
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Jan Schmidt [Fri, 19 Oct 2012 07:22:03 +0000 (09:22 +0200)]
Btrfs: don't put removals from push_node_left into tree mod log twice
Independant of the check (push_items < src_items) tree_mod_log_eb_copy did
log the removal of the old data entries from the source buffer. Therefore,
we must not call tree_mod_log_eb_move if the check evaluates to true, as
that would log the removal twice, finally resulting in (rewinded) buffers
with wrong values for header_nritems.
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>