Blame view

fs/btrfs/dir-item.c 11.4 KB
c1d7c514f   David Sterba   btrfs: replace GP...
1
  // SPDX-License-Identifier: GPL-2.0
6cbd55707   Chris Mason   Btrfs: add GPLv2
2
3
  /*
   * Copyright (C) 2007 Oracle.  All rights reserved.
6cbd55707   Chris Mason   Btrfs: add GPLv2
4
   */
62e2749e0   Chris Mason   Btrfs: Use a chun...
5
6
  #include "ctree.h"
  #include "disk-io.h"
e089f05c1   Chris Mason   Btrfs: transactio...
7
  #include "transaction.h"
62e2749e0   Chris Mason   Btrfs: Use a chun...
8

d352ac681   Chris Mason   Btrfs: add and im...
9
10
11
12
13
14
15
16
  /*
   * insert a name into a directory, doing overflow properly if there is a hash
   * collision.  data_size indicates how big the item inserted should be.  On
   * success a struct btrfs_dir_item pointer is returned, otherwise it is
   * an ERR_PTR.
   *
   * The name is not copied into the dir item, you have to do that yourself.
   */
35b7e4761   Chris Mason   Btrfs: fix page c...
17
18
19
20
21
  static struct btrfs_dir_item *insert_with_overflow(struct btrfs_trans_handle
  						   *trans,
  						   struct btrfs_root *root,
  						   struct btrfs_path *path,
  						   struct btrfs_key *cpu_key,
e06afa839   Chris Mason   Btrfs: rename
22
23
24
  						   u32 data_size,
  						   const char *name,
  						   int name_len)
7fcde0e32   Chris Mason   Btrfs: finish off...
25
  {
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
26
  	struct btrfs_fs_info *fs_info = root->fs_info;
7fcde0e32   Chris Mason   Btrfs: finish off...
27
  	int ret;
7e38180e2   Chris Mason   Btrfs: directory ...
28
29
  	char *ptr;
  	struct btrfs_item *item;
5f39d397d   Chris Mason   Btrfs: Create ext...
30
  	struct extent_buffer *leaf;
7fcde0e32   Chris Mason   Btrfs: finish off...
31
32
  
  	ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
7e38180e2   Chris Mason   Btrfs: directory ...
33
  	if (ret == -EEXIST) {
e06afa839   Chris Mason   Btrfs: rename
34
  		struct btrfs_dir_item *di;
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
35
  		di = btrfs_match_dir_item_name(fs_info, path, name, name_len);
e06afa839   Chris Mason   Btrfs: rename
36
37
  		if (di)
  			return ERR_PTR(-EEXIST);
c71dd8800   David Sterba   btrfs: remove unu...
38
  		btrfs_extend_item(path, data_size);
143bede52   Jeff Mahoney   btrfs: return voi...
39
  	} else if (ret < 0)
54aa1f4df   Chris Mason   Btrfs: Audit call...
40
  		return ERR_PTR(ret);
7e38180e2   Chris Mason   Btrfs: directory ...
41
  	WARN_ON(ret > 0);
5f39d397d   Chris Mason   Btrfs: Create ext...
42
  	leaf = path->nodes[0];
dd3cc16b8   Ross Kirk   btrfs: drop unuse...
43
  	item = btrfs_item_nr(path->slots[0]);
7e38180e2   Chris Mason   Btrfs: directory ...
44
  	ptr = btrfs_item_ptr(leaf, path->slots[0], char);
5f39d397d   Chris Mason   Btrfs: Create ext...
45
46
  	BUG_ON(data_size > btrfs_item_size(leaf, item));
  	ptr += btrfs_item_size(leaf, item) - data_size;
7e38180e2   Chris Mason   Btrfs: directory ...
47
  	return (struct btrfs_dir_item *)ptr;
7fcde0e32   Chris Mason   Btrfs: finish off...
48
  }
d352ac681   Chris Mason   Btrfs: add and im...
49
50
51
52
  /*
   * xattrs work a lot like directories, this inserts an xattr item
   * into the tree
   */
5103e947b   Josef Bacik   xattr support for...
53
  int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans,
f34f57a3a   Yan, Zheng   Btrfs: Pass trans...
54
55
56
57
  			    struct btrfs_root *root,
  			    struct btrfs_path *path, u64 objectid,
  			    const char *name, u16 name_len,
  			    const void *data, u16 data_len)
