aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorMark Fasheh <mfasheh@suse.de>2012-08-08 14:32:27 -0400
committerChris Mason <chris.mason@fusionio.com>2012-10-09 09:14:45 -0400
commitf186373fef005cee948a4a39e6a14c2e5f517298 (patch)
tree5683c66a7112e56147149f379658517ab18e7689 /fs/btrfs
parent5a1d7843ca4b3a9009bea87f85ad33854b910aea (diff)
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>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/backref.c68
-rw-r--r--fs/btrfs/backref.h5
-rw-r--r--fs/btrfs/ctree.h53
-rw-r--r--fs/btrfs/hash.h10
-rw-r--r--fs/btrfs/inode-item.c285
-rw-r--r--fs/btrfs/inode.c23
-rw-r--r--fs/btrfs/tree-log.c345
7 files changed, 710 insertions, 79 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 7084431b7c9c..dc963121d1db 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -1109,6 +1109,74 @@ static int inode_ref_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
1109 found_key); 1109 found_key);
1110} 1110}
1111 1111
1112int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid,
1113 u64 start_off, struct btrfs_path *path,
1114 struct btrfs_inode_extref **ret_extref,
1115 u64 *found_off)
1116{
1117 int ret, slot;
1118 struct btrfs_key key;
1119 struct btrfs_key found_key;
1120 struct btrfs_inode_extref *extref;
1121 struct extent_buffer *leaf;
1122 unsigned long ptr;
1123
1124 key.objectid = inode_objectid;
1125 btrfs_set_key_type(&key, BTRFS_INODE_EXTREF_KEY);
1126 key.offset = start_off;
1127
1128 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
1129 if (ret < 0)
1130 return ret;
1131
1132 while (1) {
1133 leaf = path->nodes[0];
1134 slot = path->slots[0];
1135 if (slot >= btrfs_header_nritems(leaf)) {
1136 /*
1137 * If the item at offset is not found,
1138 * btrfs_search_slot will point us to the slot
1139 * where it should be inserted. In our case
1140 * that will be the slot directly before the
1141 * next INODE_REF_KEY_V2 item. In the case
1142 * that we're pointing to the last slot in a
1143 * leaf, we must move one leaf over.
1144 */
1145 ret = btrfs_next_leaf(root, path);
1146 if (ret) {
1147 if (ret >= 1)
1148 ret = -ENOENT;
1149 break;
1150 }
1151 continue;
1152 }
1153
1154 btrfs_item_key_to_cpu(leaf, &found_key, slot);
1155
1156 /*
1157 * Check that we're still looking at an extended ref key for
1158 * this particular objectid. If we have different
1159 * objectid or type then there are no more to be found
1160 * in the tree and we can exit.
1161 */
1162 ret = -ENOENT;
1163 if (found_key.objectid != inode_objectid)
1164 break;
1165 if (btrfs_key_type(&found_key) != BTRFS_INODE_EXTREF_KEY)
1166 break;
1167
1168 ret = 0;
1169 ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
1170 extref = (struct btrfs_inode_extref *)ptr;
1171 *ret_extref = extref;
1172 if (found_off)
1173 *found_off = found_key.offset;
1174 break;
1175 }
1176
1177 return ret;
1178}
1179
1112/* 1180/*
1113 * this iterates to turn a btrfs_inode_ref into a full filesystem path. elements 1181 * this iterates to turn a btrfs_inode_ref into a full filesystem path. elements
1114 * of the path are separated by '/' and the path is guaranteed to be 1182 * of the path are separated by '/' and the path is guaranteed to be
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
index 4fda5d8029a7..0b920c113952 100644
--- a/fs/btrfs/backref.h
+++ b/fs/btrfs/backref.h
@@ -70,4 +70,9 @@ struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,
70 struct btrfs_path *path); 70 struct btrfs_path *path);
71void free_ipath(struct inode_fs_paths *ipath); 71void free_ipath(struct inode_fs_paths *ipath);
72 72
73int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid,
74 u64 start_off, struct btrfs_path *path,
75 struct btrfs_inode_extref **ret_extref,
76 u64 *found_off);
77
73#endif 78#endif
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 399521ab61da..50dcd0fbae11 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -154,6 +154,13 @@ struct btrfs_ordered_sum;
154 */ 154 */
155#define BTRFS_NAME_LEN 255 155#define BTRFS_NAME_LEN 255
156 156
157/*
158 * Theoretical limit is larger, but we keep this down to a sane
159 * value. That should limit greatly the possibility of collisions on
160 * inode ref items.
161 */
162#define BTRFS_LINK_MAX 65535U
163
157/* 32 bytes in various csum fields */ 164/* 32 bytes in various csum fields */
158#define BTRFS_CSUM_SIZE 32 165#define BTRFS_CSUM_SIZE 32
159 166
@@ -489,6 +496,8 @@ struct btrfs_super_block {
489 */ 496 */
490#define BTRFS_FEATURE_INCOMPAT_BIG_METADATA (1ULL << 5) 497#define BTRFS_FEATURE_INCOMPAT_BIG_METADATA (1ULL << 5)
491 498
499#define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF (1ULL << 6)
500
492#define BTRFS_FEATURE_COMPAT_SUPP 0ULL 501#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
493#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL 502#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL
494#define BTRFS_FEATURE_INCOMPAT_SUPP \ 503#define BTRFS_FEATURE_INCOMPAT_SUPP \
@@ -496,7 +505,8 @@ struct btrfs_super_block {
496 BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL | \ 505 BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL | \
497 BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS | \ 506 BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS | \
498 BTRFS_FEATURE_INCOMPAT_BIG_METADATA | \ 507 BTRFS_FEATURE_INCOMPAT_BIG_METADATA | \
499 BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO) 508 BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO | \
509 BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
500 510
501/* 511/*
502 * A leaf is full of items. offset and size tell us where to find 512 * A leaf is full of items. offset and size tell us where to find
@@ -643,6 +653,14 @@ struct btrfs_inode_ref {
643 /* name goes here */ 653 /* name goes here */
644} __attribute__ ((__packed__)); 654} __attribute__ ((__packed__));
645 655
656struct btrfs_inode_extref {
657 __le64 parent_objectid;
658 __le64 index;
659 __le16 name_len;
660 __u8 name[0];
661 /* name goes here */
662} __attribute__ ((__packed__));
663
646struct btrfs_timespec { 664struct btrfs_timespec {
647 __le64 sec; 665 __le64 sec;
648 __le32 nsec; 666 __le32 nsec;
@@ -1601,6 +1619,7 @@ struct btrfs_ioctl_defrag_range_args {
1601 */ 1619 */
1602#define BTRFS_INODE_ITEM_KEY 1 1620#define BTRFS_INODE_ITEM_KEY 1
1603#define BTRFS_INODE_REF_KEY 12 1621#define BTRFS_INODE_REF_KEY 12
1622#define BTRFS_INODE_EXTREF_KEY 13
1604#define BTRFS_XATTR_ITEM_KEY 24 1623#define BTRFS_XATTR_ITEM_KEY 24
1605#define BTRFS_ORPHAN_ITEM_KEY 48 1624#define BTRFS_ORPHAN_ITEM_KEY 48
1606/* reserve 2-15 close to the inode for later flexibility */ 1625/* reserve 2-15 close to the inode for later flexibility */
@@ -1987,6 +2006,13 @@ BTRFS_SETGET_STACK_FUNCS(block_group_flags,
1987BTRFS_SETGET_FUNCS(inode_ref_name_len, struct btrfs_inode_ref, name_len, 16); 2006BTRFS_SETGET_FUNCS(inode_ref_name_len, struct btrfs_inode_ref, name_len, 16);
1988BTRFS_SETGET_FUNCS(inode_ref_index, struct btrfs_inode_ref, index, 64); 2007BTRFS_SETGET_FUNCS(inode_ref_index, struct btrfs_inode_ref, index, 64);
1989 2008
2009/* struct btrfs_inode_extref */
2010BTRFS_SETGET_FUNCS(inode_extref_parent, struct btrfs_inode_extref,
2011 parent_objectid, 64);
2012BTRFS_SETGET_FUNCS(inode_extref_name_len, struct btrfs_inode_extref,
2013 name_len, 16);
2014BTRFS_SETGET_FUNCS(inode_extref_index, struct btrfs_inode_extref, index, 64);
2015
1990/* struct btrfs_inode_item */ 2016/* struct btrfs_inode_item */
1991BTRFS_SETGET_FUNCS(inode_generation, struct btrfs_inode_item, generation, 64); 2017BTRFS_SETGET_FUNCS(inode_generation, struct btrfs_inode_item, generation, 64);
1992BTRFS_SETGET_FUNCS(inode_sequence, struct btrfs_inode_item, sequence, 64); 2018BTRFS_SETGET_FUNCS(inode_sequence, struct btrfs_inode_item, sequence, 64);
@@ -3184,12 +3210,12 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
3184 struct btrfs_root *root, 3210 struct btrfs_root *root,
3185 const char *name, int name_len, 3211 const char *name, int name_len,
3186 u64 inode_objectid, u64 ref_objectid, u64 *index); 3212 u64 inode_objectid, u64 ref_objectid, u64 *index);
3187struct btrfs_inode_ref * 3213int btrfs_get_inode_ref_index(struct btrfs_trans_handle *trans,
3188btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans, 3214 struct btrfs_root *root,
3189 struct btrfs_root *root, 3215 struct btrfs_path *path,
3190 struct btrfs_path *path, 3216 const char *name, int name_len,
3191 const char *name, int name_len, 3217 u64 inode_objectid, u64 ref_objectid, int mod,
3192 u64 inode_objectid, u64 ref_objectid, int mod); 3218 u64 *ret_index);
3193int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans, 3219int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans,
3194 struct btrfs_root *root, 3220 struct btrfs_root *root,
3195 struct btrfs_path *path, u64 objectid); 3221 struct btrfs_path *path, u64 objectid);
@@ -3197,6 +3223,19 @@ int btrfs_lookup_inode(struct btrfs_trans_handle *trans, struct btrfs_root
3197 *root, struct btrfs_path *path, 3223 *root, struct btrfs_path *path,
3198 struct btrfs_key *location, int mod); 3224 struct btrfs_key *location, int mod);
3199 3225
3226struct btrfs_inode_extref *
3227btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
3228 struct btrfs_root *root,
3229 struct btrfs_path *path,
3230 const char *name, int name_len,
3231 u64 inode_objectid, u64 ref_objectid, int ins_len,
3232 int cow);
3233
3234int btrfs_find_name_in_ext_backref(struct btrfs_path *path,
3235 u64 ref_objectid, const char *name,
3236 int name_len,
3237 struct btrfs_inode_extref **extref_ret);
3238
3200/* file-item.c */ 3239/* file-item.c */
3201int btrfs_del_csums(struct btrfs_trans_handle *trans, 3240int btrfs_del_csums(struct btrfs_trans_handle *trans,
3202 struct btrfs_root *root, u64 bytenr, u64 len); 3241 struct btrfs_root *root, u64 bytenr, u64 len);
diff --git a/fs/btrfs/hash.h b/fs/btrfs/hash.h
index db2ff9773b99..1d982812ab67 100644
--- a/fs/btrfs/hash.h
+++ b/fs/btrfs/hash.h
@@ -24,4 +24,14 @@ static inline u64 btrfs_name_hash(const char *name, int len)
24{ 24{
25 return crc32c((u32)~1, name, len); 25 return crc32c((u32)~1, name, len);
26} 26}
27
28/*
29 * Figure the key offset of an extended inode ref
30 */
31static inline u64 btrfs_extref_hash(u64 parent_objectid, const char *name,
32 int len)
33{
34 return (u64) crc32c(parent_objectid, name, len);
35}
36
27#endif 37#endif
diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c
index a13cf1a96c73..48b8fda93132 100644
--- a/fs/btrfs/inode-item.c
+++ b/fs/btrfs/inode-item.c
@@ -18,6 +18,7 @@
18 18
19#include "ctree.h" 19#include "ctree.h"
20#include "disk-io.h" 20#include "disk-io.h"
21#include "hash.h"
21#include "transaction.h" 22#include "transaction.h"
22#include "print-tree.h" 23#include "print-tree.h"
23 24
@@ -50,18 +51,57 @@ static int find_name_in_backref(struct btrfs_path *path, const char *name,
50 return 0; 51 return 0;
51} 52}
52 53
53struct btrfs_inode_ref * 54int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid,
55 const char *name, int name_len,
56 struct btrfs_inode_extref **extref_ret)
57{
58 struct extent_buffer *leaf;
59 struct btrfs_inode_extref *extref;
60 unsigned long ptr;
61 unsigned long name_ptr;
62 u32 item_size;
63 u32 cur_offset = 0;
64 int ref_name_len;
65
66 leaf = path->nodes[0];
67 item_size = btrfs_item_size_nr(leaf, path->slots[0]);
68 ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
69
70 /*
71 * Search all extended backrefs in this item. We're only
72 * looking through any collisions so most of the time this is
73 * just going to compare against one buffer. If all is well,
74 * we'll return success and the inode ref object.
75 */
76 while (cur_offset < item_size) {
77 extref = (struct btrfs_inode_extref *) (ptr + cur_offset);
78 name_ptr = (unsigned long)(&extref->name);
79 ref_name_len = btrfs_inode_extref_name_len(leaf, extref);
80
81 if (ref_name_len == name_len &&
82 btrfs_inode_extref_parent(leaf, extref) == ref_objectid &&
83 (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)) {
84 if (extref_ret)
85 *extref_ret = extref;
86 return 1;
87 }
88
89 cur_offset += ref_name_len + sizeof(*extref);
90 }
91 return 0;
92}
93
94static struct btrfs_inode_ref *
54btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans, 95btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans,
55 struct btrfs_root *root, 96 struct btrfs_root *root,
56 struct btrfs_path *path, 97 struct btrfs_path *path,
57 const char *name, int name_len, 98 const char *name, int name_len,
58 u64 inode_objectid, u64 ref_objectid, int mod) 99 u64 inode_objectid, u64 ref_objectid, int ins_len,
100 int cow)
59{ 101{
102 int ret;
60 struct btrfs_key key; 103 struct btrfs_key key;
61 struct btrfs_inode_ref *ref; 104 struct btrfs_inode_ref *ref;
62 int ins_len = mod < 0 ? -1 : 0;
63 int cow = mod != 0;
64 int ret;
65 105
66 key.objectid = inode_objectid; 106 key.objectid = inode_objectid;
67 key.type = BTRFS_INODE_REF_KEY; 107 key.type = BTRFS_INODE_REF_KEY;
@@ -77,13 +117,150 @@ btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans,
77 return ref; 117 return ref;
78} 118}
79 119
80int btrfs_del_inode_ref(struct btrfs_trans_handle *trans, 120/* Returns NULL if no extref found */
121struct btrfs_inode_extref *
122btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
123 struct btrfs_root *root,
124 struct btrfs_path *path,
125 const char *name, int name_len,
126 u64 inode_objectid, u64 ref_objectid, int ins_len,
127 int cow)
128{
129 int ret;
130 struct btrfs_key key;
131 struct btrfs_inode_extref *extref;
132
133 key.objectid = inode_objectid;
134 key.type = BTRFS_INODE_EXTREF_KEY;
135 key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
136
137 ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
138 if (ret < 0)
139 return ERR_PTR(ret);
140 if (ret > 0)
141 return NULL;
142 if (!btrfs_find_name_in_ext_backref(path, ref_objectid, name, name_len, &extref))
143 return NULL;
144 return extref;
145}
146
147int btrfs_get_inode_ref_index(struct btrfs_trans_handle *trans,
148 struct btrfs_root *root,
149 struct btrfs_path *path,
150 const char *name, int name_len,
151 u64 inode_objectid, u64 ref_objectid, int mod,
152 u64 *ret_index)
153{
154 struct btrfs_inode_ref *ref;
155 struct btrfs_inode_extref *extref;
156 int ins_len = mod < 0 ? -1 : 0;
157 int cow = mod != 0;
158
159 ref = btrfs_lookup_inode_ref(trans, root, path, name, name_len,
160 inode_objectid, ref_objectid, ins_len,
161 cow);
162 if (IS_ERR(ref))
163 return PTR_ERR(ref);
164
165 if (ref != NULL) {
166 *ret_index = btrfs_inode_ref_index(path->nodes[0], ref);
167 return 0;
168 }
169
170 btrfs_release_path(path);
171
172 extref = btrfs_lookup_inode_extref(trans, root, path, name,
173 name_len, inode_objectid,
174 ref_objectid, ins_len, cow);
175 if (IS_ERR(extref))
176 return PTR_ERR(extref);
177
178 if (extref) {
179 *ret_index = btrfs_inode_extref_index(path->nodes[0], extref);
180 return 0;
181 }
182
183 return -ENOENT;
184}
185
186int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
81 struct btrfs_root *root, 187 struct btrfs_root *root,
82 const char *name, int name_len, 188 const char *name, int name_len,
83 u64 inode_objectid, u64 ref_objectid, u64 *index) 189 u64 inode_objectid, u64 ref_objectid, u64 *index)
84{ 190{
85 struct btrfs_path *path; 191 struct btrfs_path *path;
86 struct btrfs_key key; 192 struct btrfs_key key;
193 struct btrfs_inode_extref *extref;
194 struct extent_buffer *leaf;
195 int ret;
196 int del_len = name_len + sizeof(*extref);
197 unsigned long ptr;
198 unsigned long item_start;
199 u32 item_size;
200
201 key.objectid = inode_objectid;
202 btrfs_set_key_type(&key, BTRFS_INODE_EXTREF_KEY);
203 key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
204
205 path = btrfs_alloc_path();
206 if (!path)
207 return -ENOMEM;
208
209 path->leave_spinning = 1;
210
211 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
212 if (ret > 0)
213 ret = -ENOENT;
214 if (ret < 0)
215 goto out;
216
217 /*
218 * Sanity check - did we find the right item for this name?
219 * This should always succeed so error here will make the FS
220 * readonly.
221 */
222 if (!btrfs_find_name_in_ext_backref(path, ref_objectid,
223 name, name_len, &extref)) {
224 btrfs_std_error(root->fs_info, -ENOENT);
225 ret = -EROFS;
226 goto out;
227 }
228
229 leaf = path->nodes[0];
230 item_size = btrfs_item_size_nr(leaf, path->slots[0]);
231 if (index)
232 *index = btrfs_inode_extref_index(leaf, extref);
233
234 if (del_len == item_size) {
235 /*
236 * Common case only one ref in the item, remove the
237 * whole item.
238 */
239 ret = btrfs_del_item(trans, root, path);
240 goto out;
241 }
242
243 ptr = (unsigned long)extref;
244 item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
245
246 memmove_extent_buffer(leaf, ptr, ptr + del_len,
247 item_size - (ptr + del_len - item_start));
248
249 btrfs_truncate_item(trans, root, path, item_size - del_len, 1);
250
251out:
252 btrfs_free_path(path);
253
254 return ret;
255}
256
257int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
258 struct btrfs_root *root,
259 const char *name, int name_len,
260 u64 inode_objectid, u64 ref_objectid, u64 *index)
261{
262 struct btrfs_path *path;
263 struct btrfs_key key;
87 struct btrfs_inode_ref *ref; 264 struct btrfs_inode_ref *ref;
88 struct extent_buffer *leaf; 265 struct extent_buffer *leaf;
89 unsigned long ptr; 266 unsigned long ptr;
@@ -91,6 +268,7 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
91 u32 item_size; 268 u32 item_size;
92 u32 sub_item_len; 269 u32 sub_item_len;
93 int ret; 270 int ret;
271 int search_ext_refs = 0;
94 int del_len = name_len + sizeof(*ref); 272 int del_len = name_len + sizeof(*ref);
95 273
96 key.objectid = inode_objectid; 274 key.objectid = inode_objectid;
@@ -106,12 +284,14 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
106 ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 284 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
107 if (ret > 0) { 285 if (ret > 0) {
108 ret = -ENOENT; 286 ret = -ENOENT;
287 search_ext_refs = 1;
109 goto out; 288 goto out;
110 } else if (ret < 0) { 289 } else if (ret < 0) {
111 goto out; 290 goto out;
112 } 291 }
113 if (!find_name_in_backref(path, name, name_len, &ref)) { 292 if (!find_name_in_backref(path, name, name_len, &ref)) {
114 ret = -ENOENT; 293 ret = -ENOENT;
294 search_ext_refs = 1;
115 goto out; 295 goto out;
116 } 296 }
117 leaf = path->nodes[0]; 297 leaf = path->nodes[0];
@@ -129,8 +309,78 @@ int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
129 item_start = btrfs_item_ptr_offset(leaf, path->slots[0]); 309 item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
130 memmove_extent_buffer(leaf, ptr, ptr + sub_item_len, 310 memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
131 item_size - (ptr + sub_item_len - item_start)); 311 item_size - (ptr + sub_item_len - item_start));
132 btrfs_truncate_item(trans, root, path, 312 btrfs_truncate_item(trans, root, path, item_size - sub_item_len, 1);
133 item_size - sub_item_len, 1); 313out:
314 btrfs_free_path(path);
315
316 if (search_ext_refs) {
317 /*
318 * No refs were found, or we could not find the
319 * name in our ref array. Find and remove the extended
320 * inode ref then.
321 */
322 return btrfs_del_inode_extref(trans, root, name, name_len,
323 inode_objectid, ref_objectid, index);
324 }
325
326 return ret;
327}
328
329/*
330 * btrfs_insert_inode_extref() - Inserts an extended inode ref into a tree.
331 *
332 * The caller must have checked against BTRFS_LINK_MAX already.
333 */
334static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
335 struct btrfs_root *root,
336 const char *name, int name_len,
337 u64 inode_objectid, u64 ref_objectid, u64 index)
338{
339 struct btrfs_inode_extref *extref;
340 int ret;
341 int ins_len = name_len + sizeof(*extref);
342 unsigned long ptr;
343 struct btrfs_path *path;
344 struct btrfs_key key;
345 struct extent_buffer *leaf;
346 struct btrfs_item *item;
347
348 key.objectid = inode_objectid;
349 key.type = BTRFS_INODE_EXTREF_KEY;
350 key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
351
352 path = btrfs_alloc_path();
353 if (!path)
354 return -ENOMEM;
355
356 path->leave_spinning = 1;
357 ret = btrfs_insert_empty_item(trans, root, path, &key,
358 ins_len);
359 if (ret == -EEXIST) {
360 if (btrfs_find_name_in_ext_backref(path, ref_objectid,
361 name, name_len, NULL))
362 goto out;
363
364 btrfs_extend_item(trans, root, path, ins_len);
365 ret = 0;
366 }
367 if (ret < 0)
368 goto out;
369
370 leaf = path->nodes[0];
371 item = btrfs_item_nr(leaf, path->slots[0]);
372 ptr = (unsigned long)btrfs_item_ptr(leaf, path->slots[0], char);
373 ptr += btrfs_item_size(leaf, item) - ins_len;
374 extref = (struct btrfs_inode_extref *)ptr;
375
376 btrfs_set_inode_extref_name_len(path->nodes[0], extref, name_len);
377 btrfs_set_inode_extref_index(path->nodes[0], extref, index);
378 btrfs_set_inode_extref_parent(path->nodes[0], extref, ref_objectid);
379
380 ptr = (unsigned long)&extref->name;
381 write_extent_buffer(path->nodes[0], name, ptr, name_len);
382 btrfs_mark_buffer_dirty(path->nodes[0]);
383
134out: 384out:
135 btrfs_free_path(path); 385 btrfs_free_path(path);
136 return ret; 386 return ret;
@@ -191,6 +441,19 @@ int btrfs_insert_inode_ref(struct btrfs_trans_handle *trans,
191 441
192out: 442out:
193 btrfs_free_path(path); 443 btrfs_free_path(path);
444
445 if (ret == -EMLINK) {
446 struct btrfs_super_block *disk_super = root->fs_info->super_copy;
447 /* We ran out of space in the ref array. Need to
448 * add an extended ref. */
449 if (btrfs_super_incompat_flags(disk_super)
450 & BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
451 ret = btrfs_insert_inode_extref(trans, root, name,
452 name_len,
453 inode_objectid,
454 ref_objectid, index);
455 }
456
194 return ret; 457 return ret;
195} 458}
196 459
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1c50f7c4f5ac..596305e4d75b 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2903,7 +2903,6 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir,
2903 struct btrfs_trans_handle *trans; 2903 struct btrfs_trans_handle *trans;
2904 struct btrfs_root *root = BTRFS_I(dir)->root; 2904 struct btrfs_root *root = BTRFS_I(dir)->root;
2905 struct btrfs_path *path; 2905 struct btrfs_path *path;
2906 struct btrfs_inode_ref *ref;
2907 struct btrfs_dir_item *di; 2906 struct btrfs_dir_item *di;
2908 struct inode *inode = dentry->d_inode; 2907 struct inode *inode = dentry->d_inode;
2909 u64 index; 2908 u64 index;
@@ -3017,17 +3016,17 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir,
3017 } 3016 }
3018 btrfs_release_path(path); 3017 btrfs_release_path(path);
3019 3018
3020 ref = btrfs_lookup_inode_ref(trans, root, path, 3019 ret = btrfs_get_inode_ref_index(trans, root, path, dentry->d_name.name,
3021 dentry->d_name.name, dentry->d_name.len, 3020 dentry->d_name.len, ino, dir_ino, 0,
3022 ino, dir_ino, 0); 3021 &index);
3023 if (IS_ERR(ref)) { 3022 if (ret) {
3024 err = PTR_ERR(ref); 3023 err = ret;
3025 goto out; 3024 goto out;
3026 } 3025 }
3027 BUG_ON(!ref); /* Logic error */ 3026
3028 if (check_path_shared(root, path)) 3027 if (check_path_shared(root, path))
3029 goto out; 3028 goto out;
3030 index = btrfs_inode_ref_index(path->nodes[0], ref); 3029
3031 btrfs_release_path(path); 3030 btrfs_release_path(path);
3032 3031
3033 /* 3032 /*
@@ -4743,6 +4742,12 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
4743 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY); 4742 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);
4744 key[0].offset = 0; 4743 key[0].offset = 0;
4745 4744
4745 /*
4746 * Start new inodes with an inode_ref. This is slightly more
4747 * efficient for small numbers of hard links since they will
4748 * be packed into one item. Extended refs will kick in if we
4749 * add more hard links than can fit in the ref item.
4750 */
4746 key[1].objectid = objectid; 4751 key[1].objectid = objectid;
4747 btrfs_set_key_type(&key[1], BTRFS_INODE_REF_KEY); 4752 btrfs_set_key_type(&key[1], BTRFS_INODE_REF_KEY);
4748 key[1].offset = ref_objectid; 4753 key[1].offset = ref_objectid;
@@ -5049,7 +5054,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
5049 if (root->objectid != BTRFS_I(inode)->root->objectid) 5054 if (root->objectid != BTRFS_I(inode)->root->objectid)
5050 return -EXDEV; 5055 return -EXDEV;
5051 5056
5052 if (inode->i_nlink == ~0U) 5057 if (inode->i_nlink >= BTRFS_LINK_MAX)
5053 return -EMLINK; 5058 return -EMLINK;
5054 5059
5055 err = btrfs_set_inode_index(dir, &index); 5060 err = btrfs_set_inode_index(dir, &index);
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 15dae589e59f..1d7b34844323 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -24,8 +24,10 @@
24#include "disk-io.h" 24#include "disk-io.h"
25#include "locking.h" 25#include "locking.h"
26#include "print-tree.h" 26#include "print-tree.h"
27#include "backref.h"
27#include "compat.h" 28#include "compat.h"
28#include "tree-log.h" 29#include "tree-log.h"
30#include "hash.h"
29 31
30/* magic values for the inode_only field in btrfs_log_inode: 32/* magic values for the inode_only field in btrfs_log_inode:
31 * 33 *
@@ -743,6 +745,7 @@ out:
743 */ 745 */
744static noinline int backref_in_log(struct btrfs_root *log, 746static noinline int backref_in_log(struct btrfs_root *log,
745 struct btrfs_key *key, 747 struct btrfs_key *key,
748 u64 ref_objectid,
746 char *name, int namelen) 749 char *name, int namelen)
747{ 750{
748 struct btrfs_path *path; 751 struct btrfs_path *path;
@@ -763,8 +766,17 @@ static noinline int backref_in_log(struct btrfs_root *log,
763 if (ret != 0) 766 if (ret != 0)
764 goto out; 767 goto out;
765 768
766 item_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
767 ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]); 769 ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]);
770
771 if (key->type == BTRFS_INODE_EXTREF_KEY) {
772 if (btrfs_find_name_in_ext_backref(path, ref_objectid,
773 name, namelen, NULL))
774 match = 1;
775
776 goto out;
777 }
778
779 item_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
768 ptr_end = ptr + item_size; 780 ptr_end = ptr + item_size;
769 while (ptr < ptr_end) { 781 while (ptr < ptr_end) {
770 ref = (struct btrfs_inode_ref *)ptr; 782 ref = (struct btrfs_inode_ref *)ptr;
@@ -790,27 +802,36 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
790 struct btrfs_path *path, 802 struct btrfs_path *path,
791 struct btrfs_root *log_root, 803 struct btrfs_root *log_root,
792 struct inode *dir, struct inode *inode, 804 struct inode *dir, struct inode *inode,
793 struct btrfs_key *key,
794 struct extent_buffer *eb, 805 struct extent_buffer *eb,
795 struct btrfs_inode_ref *ref, 806 u64 inode_objectid, u64 parent_objectid,
796 char *name, int namelen, int *search_done) 807 u64 ref_index, char *name, int namelen,
808 int *search_done)
797{ 809{
798 int ret; 810 int ret;
811 char *victim_name;
812 int victim_name_len;
813 struct extent_buffer *leaf;
799 struct btrfs_dir_item *di; 814 struct btrfs_dir_item *di;
815 struct btrfs_key search_key;
816 struct btrfs_inode_extref *extref;
800 817
801 ret = btrfs_search_slot(NULL, root, key, path, 0, 0); 818again:
819 /* Search old style refs */
820 search_key.objectid = inode_objectid;
821 search_key.type = BTRFS_INODE_REF_KEY;
822 search_key.offset = parent_objectid;
823 ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
802 if (ret == 0) { 824 if (ret == 0) {
803 char *victim_name;
804 int victim_name_len;
805 struct btrfs_inode_ref *victim_ref; 825 struct btrfs_inode_ref *victim_ref;
806 unsigned long ptr; 826 unsigned long ptr;
807 unsigned long ptr_end; 827 unsigned long ptr_end;
808 struct extent_buffer *leaf = path->nodes[0]; 828
829 leaf = path->nodes[0];
809 830
810 /* are we trying to overwrite a back ref for the root directory 831 /* are we trying to overwrite a back ref for the root directory
811 * if so, just jump out, we're done 832 * if so, just jump out, we're done
812 */ 833 */
813 if (key->objectid == key->offset) 834 if (search_key.objectid == search_key.offset)
814 return 1; 835 return 1;
815 836
816 /* check all the names in this back reference to see 837 /* check all the names in this back reference to see
@@ -830,7 +851,9 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
830 (unsigned long)(victim_ref + 1), 851 (unsigned long)(victim_ref + 1),
831 victim_name_len); 852 victim_name_len);
832 853
833 if (!backref_in_log(log_root, key, victim_name, 854 if (!backref_in_log(log_root, &search_key,
855 parent_objectid,
856 victim_name,
834 victim_name_len)) { 857 victim_name_len)) {
835 btrfs_inc_nlink(inode); 858 btrfs_inc_nlink(inode);
836 btrfs_release_path(path); 859 btrfs_release_path(path);
@@ -838,9 +861,14 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
838 ret = btrfs_unlink_inode(trans, root, dir, 861 ret = btrfs_unlink_inode(trans, root, dir,
839 inode, victim_name, 862 inode, victim_name,
840 victim_name_len); 863 victim_name_len);
864 BUG_ON(ret);
841 btrfs_run_delayed_items(trans, root); 865 btrfs_run_delayed_items(trans, root);
866 kfree(victim_name);
867 *search_done = 1;
868 goto again;
842 } 869 }
843 kfree(victim_name); 870 kfree(victim_name);
871
844 ptr = (unsigned long)(victim_ref + 1) + victim_name_len; 872 ptr = (unsigned long)(victim_ref + 1) + victim_name_len;
845 } 873 }
846 BUG_ON(ret); 874 BUG_ON(ret);
@@ -853,10 +881,74 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
853 } 881 }
854 btrfs_release_path(path); 882 btrfs_release_path(path);
855 883
884 /* Same search but for extended refs */
885 extref = btrfs_lookup_inode_extref(NULL, root, path, name, namelen,
886 inode_objectid, parent_objectid, 0,
887 0);
888 if (!IS_ERR_OR_NULL(extref)) {
889 u32 item_size;
890 u32 cur_offset = 0;
891 unsigned long base;
892 struct inode *victim_parent;
893
894 leaf = path->nodes[0];
895
896 item_size = btrfs_item_size_nr(leaf, path->slots[0]);
897 base = btrfs_item_ptr_offset(leaf, path->slots[0]);
898
899 while (cur_offset < item_size) {
900 extref = (struct btrfs_inode_extref *)base + cur_offset;
901
902 victim_name_len = btrfs_inode_extref_name_len(leaf, extref);
903
904 if (btrfs_inode_extref_parent(leaf, extref) != parent_objectid)
905 goto next;
906
907 victim_name = kmalloc(victim_name_len, GFP_NOFS);
908 read_extent_buffer(leaf, victim_name, (unsigned long)&extref->name,
909 victim_name_len);
910
911 search_key.objectid = inode_objectid;
912 search_key.type = BTRFS_INODE_EXTREF_KEY;
913 search_key.offset = btrfs_extref_hash(parent_objectid,
914 victim_name,
915 victim_name_len);
916 ret = 0;
917 if (!backref_in_log(log_root, &search_key,
918 parent_objectid, victim_name,
919 victim_name_len)) {
920 ret = -ENOENT;
921 victim_parent = read_one_inode(root,
922 parent_objectid);
923 if (victim_parent) {
924 btrfs_inc_nlink(inode);
925 btrfs_release_path(path);
926
927 ret = btrfs_unlink_inode(trans, root,
928 victim_parent,
929 inode,
930 victim_name,
931 victim_name_len);
932 btrfs_run_delayed_items(trans, root);
933 }
934 BUG_ON(ret);
935 iput(victim_parent);
936 kfree(victim_name);
937 *search_done = 1;
938 goto again;
939 }
940 kfree(victim_name);
941 BUG_ON(ret);
942next:
943 cur_offset += victim_name_len + sizeof(*extref);
944 }
945 *search_done = 1;
946 }
947 btrfs_release_path(path);
948
856 /* look for a conflicting sequence number */ 949 /* look for a conflicting sequence number */
857 di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir), 950 di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir),
858 btrfs_inode_ref_index(eb, ref), 951 ref_index, name, namelen, 0);
859 name, namelen, 0);
860 if (di && !IS_ERR(di)) { 952 if (di && !IS_ERR(di)) {
861 ret = drop_one_dir_item(trans, root, path, dir, di); 953 ret = drop_one_dir_item(trans, root, path, dir, di);
862 BUG_ON(ret); 954 BUG_ON(ret);
@@ -875,6 +967,48 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
875 return 0; 967 return 0;
876} 968}
877 969
970static int extref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
971 u32 *namelen, char **name, u64 *index,
972 u64 *parent_objectid)
973{
974 struct btrfs_inode_extref *extref;
975
976 extref = (struct btrfs_inode_extref *)ref_ptr;
977
978 *namelen = btrfs_inode_extref_name_len(eb, extref);
979 *name = kmalloc(*namelen, GFP_NOFS);
980 if (*name == NULL)
981 return -ENOMEM;
982
983 read_extent_buffer(eb, *name, (unsigned long)&extref->name,
984 *namelen);
985
986 *index = btrfs_inode_extref_index(eb, extref);
987 if (parent_objectid)
988 *parent_objectid = btrfs_inode_extref_parent(eb, extref);
989
990 return 0;
991}
992
993static int ref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
994 u32 *namelen, char **name, u64 *index)
995{
996 struct btrfs_inode_ref *ref;
997
998 ref = (struct btrfs_inode_ref *)ref_ptr;
999
1000 *namelen = btrfs_inode_ref_name_len(eb, ref);
1001 *name = kmalloc(*namelen, GFP_NOFS);
1002 if (*name == NULL)
1003 return -ENOMEM;
1004
1005 read_extent_buffer(eb, *name, (unsigned long)(ref + 1), *namelen);
1006
1007 *index = btrfs_inode_ref_index(eb, ref);
1008
1009 return 0;
1010}
1011
878/* 1012/*
879 * replay one inode back reference item found in the log tree. 1013 * replay one inode back reference item found in the log tree.
880 * eb, slot and key refer to the buffer and key found in the log tree. 1014 * eb, slot and key refer to the buffer and key found in the log tree.
@@ -888,7 +1022,6 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
888 struct extent_buffer *eb, int slot, 1022 struct extent_buffer *eb, int slot,
889 struct btrfs_key *key) 1023 struct btrfs_key *key)
890{ 1024{
891 struct btrfs_inode_ref *ref;
892 struct inode *dir; 1025 struct inode *dir;
893 struct inode *inode; 1026 struct inode *inode;
894 unsigned long ref_ptr; 1027 unsigned long ref_ptr;
@@ -897,6 +1030,27 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
897 int namelen; 1030 int namelen;
898 int ret; 1031 int ret;
899 int search_done = 0; 1032 int search_done = 0;
1033 int log_ref_ver = 0;
1034 u64 parent_objectid;
1035 u64 inode_objectid;
1036 u64 ref_index;
1037 int ref_struct_size;
1038
1039 ref_ptr = btrfs_item_ptr_offset(eb, slot);
1040 ref_end = ref_ptr + btrfs_item_size_nr(eb, slot);
1041
1042 if (key->type == BTRFS_INODE_EXTREF_KEY) {
1043 struct btrfs_inode_extref *r;
1044
1045 ref_struct_size = sizeof(struct btrfs_inode_extref);
1046 log_ref_ver = 1;
1047 r = (struct btrfs_inode_extref *)ref_ptr;
1048 parent_objectid = btrfs_inode_extref_parent(eb, r);
1049 } else {
1050 ref_struct_size = sizeof(struct btrfs_inode_ref);
1051 parent_objectid = key->offset;
1052 }
1053 inode_objectid = key->objectid;
900 1054
901 /* 1055 /*
902 * it is possible that we didn't log all the parent directories 1056 * it is possible that we didn't log all the parent directories
@@ -904,32 +1058,38 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
904 * copy the back ref in. The link count fixup code will take 1058 * copy the back ref in. The link count fixup code will take
905 * care of the rest 1059 * care of the rest
906 */ 1060 */
907 dir = read_one_inode(root, key->offset); 1061 dir = read_one_inode(root, parent_objectid);
908 if (!dir) 1062 if (!dir)
909 return -ENOENT; 1063 return -ENOENT;
910 1064
911 inode = read_one_inode(root, key->objectid); 1065 inode = read_one_inode(root, inode_objectid);
912 if (!inode) { 1066 if (!inode) {
913 iput(dir); 1067 iput(dir);
914 return -EIO; 1068 return -EIO;
915 } 1069 }
916 1070
917 ref_ptr = btrfs_item_ptr_offset(eb, slot);
918 ref_end = ref_ptr + btrfs_item_size_nr(eb, slot);
919
920 while (ref_ptr < ref_end) { 1071 while (ref_ptr < ref_end) {
921 ref = (struct btrfs_inode_ref *)ref_ptr; 1072 if (log_ref_ver) {
922 1073 ret = extref_get_fields(eb, ref_ptr, &namelen, &name,
923 namelen = btrfs_inode_ref_name_len(eb, ref); 1074 &ref_index, &parent_objectid);
924 name = kmalloc(namelen, GFP_NOFS); 1075 /*
925 BUG_ON(!name); 1076 * parent object can change from one array
926 1077 * item to another.
927 read_extent_buffer(eb, name, (unsigned long)(ref + 1), namelen); 1078 */
1079 if (!dir)
1080 dir = read_one_inode(root, parent_objectid);
1081 if (!dir)
1082 return -ENOENT;
1083 } else {
1084 ret = ref_get_fields(eb, ref_ptr, &namelen, &name,
1085 &ref_index);
1086 }
1087 if (ret)
1088 return ret;
928 1089
929 /* if we already have a perfect match, we're done */ 1090 /* if we already have a perfect match, we're done */
930 if (!inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode), 1091 if (!inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode),
931 btrfs_inode_ref_index(eb, ref), 1092 ref_index, name, namelen)) {
932 name, namelen)) {
933 /* 1093 /*
934 * look for a conflicting back reference in the 1094 * look for a conflicting back reference in the
935 * metadata. if we find one we have to unlink that name 1095 * metadata. if we find one we have to unlink that name
@@ -940,8 +1100,10 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
940 1100
941 if (!search_done) { 1101 if (!search_done) {
942 ret = __add_inode_ref(trans, root, path, log, 1102 ret = __add_inode_ref(trans, root, path, log,
943 dir, inode, key, eb, ref, 1103 dir, inode, eb,
944 name, namelen, 1104 inode_objectid,
1105 parent_objectid,
1106 ref_index, name, namelen,
945 &search_done); 1107 &search_done);
946 if (ret == 1) 1108 if (ret == 1)
947 goto out; 1109 goto out;
@@ -950,14 +1112,18 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
950 1112
951 /* insert our name */ 1113 /* insert our name */
952 ret = btrfs_add_link(trans, dir, inode, name, namelen, 1114 ret = btrfs_add_link(trans, dir, inode, name, namelen,
953 0, btrfs_inode_ref_index(eb, ref)); 1115 0, ref_index);
954 BUG_ON(ret); 1116 BUG_ON(ret);
955 1117
956 btrfs_update_inode(trans, root, inode); 1118 btrfs_update_inode(trans, root, inode);
957 } 1119 }
958 1120
959 ref_ptr = (unsigned long)(ref + 1) + namelen; 1121 ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + namelen;
960 kfree(name); 1122 kfree(name);
1123 if (log_ref_ver) {
1124 iput(dir);
1125 dir = NULL;
1126 }
961 } 1127 }
962 1128
963 /* finally write the back reference in the inode */ 1129 /* finally write the back reference in the inode */
@@ -981,25 +1147,55 @@ static int insert_orphan_item(struct btrfs_trans_handle *trans,
981 return ret; 1147 return ret;
982} 1148}
983 1149
1150static int count_inode_extrefs(struct btrfs_root *root,
1151 struct inode *inode, struct btrfs_path *path)
1152{
1153 int ret = 0;
1154 int name_len;
1155 unsigned int nlink = 0;
1156 u32 item_size;
1157 u32 cur_offset = 0;
1158 u64 inode_objectid = btrfs_ino(inode);
1159 u64 offset = 0;
1160 unsigned long ptr;
1161 struct btrfs_inode_extref *extref;
1162 struct extent_buffer *leaf;
984 1163
985/* 1164 while (1) {
986 * There are a few corners where the link count of the file can't 1165 ret = btrfs_find_one_extref(root, inode_objectid, offset, path,
987 * be properly maintained during replay. So, instead of adding 1166 &extref, &offset);
988 * lots of complexity to the log code, we just scan the backrefs 1167 if (ret)
989 * for any file that has been through replay. 1168 break;
990 * 1169
991 * The scan will update the link count on the inode to reflect the 1170 leaf = path->nodes[0];
992 * number of back refs found. If it goes down to zero, the iput 1171 item_size = btrfs_item_size_nr(leaf, path->slots[0]);
993 * will free the inode. 1172 ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
994 */ 1173
995static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans, 1174 while (cur_offset < item_size) {
996 struct btrfs_root *root, 1175 extref = (struct btrfs_inode_extref *) (ptr + cur_offset);
997 struct inode *inode) 1176 name_len = btrfs_inode_extref_name_len(leaf, extref);
1177
1178 nlink++;
1179
1180 cur_offset += name_len + sizeof(*extref);
1181 }
1182
1183 offset++;
1184 btrfs_release_path(path);
1185 }
1186 btrfs_release_path(path);
1187
1188 if (ret < 0)
1189 return ret;
1190 return nlink;
1191}
1192
1193static int count_inode_refs(struct btrfs_root *root,
1194 struct inode *inode, struct btrfs_path *path)
998{ 1195{
999 struct btrfs_path *path;
1000 int ret; 1196 int ret;
1001 struct btrfs_key key; 1197 struct btrfs_key key;
1002 u64 nlink = 0; 1198 unsigned int nlink = 0;
1003 unsigned long ptr; 1199 unsigned long ptr;
1004 unsigned long ptr_end; 1200 unsigned long ptr_end;
1005 int name_len; 1201 int name_len;
@@ -1009,10 +1205,6 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
1009 key.type = BTRFS_INODE_REF_KEY; 1205 key.type = BTRFS_INODE_REF_KEY;
1010 key.offset = (u64)-1; 1206 key.offset = (u64)-1;
1011 1207
1012 path = btrfs_alloc_path();
1013 if (!path)
1014 return -ENOMEM;
1015
1016 while (1) { 1208 while (1) {
1017 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 1209 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
1018 if (ret < 0) 1210 if (ret < 0)
@@ -1046,6 +1238,50 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
1046 btrfs_release_path(path); 1238 btrfs_release_path(path);
1047 } 1239 }
1048 btrfs_release_path(path); 1240 btrfs_release_path(path);
1241
1242 return nlink;
1243}
1244
1245/*
1246 * There are a few corners where the link count of the file can't
1247 * be properly maintained during replay. So, instead of adding
1248 * lots of complexity to the log code, we just scan the backrefs
1249 * for any file that has been through replay.
1250 *
1251 * The scan will update the link count on the inode to reflect the
1252 * number of back refs found. If it goes down to zero, the iput
1253 * will free the inode.
1254 */
1255static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
1256 struct btrfs_root *root,
1257 struct inode *inode)
1258{
1259 struct btrfs_path *path;
1260 int ret;
1261 u64 nlink = 0;
1262 u64 ino = btrfs_ino(inode);
1263
1264 path = btrfs_alloc_path();
1265 if (!path)
1266 return -ENOMEM;
1267
1268 ret = count_inode_refs(root, inode, path);
1269 if (ret < 0)
1270 goto out;
1271
1272 nlink = ret;
1273
1274 ret = count_inode_extrefs(root, inode, path);
1275 if (ret == -ENOENT)
1276 ret = 0;
1277
1278 if (ret < 0)
1279 goto out;
1280
1281 nlink += ret;
1282
1283 ret = 0;
1284
1049 if (nlink != inode->i_nlink) { 1285 if (nlink != inode->i_nlink) {
1050 set_nlink(inode, nlink); 1286 set_nlink(inode, nlink);
1051 btrfs_update_inode(trans, root, inode); 1287 btrfs_update_inode(trans, root, inode);
@@ -1061,9 +1297,10 @@ static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
1061 ret = insert_orphan_item(trans, root, ino); 1297 ret = insert_orphan_item(trans, root, ino);
1062 BUG_ON(ret); 1298 BUG_ON(ret);
1063 } 1299 }
1064 btrfs_free_path(path);
1065 1300
1066 return 0; 1301out:
1302 btrfs_free_path(path);
1303 return ret;
1067} 1304}
1068 1305
1069static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans, 1306static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans,
@@ -1710,6 +1947,10 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
1710 ret = add_inode_ref(wc->trans, root, log, path, 1947 ret = add_inode_ref(wc->trans, root, log, path,
1711 eb, i, &key); 1948 eb, i, &key);
1712 BUG_ON(ret && ret != -ENOENT); 1949 BUG_ON(ret && ret != -ENOENT);
1950 } else if (key.type == BTRFS_INODE_EXTREF_KEY) {
1951 ret = add_inode_ref(wc->trans, root, log, path,
1952 eb, i, &key);
1953 BUG_ON(ret && ret != -ENOENT);
1713 } else if (key.type == BTRFS_EXTENT_DATA_KEY) { 1954 } else if (key.type == BTRFS_EXTENT_DATA_KEY) {
1714 ret = replay_one_extent(wc->trans, root, path, 1955 ret = replay_one_extent(wc->trans, root, path,
1715 eb, i, &key); 1956 eb, i, &key);