aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Bo <bo.li.liu@oracle.com>2018-01-25 13:02:56 -0500
committerDavid Sterba <dsterba@suse.com>2018-02-02 10:24:53 -0500
commit900c9981680067573671ecc5cbfa7c5770be3a40 (patch)
tree21d888f9be39ded9273d584ed1b552d15eeaa81f
parent1a932ef4e47984dee227834667b5ff5a334e4805 (diff)
Btrfs: fix unexpected -EEXIST when creating new inode
The highest objectid, which is assigned to new inode, is decided at the time of initializing fs roots. However, in cases where log replay gets processed, the btree which fs root owns might be changed, so we have to search it again for the highest objectid, otherwise creating new inode would end up with -EEXIST. cc: <stable@vger.kernel.org> v4.4-rc6+ Fixes: f32e48e92596 ("Btrfs: Initialize btrfs_root->highest_objectid when loading tree root and subvolume roots") Signed-off-by: Liu Bo <bo.li.liu@oracle.com> Reviewed-by: Josef Bacik <jbacik@fb.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/tree-log.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 79af4ae042ae..61f20c367aaf 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -28,6 +28,7 @@
28#include "hash.h" 28#include "hash.h"
29#include "compression.h" 29#include "compression.h"
30#include "qgroup.h" 30#include "qgroup.h"
31#include "inode-map.h"
31 32
32/* magic values for the inode_only field in btrfs_log_inode: 33/* magic values for the inode_only field in btrfs_log_inode:
33 * 34 *
@@ -5685,6 +5686,23 @@ again:
5685 path); 5686 path);
5686 } 5687 }
5687 5688
5689 if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) {
5690 struct btrfs_root *root = wc.replay_dest;
5691
5692 btrfs_release_path(path);
5693
5694 /*
5695 * We have just replayed everything, and the highest
5696 * objectid of fs roots probably has changed in case
5697 * some inode_item's got replayed.
5698 *
5699 * root->objectid_mutex is not acquired as log replay
5700 * could only happen during mount.
5701 */
5702 ret = btrfs_find_highest_objectid(root,
5703 &root->highest_objectid);
5704 }
5705
5688 key.offset = found_key.offset - 1; 5706 key.offset = found_key.offset - 1;
5689 wc.replay_dest->log_root = NULL; 5707 wc.replay_dest->log_root = NULL;
5690 free_extent_buffer(log->node); 5708 free_extent_buffer(log->node);