5103e947b   Josef Bacik   xattr support for...
58
59
  {
  	int ret = 0;
5103e947b   Josef Bacik   xattr support for...
60
61
62
63
64
65
  	struct btrfs_dir_item *dir_item;
  	unsigned long name_ptr, data_ptr;
  	struct btrfs_key key, location;
  	struct btrfs_disk_key disk_key;
  	struct extent_buffer *leaf;
  	u32 data_size;
b9d04c607   David Sterba   btrfs: do proper ...
66
67
  	if (name_len + data_len > BTRFS_MAX_XATTR_SIZE(root->fs_info))
  		return -ENOSPC;
f34f57a3a   Yan, Zheng   Btrfs: Pass trans...
68
69
  
  	key.objectid = objectid;
962a298f3   David Sterba   btrfs: kill the k...
70
  	key.type = BTRFS_XATTR_ITEM_KEY;
df68b8a7a   David Miller   Btrfs: unaligned ...
71
  	key.offset = btrfs_name_hash(name, name_len);
5103e947b   Josef Bacik   xattr support for...
72
73
74
75
  
  	data_size = sizeof(*dir_item) + name_len + data_len;
  	dir_item = insert_with_overflow(trans, root, path, &key, data_size,
  					name, name_len);
fa09200b8   Josef Bacik   Btrfs: try to onl...
76
77
  	if (IS_ERR(dir_item))
  		return PTR_ERR(dir_item);
5103e947b   Josef Bacik   xattr support for...
78
79
80
81
82
83
84
  	memset(&location, 0, sizeof(location));
  
  	leaf = path->nodes[0];
  	btrfs_cpu_key_to_disk(&disk_key, &location);
  	btrfs_set_dir_item_key(leaf, dir_item, &disk_key);
  	btrfs_set_dir_type(leaf, dir_item, BTRFS_FT_XATTR);
  	btrfs_set_dir_name_len(leaf, dir_item, name_len);
e02119d5a   Chris Mason   Btrfs: Add a writ...
85
  	btrfs_set_dir_transid(leaf, dir_item, trans->transid);
5103e947b   Josef Bacik   xattr support for...
86
87
88
89
90
91
92
  	btrfs_set_dir_data_len(leaf, dir_item, data_len);
  	name_ptr = (unsigned long)(dir_item + 1);
  	data_ptr = (unsigned long)((char *)name_ptr + name_len);
  
  	write_extent_buffer(leaf, name, name_ptr, name_len);
  	write_extent_buffer(leaf, data, data_ptr, data_len);
  	btrfs_mark_buffer_dirty(path->nodes[0]);
5103e947b   Josef Bacik   xattr support for...
93
94
  	return ret;
  }
d352ac681   Chris Mason   Btrfs: add and im...
95
96
97
98
99
100
  /*
   * insert a directory item in the tree, doing all the magic for
   * both indexes. 'dir' indicates which objectid to insert it into,
   * 'location' is the key to stuff into the directory item, 'type' is the
   * type of the inode we're pointing to, and 'index' is the sequence number
   * to use for the second index (if one is created).
79787eaab   Jeff Mahoney   btrfs: replace ma...
101
   * Will return 0 or -ENOMEM
d352ac681   Chris Mason   Btrfs: add and im...
102
   */
684572df9   Lu Fengqi   btrfs: Remove roo...
103
104
105
  int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, const char *name,
  			  int name_len, struct btrfs_inode *dir,
  			  struct btrfs_key *location, u8 type, u64 index)
