Blame view

fs/btrfs/dir-item.c 11.6 KB
6cbd55707   Chris Mason   Btrfs: add GPLv2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /*
   * Copyright (C) 2007 Oracle.  All rights reserved.
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public
   * License v2 as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public
   * License along with this program; if not, write to the
   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   * Boston, MA 021110-1307, USA.
   */
62e2749e0   Chris Mason   Btrfs: Use a chun...
18
19
20
  #include "ctree.h"
  #include "disk-io.h"
  #include "hash.h"
e089f05c1   Chris Mason   Btrfs: transactio...
21
  #include "transaction.h"
62e2749e0   Chris Mason   Btrfs: Use a chun...
22

d352ac681   Chris Mason   Btrfs: add and im...
23
24
25
26
27
28
29
30
  /*
   * 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...
31
32
33
34
35
  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
36
37
38
  						   u32 data_size,
  						   const char *name,
  						   int name_len)
7fcde0e32   Chris Mason   Btrfs: finish off...
39
  {
7fcde0e32   Chris Mason   Btrfs: finish off...
40
  	int ret;
7e38180e2   Chris Mason   Btrfs: directory ...
41
42
  	char *ptr;
  	struct btrfs_item *item;
5f39d397d   Chris Mason   Btrfs: Create ext...
43
  	struct extent_buffer *leaf;
7fcde0e32   Chris Mason   Btrfs: finish off...
44
45
  
  	ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
7e38180e2   Chris Mason   Btrfs: directory ...
46
  	if (ret == -EEXIST) {
e06afa839   Chris Mason   Btrfs: rename
47
48
49
50
  		struct btrfs_dir_item *di;
  		di = btrfs_match_dir_item_name(root, path, name, name_len);
  		if (di)
  			return ERR_PTR(-EEXIST);
7e38180e2   Chris Mason   Btrfs: directory ...
51
  		ret = btrfs_extend_item(trans, root, path, data_size);
7fcde0e32   Chris Mason   Btrfs: finish off...
52
  	}
54aa1f4df   Chris Mason   Btrfs: Audit call...
53
54
  	if (ret < 0)
  		return ERR_PTR(ret);
7e38180e2   Chris Mason   Btrfs: directory ...
55
  	WARN_ON(ret > 0);
5f39d397d   Chris Mason   Btrfs: Create ext...
56
57
  	leaf = path->nodes[0];
  	item = btrfs_item_nr(leaf, path->slots[0]);
7e38180e2   Chris Mason   Btrfs: directory ...
58
  	ptr = btrfs_item_ptr(leaf, path->slots[0], char);
5f39d397d   Chris Mason   Btrfs: Create ext...
59
60
  	BUG_ON(data_size > btrfs_item_size(leaf, item));
  	ptr += btrfs_item_size(leaf, item) - data_size;
7e38180e2   Chris Mason   Btrfs: directory ...
61
  	return (struct btrfs_dir_item *)ptr;
7fcde0e32   Chris Mason   Btrfs: finish off...
62
  }
d352ac681   Chris Mason   Btrfs: add and im...
63
64
65
66
  /*
   * xattrs work a lot like directories, this inserts an xattr item
   * into the tree
   */
5103e947b   Josef Bacik   xattr support for...
67
  int btrfs_insert_xattr_item(struct btrfs_trans_handle *trans,
f34f57a3a   Yan, Zheng   Btrfs: Pass trans...
68
69
70
71
  			    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...
72
73
  {
  	int ret = 0;
5103e947b   Josef Bacik   xattr support for...
74
75
76
77
78
79
  	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;
f34f57a3a   Yan, Zheng   Btrfs: Pass trans...
80
81
82
  	BUG_ON(name_len + data_len > BTRFS_MAX_XATTR_SIZE(root));
  
  	key.objectid = objectid;
5103e947b   Josef Bacik   xattr support for...
83
  	btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
df68b8a7a   David Miller   Btrfs: unaligned ...
84
  	key.offset = btrfs_name_hash(name, name_len);
5103e947b   Josef Bacik   xattr support for...
85
86
87
88
  
  	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...
89
90
  	if (IS_ERR(dir_item))
  		return PTR_ERR(dir_item);
5103e947b   Josef Bacik   xattr support for...
91
92
93
94
95
96
97
  	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...
98
  	btrfs_set_dir_transid(leaf, dir_item, trans->transid);
5103e947b   Josef Bacik   xattr support for...
99
100
101
102
103
104
105
  	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...
106
107
  	return ret;
  }
d352ac681   Chris Mason   Btrfs: add and im...
108
109
110
111
112
113
114
  /*
   * 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).
   */
e089f05c1   Chris Mason   Btrfs: transactio...
115
  int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
16cdcec73   Miao Xie   btrfs: implement ...
116
117
118
  			  *root, const char *name, int name_len,
  			  struct inode *dir, struct btrfs_key *location,
  			  u8 type, u64 index)
