diff options
| author | 2012-11-01 06:38:47 +0000 | |
|---|---|---|
| committer | 2012-12-12 17:15:18 -0500 | |
| commit | 183f37fa3503332740c76f1b493f4304ec889358 (patch) | |
| tree | 8b3eb78cb9b62da3eebca87cf3e883ebee70543a | |
| parent | 292fd7fc39aa06668f3a8db546714e727120cb3e (diff) | |
| download | linux-183f37fa3503332740c76f1b493f4304ec889358.tar.gz | |
Btrfs: do not log extents when we only log new names
When we log new names, we need to log just enough to recreate the inode
during log replay, and there is no need to log extents along with it.
This actually fixes a bug revealed by xfstests 241, where it shows
that we're logging some extents that have not updated metadata,
so we don't get proper EXTENT_DATA items to be copied to log tree.
Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
| -rw-r--r-- | fs/btrfs/tree-log.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 81e407d9677a..4ec41ecb4d65 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -3398,81 +3398,82 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, max_key.objectid = ino; /* today the code can only do partial logging of directories */ if (inode_only == LOG_INODE_EXISTS || S_ISDIR(inode->i_mode)) max_key.type = BTRFS_XATTR_ITEM_KEY; else max_key.type = (u8)-1; max_key.offset = (u64)-1; /* Only run delayed items if we are a dir or a new file */ if (S_ISDIR(inode->i_mode) || BTRFS_I(inode)->generation > root->fs_info->last_trans_committed) { ret = btrfs_commit_inode_delayed_items(trans, inode); if (ret) { btrfs_free_path(path); btrfs_free_path(dst_path); return ret; } } mutex_lock(&BTRFS_I(inode)->log_mutex); /* * a brute force approach to making sure we get the most uptodate * copies of everything. */ if (S_ISDIR(inode->i_mode)) { int max_key_type = BTRFS_DIR_LOG_INDEX_KEY; if (inode_only == LOG_INODE_EXISTS) max_key_type = BTRFS_XATTR_ITEM_KEY; ret = drop_objectid_items(trans, log, path, ino, max_key_type); } else { if (test_and_clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags)) { ret = btrfs_truncate_inode_items(trans, log, inode, 0, 0); } else { - fast_search = true; + if (inode_only == LOG_INODE_ALL) + fast_search = true; max_key.type = BTRFS_XATTR_ITEM_KEY; ret = drop_objectid_items(trans, log, path, ino, BTRFS_XATTR_ITEM_KEY); } } if (ret) { err = ret; goto out_unlock; } path->keep_locks = 1; while (1) { ins_nr = 0; ret = btrfs_search_forward(root, &min_key, &max_key, path, 0, trans->transid); if (ret != 0) break; again: /* note, ins_nr might be > 0 here, cleanup outside the loop */ if (min_key.objectid != ino) break; if (min_key.type > max_key.type) break; src = path->nodes[0]; if (ins_nr && ins_start_slot + ins_nr == path->slots[0]) { ins_nr++; goto next_slot; } else if (!ins_nr) { ins_start_slot = path->slots[0]; ins_nr = 1; goto next_slot; } ret = copy_items(trans, inode, dst_path, src, ins_start_slot, ins_nr, inode_only); if (ret) { err = ret; goto out_unlock; } |