62e2749e0   Chris Mason   Btrfs: Use a chun...
106
107
  {
  	int ret = 0;
e06afa839   Chris Mason   Btrfs: rename
108
  	int ret2 = 0;
684572df9   Lu Fengqi   btrfs: Remove roo...
109
  	struct btrfs_root *root = dir->root;
5caf2a002   Chris Mason   Btrfs: dynamic al...
110
  	struct btrfs_path *path;
62e2749e0   Chris Mason   Btrfs: Use a chun...
111
  	struct btrfs_dir_item *dir_item;
5f39d397d   Chris Mason   Btrfs: Create ext...
112
113
  	struct extent_buffer *leaf;
  	unsigned long name_ptr;
62e2749e0   Chris Mason   Btrfs: Use a chun...
114
  	struct btrfs_key key;
5f39d397d   Chris Mason   Btrfs: Create ext...
115
  	struct btrfs_disk_key disk_key;
62e2749e0   Chris Mason   Btrfs: Use a chun...
116
  	u32 data_size;
8e7611cf3   Nikolay Borisov   btrfs: Make btrfs...
117
  	key.objectid = btrfs_ino(dir);
962a298f3   David Sterba   btrfs: kill the k...
118
  	key.type = BTRFS_DIR_ITEM_KEY;
df68b8a7a   David Miller   Btrfs: unaligned ...
119
  	key.offset = btrfs_name_hash(name, name_len);
b9473439d   Chris Mason   Btrfs: leave btre...
120

5caf2a002   Chris Mason   Btrfs: dynamic al...
121
  	path = btrfs_alloc_path();
16cdcec73   Miao Xie   btrfs: implement ...
122
123
  	if (!path)
  		return -ENOMEM;
b9473439d   Chris Mason   Btrfs: leave btre...
124
  	path->leave_spinning = 1;
16cdcec73   Miao Xie   btrfs: implement ...
125
  	btrfs_cpu_key_to_disk(&disk_key, location);
62e2749e0   Chris Mason   Btrfs: Use a chun...
126
  	data_size = sizeof(*dir_item) + name_len;
e06afa839   Chris Mason   Btrfs: rename
127
128
  	dir_item = insert_with_overflow(trans, root, path, &key, data_size,
  					name, name_len);
7e38180e2   Chris Mason   Btrfs: directory ...
129
130
  	if (IS_ERR(dir_item)) {
  		ret = PTR_ERR(dir_item);
e06afa839   Chris Mason   Btrfs: rename
131
132
  		if (ret == -EEXIST)
  			goto second_insert;
c2db1073f   Tsutomu Itoh   Btrfs: check retu...
133
  		goto out_free;
7e38180e2   Chris Mason   Btrfs: directory ...
134
  	}
62e2749e0   Chris Mason   Btrfs: Use a chun...
135

5f39d397d   Chris Mason   Btrfs: Create ext...
136
  	leaf = path->nodes[0];
5f39d397d   Chris Mason   Btrfs: Create ext...
137
138
  	btrfs_set_dir_item_key(leaf, dir_item, &disk_key);
  	btrfs_set_dir_type(leaf, dir_item, type);
5103e947b   Josef Bacik   xattr support for...
139
  	btrfs_set_dir_data_len(leaf, dir_item, 0);
5f39d397d   Chris Mason   Btrfs: Create ext...
140
  	btrfs_set_dir_name_len(leaf, dir_item, name_len);
e02119d5a   Chris Mason   Btrfs: Add a writ...
141
  	btrfs_set_dir_transid(leaf, dir_item, trans->transid);
5f39d397d   Chris Mason   Btrfs: Create ext...
142
  	name_ptr = (unsigned long)(dir_item + 1);
c5739bba5   Chris Mason   Btrfs: snapshot p...
143

5f39d397d   Chris Mason   Btrfs: Create ext...
144
145
  	write_extent_buffer(leaf, name, name_ptr, name_len);
  	btrfs_mark_buffer_dirty(leaf);
7e38180e2   Chris Mason   Btrfs: directory ...
146

e06afa839   Chris Mason   Btrfs: rename
147
  second_insert:
7e38180e2   Chris Mason   Btrfs: directory ...
148
149
150
  	/* FIXME, use some real flag for selecting the extra index */
  	if (root == root->fs_info->tree_root) {
  		ret = 0;
c2db1073f   Tsutomu Itoh   Btrfs: check retu...
151
  		goto out_free;
7e38180e2   Chris Mason   Btrfs: directory ...
152
  	}
b3b4aa74b   David Sterba   btrfs: drop unuse...
153
  	btrfs_release_path(path);
7e38180e2   Chris Mason   Btrfs: directory ...
154

4465c8b42   Lu Fengqi   btrfs: Remove fs_...
155
156
  	ret2 = btrfs_insert_delayed_dir_index(trans, name, name_len, dir,
  					      &disk_key, type, index);
c2db1073f   Tsutomu Itoh   Btrfs: check retu...
157
  out_free:
5caf2a002   Chris Mason   Btrfs: dynamic al...
158
  	btrfs_free_path(path);
e06afa839   Chris Mason   Btrfs: rename
159
160
161
162
163
  	if (ret)
  		return ret;
  	if (ret2)
  		return ret2;
  	return 0;
62e2749e0   Chris Mason   Btrfs: Use a chun...
164
  }
d352ac681   Chris Mason   Btrfs: add and im...
165
166
167
168
169
  /*
   * lookup a directory item based on name.  'dir' is the objectid
   * we're searching in, and 'mod' tells us if you plan on deleting the
   * item (use mod < 0) or changing the options (use mod > 0)
   */