62e2749e0   Chris Mason   Btrfs: Use a chun...
119
120
  {
  	int ret = 0;
e06afa839   Chris Mason   Btrfs: rename
121
  	int ret2 = 0;
5caf2a002   Chris Mason   Btrfs: dynamic al...
122
  	struct btrfs_path *path;
62e2749e0   Chris Mason   Btrfs: Use a chun...
123
  	struct btrfs_dir_item *dir_item;
5f39d397d   Chris Mason   Btrfs: Create ext...
124
125
  	struct extent_buffer *leaf;
  	unsigned long name_ptr;
62e2749e0   Chris Mason   Btrfs: Use a chun...
126
  	struct btrfs_key key;
5f39d397d   Chris Mason   Btrfs: Create ext...
127
  	struct btrfs_disk_key disk_key;
62e2749e0   Chris Mason   Btrfs: Use a chun...
128
  	u32 data_size;
0d0ca30f1   Chris Mason   Btrfs: update the...
129
  	key.objectid = btrfs_ino(dir);
1d4f6404d   Chris Mason   Btrfs: directory ...
130
  	btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
df68b8a7a   David Miller   Btrfs: unaligned ...
131
  	key.offset = btrfs_name_hash(name, name_len);
b9473439d   Chris Mason   Btrfs: leave btre...
132

5caf2a002   Chris Mason   Btrfs: dynamic al...
133
  	path = btrfs_alloc_path();
16cdcec73   Miao Xie   btrfs: implement ...
134
135
  	if (!path)
  		return -ENOMEM;
b9473439d   Chris Mason   Btrfs: leave btre...
136
  	path->leave_spinning = 1;
16cdcec73   Miao Xie   btrfs: implement ...
137
  	btrfs_cpu_key_to_disk(&disk_key, location);
62e2749e0   Chris Mason   Btrfs: Use a chun...
138
  	data_size = sizeof(*dir_item) + name_len;
e06afa839   Chris Mason   Btrfs: rename
139
140
  	dir_item = insert_with_overflow(trans, root, path, &key, data_size,
  					name, name_len);
7e38180e2   Chris Mason   Btrfs: directory ...
141
142
  	if (IS_ERR(dir_item)) {
  		ret = PTR_ERR(dir_item);
e06afa839   Chris Mason   Btrfs: rename
143
144
  		if (ret == -EEXIST)
  			goto second_insert;
c2db1073f   Tsutomu Itoh   Btrfs: check retu...
145
  		goto out_free;
7e38180e2   Chris Mason   Btrfs: directory ...
146
  	}
62e2749e0   Chris Mason   Btrfs: Use a chun...
147

5f39d397d   Chris Mason   Btrfs: Create ext...
148
  	leaf = path->nodes[0];
5f39d397d   Chris Mason   Btrfs: Create ext...
149
150
  	btrfs_set_dir_item_key(leaf, dir_item, &disk_key);
  	btrfs_set_dir_type(leaf, dir_item, type);
5103e947b   Josef Bacik   xattr support for...
151
  	btrfs_set_dir_data_len(leaf, dir_item, 0);
5f39d397d   Chris Mason   Btrfs: Create ext...
152
  	btrfs_set_dir_name_len(leaf, dir_item, name_len);
e02119d5a   Chris Mason   Btrfs: Add a writ...
153
  	btrfs_set_dir_transid(leaf, dir_item, trans->transid);
5f39d397d   Chris Mason   Btrfs: Create ext...
154
  	name_ptr = (unsigned long)(dir_item + 1);
c5739bba5   Chris Mason   Btrfs: snapshot p...
155

5f39d397d   Chris Mason   Btrfs: Create ext...
156
157
  	write_extent_buffer(leaf, name, name_ptr, name_len);
  	btrfs_mark_buffer_dirty(leaf);
7e38180e2   Chris Mason   Btrfs: directory ...
158

e06afa839   Chris Mason   Btrfs: rename
159
  second_insert:
7e38180e2   Chris Mason   Btrfs: directory ...
160
161
162
  	/* 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...
163
  		goto out_free;
7e38180e2   Chris Mason   Btrfs: directory ...
164
  	}
b3b4aa74b   David Sterba   btrfs: drop unuse...
165
  	btrfs_release_path(path);
7e38180e2   Chris Mason   Btrfs: directory ...
166

16cdcec73   Miao Xie   btrfs: implement ...
167
168
  	ret2 = btrfs_insert_delayed_dir_index(trans, root, name, name_len, dir,
  					      &disk_key, type, index);
c2db1073f   Tsutomu Itoh   Btrfs: check retu...
169
  out_free:
5caf2a002   Chris Mason   Btrfs: dynamic al...
170
  	btrfs_free_path(path);
e06afa839   Chris Mason   Btrfs: rename
171
172
173
174
175
  	if (ret)
  		return ret;
  	if (ret2)
  		return ret2;
  	return 0;
62e2749e0   Chris Mason   Btrfs: Use a chun...
176
  }
d352ac681   Chris Mason   Btrfs: add and im...
177
178
179
180
181
  /*
   * 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 ...
182
183
184
185
186
  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...
187
  {
1d4f6404d   Chris Mason   Btrfs: directory ...
188
  	int ret;
62e2749e0   Chris Mason   Btrfs: Use a chun...
189
  	struct btrfs_key key;
1d4f6404d   Chris Mason   Btrfs: directory ...
190
191
  	int ins_len = mod < 0 ? -1 : 0;
  	int cow = mod != 0;
62e2749e0   Chris Mason   Btrfs: Use a chun...
192
193
  
  	key.objectid = dir;
1d4f6404d   Chris Mason   Btrfs: directory ...
194
  	btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
5f39d397d   Chris Mason   Btrfs: Create ext...
195

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

7e38180e2   Chris Mason   Btrfs: directory ...
198
199
200
  	ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
  	if (ret < 0)
  		return ERR_PTR(ret);
85d85a743   Li Zefan   Btrfs: remove red...
201
  	if (ret > 0)
7e38180e2   Chris Mason   Btrfs: directory ...
202
203
204
  		return NULL;
  
  	return btrfs_match_dir_item_name(root, path, name, name_len);
62e2749e0   Chris Mason   Btrfs: Use a chun...
205
  }
d352ac681   Chris Mason   Btrfs: add and im...
206
207
208
209
210
211
212
213
  /*
   * 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 ...
214
215
216
217
218
219
220
221
222
223
224
225
226
  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;
7e38180e2   Chris Mason   Btrfs: directory ...
227
228
229
230
231
232
233
234
235
236
  	btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY);
  	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);
  	return btrfs_match_dir_item_name(root, path, name, name_len);
  }
4df27c4d5   Yan, Zheng   Btrfs: change how...
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
  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;
  
  		di = btrfs_match_dir_item_name(root, path, name, name_len);
  		if (di)
  			return di;
  
  		path->slots[0]++;
  	}
  	return NULL;
  }
5103e947b   Josef Bacik   xattr support for...
283
284
285
286
287
288
289
290
291
292
  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...
293
294
295
  
  	key.objectid = dir;
  	btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY);
df68b8a7a   David Miller   Btrfs: unaligned ...
296
  	key.offset = btrfs_name_hash(name, name_len);
5103e947b   Josef Bacik   xattr support for...
297
298
299
  	ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
  	if (ret < 0)
  		return ERR_PTR(ret);
85d85a743   Li Zefan   Btrfs: remove red...
300
  	if (ret > 0)
5103e947b   Josef Bacik   xattr support for...
301
302
303
304
  		return NULL;
  
  	return btrfs_match_dir_item_name(root, path, name, name_len);
  }
d352ac681   Chris Mason   Btrfs: add and im...
305
306
307
308
309
  /*
   * 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.
   */
7e38180e2   Chris Mason   Btrfs: directory ...
310
  struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
7f5c15160   Chris Mason   Add generation nu...
311
312
  			      struct btrfs_path *path,
  			      const char *name, int name_len)
