219
220
return btrfs_match_dir_item_name(root, path, name, name_len);
223
struct btrfs_dir_item *btrfs_lookup_dir_index(struct btrfs_trans_handle *trans,
224
struct btrfs_root *root,
225
struct btrfs_path *path, u64 dir,
226
const char *name, int name_len,
230
struct btrfs_key key;
231
int ins_len = mod < 0 ? -1 : 0;
235
key.type = BTRFS_DIR_INDEX_KEY;
238
ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
242
return ERR_PTR(-ENOENT);
244
return btrfs_match_dir_item_name(root, path, name, name_len);
248
* given a pointer into a directory item, delete it. This
249
* handles items that have more than one entry in them.
251
int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
252
struct btrfs_root *root,
253
struct btrfs_path *path,
254
struct btrfs_dir_item *di)
257
struct extent_buffer *leaf;
262
leaf = path->nodes[0];
263
sub_item_len = sizeof(*di) + btrfs_dir_name_len(leaf, di) +
264
btrfs_dir_data_len(leaf, di);
265
item_len = btrfs_item_size_nr(leaf, path->slots[0]);
266
if (sub_item_len == item_len) {
267
ret = btrfs_del_item(trans, root, path);
269
unsigned long ptr = (unsigned long)di;
272
start = btrfs_item_ptr_offset(leaf, path->slots[0]);
273
memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
274
item_len - (ptr + sub_item_len - start));
275
btrfs_truncate_item(trans, root, path, item_len - sub_item_len, 1);
280
int verify_dir_item(struct btrfs_root *root,
281
struct extent_buffer *leaf,
282
struct btrfs_dir_item *dir_item)
284
u16 namelen = BTRFS_NAME_LEN;
285
u8 type = btrfs_dir_type(leaf, dir_item);
287
if (type >= BTRFS_FT_MAX) {
288
fprintf(stderr, "invalid dir item type: %d",
293
if (type == BTRFS_FT_XATTR)
294
namelen = XATTR_NAME_MAX;
296
if (btrfs_dir_name_len(leaf, dir_item) > namelen) {
297
fprintf(stderr, "invalid dir item name len: %u",
298
(unsigned)btrfs_dir_data_len(leaf, dir_item));
302
/* BTRFS_MAX_XATTR_SIZE is the same for all dir items */
303
if ((btrfs_dir_data_len(leaf, dir_item) +
304
btrfs_dir_name_len(leaf, dir_item)) > BTRFS_MAX_XATTR_SIZE(root)) {
305
fprintf(stderr, "invalid dir item name + data len: %u + %u",
306
(unsigned)btrfs_dir_name_len(leaf, dir_item),
307
(unsigned)btrfs_dir_data_len(leaf, dir_item));
222
314
static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
223
315
struct btrfs_path *path,
224
316
const char *name, int name_len)
233
325
leaf = path->nodes[0];
234
326
dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item);
235
327
total_len = btrfs_item_size_nr(leaf, path->slots[0]);
328
if (verify_dir_item(root, leaf, dir_item))
236
331
while(cur < total_len) {
237
332
this_len = sizeof(*dir_item) +
238
333
btrfs_dir_name_len(leaf, dir_item) +
239
334
btrfs_dir_data_len(leaf, dir_item);
335
if (this_len > (total_len - cur)) {
336
fprintf(stderr, "invalid dir item size\n");
240
340
name_ptr = (unsigned long)(dir_item + 1);
242
342
if (btrfs_dir_name_len(leaf, dir_item) == name_len &&