7e38180e2   Chris Mason   Btrfs: directory ...
170
171
172
173
174
  struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans,
  					     struct btrfs_root *root,
  					     struct btrfs_path *path, u64 dir,
  					     const char *name, int name_len,
  					     int mod)
62e2749e0   Chris Mason   Btrfs: Use a chun...
175
  {
1d4f6404d   Chris Mason   Btrfs: directory ...
176
  	int ret;
62e2749e0   Chris Mason   Btrfs: Use a chun...
177
  	struct btrfs_key key;
1d4f6404d   Chris Mason   Btrfs: directory ...
178
179
  	int ins_len = mod < 0 ? -1 : 0;
  	int cow = mod != 0;
62e2749e0   Chris Mason   Btrfs: Use a chun...
180
181
  
  	key.objectid = dir;
962a298f3   David Sterba   btrfs: kill the k...
182
  	key.type = BTRFS_DIR_ITEM_KEY;
5f39d397d   Chris Mason   Btrfs: Create ext...
183

df68b8a7a   David Miller   Btrfs: unaligned ...
184
  	key.offset = btrfs_name_hash(name, name_len);
5f39d397d   Chris Mason   Btrfs: Create ext...
185

7e38180e2   Chris Mason   Btrfs: directory ...
186
187
188
  	ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
  	if (ret < 0)
  		return ERR_PTR(ret);
85d85a743   Li Zefan   Btrfs: remove red...
189
  	if (ret > 0)
7e38180e2   Chris Mason   Btrfs: directory ...
190
  		return NULL;
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
191
  	return btrfs_match_dir_item_name(root->fs_info, path, name, name_len);
62e2749e0   Chris Mason   Btrfs: Use a chun...
192
  }
9c52057c6   Chris Mason   Btrfs: fix hash o...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
  int btrfs_check_dir_item_collision(struct btrfs_root *root, u64 dir,
  				   const char *name, int name_len)
  {
  	int ret;
  	struct btrfs_key key;
  	struct btrfs_dir_item *di;
  	int data_size;
  	struct extent_buffer *leaf;
  	int slot;
  	struct btrfs_path *path;
  
  
  	path = btrfs_alloc_path();
  	if (!path)
  		return -ENOMEM;
  
  	key.objectid = dir;
962a298f3   David Sterba   btrfs: kill the k...
210
  	key.type = BTRFS_DIR_ITEM_KEY;
9c52057c6   Chris Mason   Btrfs: fix hash o...
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
  	key.offset = btrfs_name_hash(name, name_len);
  
  	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
  
  	/* return back any errors */
  	if (ret < 0)
  		goto out;
  
  	/* nothing found, we're safe */
  	if (ret > 0) {
  		ret = 0;
  		goto out;
  	}
  
  	/* we found an item, look for our name in the item */
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
226
  	di = btrfs_match_dir_item_name(root->fs_info, path, name, name_len);
9c52057c6   Chris Mason   Btrfs: fix hash o...
227
228
229
230
231
232
233
234
235
236
  	if (di) {
  		/* our exact name was found */
  		ret = -EEXIST;
  		goto out;
  	}
  
  	/*
  	 * see if there is room in the item to insert this
  	 * name
  	 */
878f2d2cb   Filipe David Borba Manana   Btrfs: fix max di...
237
  	data_size = sizeof(*di) + name_len;
9c52057c6   Chris Mason   Btrfs: fix hash o...
238
239
240
  	leaf = path->nodes[0];
  	slot = path->slots[0];
  	if (data_size + btrfs_item_size_nr(leaf, slot) +
da17066c4   Jeff Mahoney   btrfs: pull node/...
241
  	    sizeof(struct btrfs_item) > BTRFS_LEAF_DATA_SIZE(root->fs_info)) {
9c52057c6   Chris Mason   Btrfs: fix hash o...
242
243
244
245
246
247
248
249
250
  		ret = -EOVERFLOW;
  	} else {
  		/* plenty of insertion room */
  		ret = 0;
  	}
  out:
  	btrfs_free_path(path);
  	return ret;
  }
d352ac681   Chris Mason   Btrfs: add and im...
251
252
253
254
255
256
257
258
  /*
   * lookup a directory item based on index.  'dir' is the objectid
   * we're searching in, and 'mod' tells us if you plan on deleting the
   * item (use mod < 0) or changing the options (use mod > 0)
   *
   * The name is used to make sure the index really points to the name you were
   * looking for.
   */