62e2749e0   Chris Mason   Btrfs: Use a chun...
313
  {
62e2749e0   Chris Mason   Btrfs: Use a chun...
314
  	struct btrfs_dir_item *dir_item;
5f39d397d   Chris Mason   Btrfs: Create ext...
315
  	unsigned long name_ptr;
7e38180e2   Chris Mason   Btrfs: directory ...
316
317
318
  	u32 total_len;
  	u32 cur = 0;
  	u32 this_len;
5f39d397d   Chris Mason   Btrfs: Create ext...
319
  	struct extent_buffer *leaf;
a8a2ee0c6   Chris Mason   Btrfs: add a name...
320

5f39d397d   Chris Mason   Btrfs: Create ext...
321
  	leaf = path->nodes[0];
7e38180e2   Chris Mason   Btrfs: directory ...
322
  	dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item);
22a94d44b   Josef Bacik   Btrfs: add checks...
323
324
  	if (verify_dir_item(root, leaf, dir_item))
  		return NULL;
5f39d397d   Chris Mason   Btrfs: Create ext...
325
  	total_len = btrfs_item_size_nr(leaf, path->slots[0]);
d397712bc   Chris Mason   Btrfs: Fix checkp...
326
  	while (cur < total_len) {
5f39d397d   Chris Mason   Btrfs: Create ext...
327
  		this_len = sizeof(*dir_item) +
5103e947b   Josef Bacik   xattr support for...
328
329
  			btrfs_dir_name_len(leaf, dir_item) +
  			btrfs_dir_data_len(leaf, dir_item);
5f39d397d   Chris Mason   Btrfs: Create ext...
330
  		name_ptr = (unsigned long)(dir_item + 1);
7e38180e2   Chris Mason   Btrfs: directory ...
331

5f39d397d   Chris Mason   Btrfs: Create ext...
332
333
  		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 ...
334
335
336
337
338
339
340
  			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...
341
  }
