aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/tree-log.c123
1 files changed, 109 insertions, 14 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 066e754b1294..6c95159302dd 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -1951,6 +1951,104 @@ out:
1951 return ret; 1951 return ret;
1952} 1952}
1953 1953
1954static int replay_xattr_deletes(struct btrfs_trans_handle *trans,
1955 struct btrfs_root *root,
1956 struct btrfs_root *log,
1957 struct btrfs_path *path,
1958 const u64 ino)
1959{
1960 struct btrfs_key search_key;
1961 struct btrfs_path *log_path;
1962 int i;
1963 int nritems;
1964 int ret;
1965
1966 log_path = btrfs_alloc_path();
1967 if (!log_path)
1968 return -ENOMEM;
1969
1970 search_key.objectid = ino;
1971 search_key.type = BTRFS_XATTR_ITEM_KEY;
1972 search_key.offset = 0;
1973again:
1974 ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
1975 if (ret < 0)
1976 goto out;
1977process_leaf:
1978 nritems = btrfs_header_nritems(path->nodes[0]);
1979 for (i = path->slots[0]; i < nritems; i++) {
1980 struct btrfs_key key;
1981 struct btrfs_dir_item *di;
1982 struct btrfs_dir_item *log_di;
1983 u32 total_size;
1984 u32 cur;
1985
1986 btrfs_item_key_to_cpu(path->nodes[0], &key, i);
1987 if (key.objectid != ino || key.type != BTRFS_XATTR_ITEM_KEY) {
1988 ret = 0;
1989 goto out;
1990 }
1991
1992 di = btrfs_item_ptr(path->nodes[0], i, struct btrfs_dir_item);
1993 total_size = btrfs_item_size_nr(path->nodes[0], i);
1994 cur = 0;
1995 while (cur < total_size) {
1996 u16 name_len = btrfs_dir_name_len(path->nodes[0], di);
1997 u16 data_len = btrfs_dir_data_len(path->nodes[0], di);
1998 u32 this_len = sizeof(*di) + name_len + data_len;
1999 char *name;
2000
2001 name = kmalloc(name_len, GFP_NOFS);
2002 if (!name) {
2003 ret = -ENOMEM;
2004 goto out;
2005 }
2006 read_extent_buffer(path->nodes[0], name,
2007 (unsigned long)(di + 1), name_len);
2008
2009 log_di = btrfs_lookup_xattr(NULL, log, log_path, ino,
2010 name, name_len, 0);
2011 btrfs_release_path(log_path);
2012 if (!log_di) {
2013 /* Doesn't exist in log tree, so delete it. */
2014 btrfs_release_path(path);
2015 di = btrfs_lookup_xattr(trans, root, path, ino,
2016 name, name_len, -1);
2017 kfree(name);
2018 if (IS_ERR(di)) {
2019 ret = PTR_ERR(di);
2020 goto out;
2021 }
2022 ASSERT(di);
2023 ret = btrfs_delete_one_dir_name(trans, root,
2024 path, di);
2025 if (ret)
2026 goto out;
2027 btrfs_release_path(path);
2028 search_key = key;
2029 goto again;
2030 }
2031 kfree(name);
2032 if (IS_ERR(log_di)) {
2033 ret = PTR_ERR(log_di);
2034 goto out;
2035 }
2036 cur += this_len;
2037 di = (struct btrfs_dir_item *)((char *)di + this_len);
2038 }
2039 }
2040 ret = btrfs_next_leaf(root, path);
2041 if (ret > 0)
2042 ret = 0;
2043 else if (ret == 0)
2044 goto process_leaf;
2045out:
2046 btrfs_free_path(log_path);
2047 btrfs_release_path(path);
2048 return ret;
2049}
2050
2051
1954/* 2052/*
1955 * deletion replay happens before we copy any new directory items 2053 * deletion replay happens before we copy any new directory items
1956 * out of the log or out of backreferences from inodes. It 2054 * out of the log or out of backreferences from inodes. It
@@ -2104,6 +2202,10 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
2104 2202
2105 inode_item = btrfs_item_ptr(eb, i, 2203 inode_item = btrfs_item_ptr(eb, i,
2106 struct btrfs_inode_item); 2204 struct btrfs_inode_item);
2205 ret = replay_xattr_deletes(wc->trans, root, log,
2206 path, key.objectid);
2207 if (ret)
2208 break;
2107 mode = btrfs_inode_mode(eb, inode_item); 2209 mode = btrfs_inode_mode(eb, inode_item);
2108 if (S_ISDIR(mode)) { 2210 if (S_ISDIR(mode)) {
2109 ret = replay_dir_deletes(wc->trans, 2211 ret = replay_dir_deletes(wc->trans,
@@ -4072,10 +4174,8 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
4072 if (S_ISDIR(inode->i_mode)) { 4174 if (S_ISDIR(inode->i_mode)) {
4073 int max_key_type = BTRFS_DIR_LOG_INDEX_KEY; 4175 int max_key_type = BTRFS_DIR_LOG_INDEX_KEY;
4074 4176
4075 if (inode_only == LOG_INODE_EXISTS) { 4177 if (inode_only == LOG_INODE_EXISTS)
4076 max_key_type = BTRFS_INODE_EXTREF_KEY; 4178 max_key_type = BTRFS_XATTR_ITEM_KEY;
4077 max_key.type = max_key_type;
4078 }
4079 ret = drop_objectid_items(trans, log, path, ino, max_key_type); 4179 ret = drop_objectid_items(trans, log, path, ino, max_key_type);
4080 } else { 4180 } else {
4081 if (inode_only == LOG_INODE_EXISTS) { 4181 if (inode_only == LOG_INODE_EXISTS) {
@@ -4100,7 +4200,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
4100 if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC, 4200 if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
4101 &BTRFS_I(inode)->runtime_flags)) { 4201 &BTRFS_I(inode)->runtime_flags)) {
4102 if (inode_only == LOG_INODE_EXISTS) { 4202 if (inode_only == LOG_INODE_EXISTS) {
4103 max_key.type = BTRFS_INODE_EXTREF_KEY; 4203 max_key.type = BTRFS_XATTR_ITEM_KEY;
4104 ret = drop_objectid_items(trans, log, path, ino, 4204 ret = drop_objectid_items(trans, log, path, ino,
4105 max_key.type); 4205 max_key.type);
4106 } else { 4206 } else {
@@ -4111,17 +4211,12 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
4111 ret = btrfs_truncate_inode_items(trans, log, 4211 ret = btrfs_truncate_inode_items(trans, log,
4112 inode, 0, 0); 4212 inode, 0, 0);
4113 } 4213 }
4114 } else if (test_bit(BTRFS_INODE_COPY_EVERYTHING, 4214 } else if (test_and_clear_bit(BTRFS_INODE_COPY_EVERYTHING,
4115 &BTRFS_I(inode)->runtime_flags) || 4215 &BTRFS_I(inode)->runtime_flags) ||
4116 inode_only == LOG_INODE_EXISTS) { 4216 inode_only == LOG_INODE_EXISTS) {
4117 if (inode_only == LOG_INODE_ALL) { 4217 if (inode_only == LOG_INODE_ALL)
4118 clear_bit(BTRFS_INODE_COPY_EVERYTHING,
4119 &BTRFS_I(inode)->runtime_flags);
4120 fast_search = true; 4218 fast_search = true;
4121 max_key.type = BTRFS_XATTR_ITEM_KEY; 4219 max_key.type = BTRFS_XATTR_ITEM_KEY;
4122 } else {
4123 max_key.type = BTRFS_INODE_EXTREF_KEY;
4124 }
4125 ret = drop_objectid_items(trans, log, path, ino, 4220 ret = drop_objectid_items(trans, log, path, ino,
4126 max_key.type); 4221 max_key.type);
4127 } else { 4222 } else {