7e38180e2   Chris Mason   Btrfs: directory ...
259
260
261
262
263
264
265
266
267
268
269
270
271
  struct btrfs_dir_item *
  btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans,
  			    struct btrfs_root *root,
  			    struct btrfs_path *path, u64 dir,
  			    u64 objectid, const char *name, int name_len,
  			    int mod)
  {
  	int ret;
  	struct btrfs_key key;
  	int ins_len = mod < 0 ? -1 : 0;
  	int cow = mod != 0;
  
  	key.objectid = dir;
962a298f3   David Sterba   btrfs: kill the k...
272
  	key.type = BTRFS_DIR_INDEX_KEY;
7e38180e2   Chris Mason   Btrfs: directory ...
273
274
275
276
277
278
279
  	key.offset = objectid;
  
  	ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
  	if (ret < 0)
  		return ERR_PTR(ret);
  	if (ret > 0)
  		return ERR_PTR(-ENOENT);
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
280
  	return btrfs_match_dir_item_name(root->fs_info, path, name, name_len);
7e38180e2   Chris Mason   Btrfs: directory ...
281
  }
4df27c4d5   Yan, Zheng   Btrfs: change how...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
  struct btrfs_dir_item *
  btrfs_search_dir_index_item(struct btrfs_root *root,
  			    struct btrfs_path *path, u64 dirid,
  			    const char *name, int name_len)
  {
  	struct extent_buffer *leaf;
  	struct btrfs_dir_item *di;
  	struct btrfs_key key;
  	u32 nritems;
  	int ret;
  
  	key.objectid = dirid;
  	key.type = BTRFS_DIR_INDEX_KEY;
  	key.offset = 0;
  
  	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
  	if (ret < 0)
  		return ERR_PTR(ret);
  
  	leaf = path->nodes[0];
  	nritems = btrfs_header_nritems(leaf);
  
  	while (1) {
  		if (path->slots[0] >= nritems) {
  			ret = btrfs_next_leaf(root, path);
  			if (ret < 0)
  				return ERR_PTR(ret);
  			if (ret > 0)
  				break;
  			leaf = path->nodes[0];
  			nritems = btrfs_header_nritems(leaf);
  			continue;
  		}
  
  		btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
  		if (key.objectid != dirid || key.type != BTRFS_DIR_INDEX_KEY)
  			break;
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
319
320
  		di = btrfs_match_dir_item_name(root->fs_info, path,
  					       name, name_len);
4df27c4d5   Yan, Zheng   Btrfs: change how...
321
322
323
324
325
326
327
  		if (di)
  			return di;
  
  		path->slots[0]++;
  	}
  	return NULL;
  }
5103e947b   Josef Bacik   xattr support for...
328
329
330
331
332
333
334
335
336
337
  struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans,
  					  struct btrfs_root *root,
  					  struct btrfs_path *path, u64 dir,
  					  const char *name, u16 name_len,
  					  int mod)
  {
  	int ret;
  	struct btrfs_key key;
  	int ins_len = mod < 0 ? -1 : 0;
  	int cow = mod != 0;
5103e947b   Josef Bacik   xattr support for...
338
339
  
  	key.objectid = dir;
962a298f3   David Sterba   btrfs: kill the k...
340
  	key.type = BTRFS_XATTR_ITEM_KEY;
df68b8a7a   David Miller   Btrfs: unaligned ...
341
  	key.offset = btrfs_name_hash(name, name_len);
5103e947b   Josef Bacik   xattr support for...
342
343
344
  	ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
  	if (ret < 0)
  		return ERR_PTR(ret);
85d85a743   Li Zefan   Btrfs: remove red...
345
  	if (ret > 0)
5103e947b   Josef Bacik   xattr support for...
346
  		return NULL;
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
347
  	return btrfs_match_dir_item_name(root->fs_info, path, name, name_len);
5103e947b   Josef Bacik   xattr support for...
348
  }
d352ac681   Chris Mason   Btrfs: add and im...
349
350
351
352
353
  /*
   * helper function to look at the directory item pointed to by 'path'
   * this walks through all the entries in a dir item and finds one
   * for a specific name.
   */
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
354
  struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_fs_info *fs_info,
5f5bc6b1e   Filipe Manana   Btrfs: make xattr...
355
356
  						 struct btrfs_path *path,
  						 const char *name, int name_len)