7e38180e2   Chris Mason   Btrfs: directory ...
342

d352ac681   Chris Mason   Btrfs: add and im...
343
344
345
346
  /*
   * 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 ...
347
348
349
350
351
  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...
352
  	struct extent_buffer *leaf;
7e38180e2   Chris Mason   Btrfs: directory ...
353
354
  	u32 sub_item_len;
  	u32 item_len;
54aa1f4df   Chris Mason   Btrfs: Audit call...
355
  	int ret = 0;
7e38180e2   Chris Mason   Btrfs: directory ...
356

5f39d397d   Chris Mason   Btrfs: Create ext...
357
  	leaf = path->nodes[0];
5103e947b   Josef Bacik   xattr support for...
358
359
  	sub_item_len = sizeof(*di) + btrfs_dir_name_len(leaf, di) +
  		btrfs_dir_data_len(leaf, di);
5f39d397d   Chris Mason   Btrfs: Create ext...
360
361
  	item_len = btrfs_item_size_nr(leaf, path->slots[0]);
  	if (sub_item_len == item_len) {
7e38180e2   Chris Mason   Btrfs: directory ...
362
  		ret = btrfs_del_item(trans, root, path);
7e38180e2   Chris Mason   Btrfs: directory ...
363
  	} else {
5f39d397d   Chris Mason   Btrfs: Create ext...
364
365
366
367
368
369
  		/* 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 ...
370
371
  			item_len - (ptr + sub_item_len - start));
  		ret = btrfs_truncate_item(trans, root, path,
179e29e48   Chris Mason   Btrfs: Fix a numb...
372
  					  item_len - sub_item_len, 1);
7e38180e2   Chris Mason   Btrfs: directory ...
373
  	}
411fc6bce   Andi Kleen   Btrfs: Fix variab...
374
  	return ret;
7e38180e2   Chris Mason   Btrfs: directory ...
375
  }
22a94d44b   Josef Bacik   Btrfs: add checks...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
  
  int verify_dir_item(struct btrfs_root *root,
  		    struct extent_buffer *leaf,
  		    struct btrfs_dir_item *dir_item)
  {
  	u16 namelen = BTRFS_NAME_LEN;
  	u8 type = btrfs_dir_type(leaf, dir_item);
  
  	if (type >= BTRFS_FT_MAX) {
  		printk(KERN_CRIT "btrfs: invalid dir item type: %d
  ",
  		       (int)type);
  		return 1;
  	}
  
  	if (type == BTRFS_FT_XATTR)
  		namelen = XATTR_NAME_MAX;
  
  	if (btrfs_dir_name_len(leaf, dir_item) > namelen) {
9694b3fcb   Sergei Trofimovich   btrfs: typo: 'btr...
395
396
  		printk(KERN_CRIT "btrfs: invalid dir item name len: %u
  ",
22a94d44b   Josef Bacik   Btrfs: add checks...
397
398
399
400
401
402
403
404
405
406
407
408
409
410
  		       (unsigned)btrfs_dir_data_len(leaf, dir_item));
  		return 1;
  	}
  
  	/* BTRFS_MAX_XATTR_SIZE is the same for all dir items */
  	if (btrfs_dir_data_len(leaf, dir_item) > BTRFS_MAX_XATTR_SIZE(root)) {
  		printk(KERN_CRIT "btrfs: invalid dir item data len: %u
  ",
  		       (unsigned)btrfs_dir_data_len(leaf, dir_item));
  		return 1;
  	}
  
  	return 0;
  }