62e2749e0   Chris Mason   Btrfs: Use a chun...
357
  {
62e2749e0   Chris Mason   Btrfs: Use a chun...
358
  	struct btrfs_dir_item *dir_item;
5f39d397d   Chris Mason   Btrfs: Create ext...
359
  	unsigned long name_ptr;
7e38180e2   Chris Mason   Btrfs: directory ...
360
361
362
  	u32 total_len;
  	u32 cur = 0;
  	u32 this_len;
5f39d397d   Chris Mason   Btrfs: Create ext...
363
  	struct extent_buffer *leaf;
a8a2ee0c6   Chris Mason   Btrfs: add a name...
364

5f39d397d   Chris Mason   Btrfs: Create ext...
365
  	leaf = path->nodes[0];
7e38180e2   Chris Mason   Btrfs: directory ...
366
  	dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item);
22a94d44b   Josef Bacik   Btrfs: add checks...
367

5f39d397d   Chris Mason   Btrfs: Create ext...
368
  	total_len = btrfs_item_size_nr(leaf, path->slots[0]);
d397712bc   Chris Mason   Btrfs: Fix checkp...
369
  	while (cur < total_len) {
5f39d397d   Chris Mason   Btrfs: Create ext...
370
  		this_len = sizeof(*dir_item) +
5103e947b   Josef Bacik   xattr support for...
371
372
  			btrfs_dir_name_len(leaf, dir_item) +
  			btrfs_dir_data_len(leaf, dir_item);
5f39d397d   Chris Mason   Btrfs: Create ext...
373
  		name_ptr = (unsigned long)(dir_item + 1);
7e38180e2   Chris Mason   Btrfs: directory ...
374

5f39d397d   Chris Mason   Btrfs: Create ext...
375
376
  		if (btrfs_dir_name_len(leaf, dir_item) == name_len &&
  		    memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)
7e38180e2   Chris Mason   Btrfs: directory ...
377
378
379
380
381
382
383
  			return dir_item;
  
  		cur += this_len;
  		dir_item = (struct btrfs_dir_item *)((char *)dir_item +
  						     this_len);
  	}
  	return NULL;
62e2749e0   Chris Mason   Btrfs: Use a chun...
384
  }
7e38180e2   Chris Mason   Btrfs: directory ...
385

d352ac681   Chris Mason   Btrfs: add and im...
386
387
388
389
  /*
   * given a pointer into a directory item, delete it.  This
   * handles items that have more than one entry in them.
   */
7e38180e2   Chris Mason   Btrfs: directory ...
390
391
392
393
394
  int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
  			      struct btrfs_root *root,
  			      struct btrfs_path *path,
  			      struct btrfs_dir_item *di)
  {
5f39d397d   Chris Mason   Btrfs: Create ext...
395
  	struct extent_buffer *leaf;
7e38180e2   Chris Mason   Btrfs: directory ...
396
397
  	u32 sub_item_len;
  	u32 item_len;
54aa1f4df   Chris Mason   Btrfs: Audit call...
398
  	int ret = 0;
7e38180e2   Chris Mason   Btrfs: directory ...
399

5f39d397d   Chris Mason   Btrfs: Create ext...
400
  	leaf = path->nodes[0];
5103e947b   Josef Bacik   xattr support for...
401
402
  	sub_item_len = sizeof(*di) + btrfs_dir_name_len(leaf, di) +
  		btrfs_dir_data_len(leaf, di);
5f39d397d   Chris Mason   Btrfs: Create ext...
403
404
  	item_len = btrfs_item_size_nr(leaf, path->slots[0]);
  	if (sub_item_len == item_len) {
7e38180e2   Chris Mason   Btrfs: directory ...
405
  		ret = btrfs_del_item(trans, root, path);
7e38180e2   Chris Mason   Btrfs: directory ...
406
  	} else {
5f39d397d   Chris Mason   Btrfs: Create ext...
407
408
409
410
411
412
  		/* MARKER */
  		unsigned long ptr = (unsigned long)di;
  		unsigned long start;
  
  		start = btrfs_item_ptr_offset(leaf, path->slots[0]);
  		memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
7e38180e2   Chris Mason   Btrfs: directory ...
413
  			item_len - (ptr + sub_item_len - start));
78ac4f9e5   David Sterba   btrfs: remove unu...
414
  		btrfs_truncate_item(path, item_len - sub_item_len, 1);
7e38180e2   Chris Mason   Btrfs: directory ...
415
  	}
411fc6bce   Andi Kleen   Btrfs: Fix variab...
416
  	return ret;
7e38180e2   Chris Mason   Btrfs: directory ...
417
  }