Blame view

fs/ext4/namei.c 65.5 KB
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1
  /*
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2
   *  linux/fs/ext4/namei.c
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
   *
   * Copyright (C) 1992, 1993, 1994, 1995
   * Remy Card (card@masi.ibp.fr)
   * Laboratoire MASI - Institut Blaise Pascal
   * Universite Pierre et Marie Curie (Paris VI)
   *
   *  from
   *
   *  linux/fs/minix/namei.c
   *
   *  Copyright (C) 1991, 1992  Linus Torvalds
   *
   *  Big-endian to little-endian byte-swapping/bitmaps by
   *        David S. Miller (davem@caip.rutgers.edu), 1995
   *  Directory entry file type support and forward compatibility hooks
   *	for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
   *  Hash Tree Directory indexing (c)
   *	Daniel Phillips, 2001
   *  Hash Tree Directory indexing porting
   *	Christopher Li, 2002
   *  Hash Tree Directory indexing cleanup
   *	Theodore Ts'o, 2002
   */
  
  #include <linux/fs.h>
  #include <linux/pagemap.h>
dab291af8   Mingming Cao   [PATCH] jbd2: ena...
29
  #include <linux/jbd2.h>
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
30
  #include <linux/time.h>
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
31
  #include <linux/ext4_fs.h>
dab291af8   Mingming Cao   [PATCH] jbd2: ena...
32
  #include <linux/ext4_jbd2.h>
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
33
34
35
36
37
38
  #include <linux/fcntl.h>
  #include <linux/stat.h>
  #include <linux/string.h>
  #include <linux/quotaops.h>
  #include <linux/buffer_head.h>
  #include <linux/bio.h>
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
39
40
41
42
43
44
45
46
47
48
  
  #include "namei.h"
  #include "xattr.h"
  #include "acl.h"
  
  /*
   * define how far ahead to read directories while searching them.
   */
  #define NAMEI_RA_CHUNKS  2
  #define NAMEI_RA_BLOCKS  4
8c55e2041   Dave Kleikamp   EXT4: Fix whitespace
49
  #define NAMEI_RA_SIZE	     (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
50
  #define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
51
  static struct buffer_head *ext4_append(handle_t *handle,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
52
53
54
55
56
57
  					struct inode *inode,
  					u32 *block, int *err)
  {
  	struct buffer_head *bh;
  
  	*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
58
  	if ((bh = ext4_bread(handle, inode, *block, 1, err))) {
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
59
  		inode->i_size += inode->i_sb->s_blocksize;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
60
61
  		EXT4_I(inode)->i_disksize = inode->i_size;
  		ext4_journal_get_write_access(handle,bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
  	}
  	return bh;
  }
  
  #ifndef assert
  #define assert(test) J_ASSERT(test)
  #endif
  
  #ifndef swap
  #define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0)
  #endif
  
  #ifdef DX_DEBUG
  #define dxtrace(command) command
  #else
  #define dxtrace(command)
  #endif
  
  struct fake_dirent
  {
  	__le32 inode;
  	__le16 rec_len;
  	u8 name_len;
  	u8 file_type;
  };
  
  struct dx_countlimit
  {
  	__le16 limit;
  	__le16 count;
  };
  
  struct dx_entry
  {
  	__le32 hash;
  	__le32 block;
  };
  
  /*
   * dx_root_info is laid out so that if it should somehow get overlaid by a
   * dirent the two low bits of the hash version will be zero.  Therefore, the
   * hash version mod 4 should never be 0.  Sincerely, the paranoia department.
   */
  
  struct dx_root
  {
  	struct fake_dirent dot;
  	char dot_name[4];
  	struct fake_dirent dotdot;
  	char dotdot_name[4];
  	struct dx_root_info
  	{
  		__le32 reserved_zero;
  		u8 hash_version;
  		u8 info_length; /* 8 */
  		u8 indirect_levels;
  		u8 unused_flags;
  	}
  	info;
  	struct dx_entry	entries[0];
  };
  
  struct dx_node
  {
  	struct fake_dirent fake;
  	struct dx_entry	entries[0];
  };
  
  
  struct dx_frame
  {
  	struct buffer_head *bh;
  	struct dx_entry *entries;
  	struct dx_entry *at;
  };
  
  struct dx_map_entry
  {
  	u32 hash;
  	u32 offs;
  };
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
143
  #ifdef CONFIG_EXT4_INDEX
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
  static inline unsigned dx_get_block (struct dx_entry *entry);
  static void dx_set_block (struct dx_entry *entry, unsigned value);
  static inline unsigned dx_get_hash (struct dx_entry *entry);
  static void dx_set_hash (struct dx_entry *entry, unsigned value);
  static unsigned dx_get_count (struct dx_entry *entries);
  static unsigned dx_get_limit (struct dx_entry *entries);
  static void dx_set_count (struct dx_entry *entries, unsigned value);
  static void dx_set_limit (struct dx_entry *entries, unsigned value);
  static unsigned dx_root_limit (struct inode *dir, unsigned infosize);
  static unsigned dx_node_limit (struct inode *dir);
  static struct dx_frame *dx_probe(struct dentry *dentry,
  				 struct inode *dir,
  				 struct dx_hash_info *hinfo,
  				 struct dx_frame *frame,
  				 int *err);
  static void dx_release (struct dx_frame *frames);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
160
  static int dx_make_map (struct ext4_dir_entry_2 *de, int size,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
161
162
  			struct dx_hash_info *hinfo, struct dx_map_entry map[]);
  static void dx_sort_map(struct dx_map_entry *map, unsigned count);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
163
  static struct ext4_dir_entry_2 *dx_move_dirents (char *from, char *to,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
164
  		struct dx_map_entry *offsets, int count);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
165
  static struct ext4_dir_entry_2* dx_pack_dirents (char *base, int size);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
166
  static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
167
  static int ext4_htree_next_block(struct inode *dir, __u32 hash,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
168
169
170
  				 struct dx_frame *frame,
  				 struct dx_frame *frames,
  				 __u32 *start_hash);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
171
172
173
  static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
  		       struct ext4_dir_entry_2 **res_dir, int *err);
  static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  			     struct inode *inode);
  
  /*
   * Future: use high four bits of block for coalesce-on-delete flags
   * Mask them off for now.
   */
  
  static inline unsigned dx_get_block (struct dx_entry *entry)
  {
  	return le32_to_cpu(entry->block) & 0x00ffffff;
  }
  
  static inline void dx_set_block (struct dx_entry *entry, unsigned value)
  {
  	entry->block = cpu_to_le32(value);
  }
  
  static inline unsigned dx_get_hash (struct dx_entry *entry)
  {
  	return le32_to_cpu(entry->hash);
  }
  
  static inline void dx_set_hash (struct dx_entry *entry, unsigned value)
  {
  	entry->hash = cpu_to_le32(value);
  }
  
  static inline unsigned dx_get_count (struct dx_entry *entries)
  {
  	return le16_to_cpu(((struct dx_countlimit *) entries)->count);
  }
  
  static inline unsigned dx_get_limit (struct dx_entry *entries)
  {
  	return le16_to_cpu(((struct dx_countlimit *) entries)->limit);
  }
  
  static inline void dx_set_count (struct dx_entry *entries, unsigned value)
  {
  	((struct dx_countlimit *) entries)->count = cpu_to_le16(value);
  }
  
  static inline void dx_set_limit (struct dx_entry *entries, unsigned value)
  {
  	((struct dx_countlimit *) entries)->limit = cpu_to_le16(value);
  }
  
  static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize)
  {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
223
224
  	unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(1) -
  		EXT4_DIR_REC_LEN(2) - infosize;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
225
226
227
228
229
  	return 0? 20: entry_space / sizeof(struct dx_entry);
  }
  
  static inline unsigned dx_node_limit (struct inode *dir)
  {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
230
  	unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
231
232
233
234
235
236
237
238
239
  	return 0? 22: entry_space / sizeof(struct dx_entry);
  }
  
  /*
   * Debug
   */
  #ifdef DX_DEBUG
  static void dx_show_index (char * label, struct dx_entry *entries)
  {
63f579335   Andrew Morton   [PATCH] ext4 whit...
240
  	int i, n = dx_get_count (entries);
8c55e2041   Dave Kleikamp   EXT4: Fix whitespace
241
  	printk("%s index ", label);
63f579335   Andrew Morton   [PATCH] ext4 whit...
242
243
244
245
246
247
  	for (i = 0; i < n; i++) {
  		printk("%x->%u ", i? dx_get_hash(entries + i) :
  				0, dx_get_block(entries + i));
  	}
  	printk("
  ");
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
248
249
250
251
252
253
254
255
  }
  
  struct stats
  {
  	unsigned names;
  	unsigned space;
  	unsigned bcount;
  };
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
256
  static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext4_dir_entry_2 *de,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
  				 int size, int show_names)
  {
  	unsigned names = 0, space = 0;
  	char *base = (char *) de;
  	struct dx_hash_info h = *hinfo;
  
  	printk("names: ");
  	while ((char *) de < base + size)
  	{
  		if (de->inode)
  		{
  			if (show_names)
  			{
  				int len = de->name_len;
  				char *name = de->name;
  				while (len--) printk("%c", *name++);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
273
  				ext4fs_dirhash(de->name, de->name_len, &h);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
274
275
276
  				printk(":%x.%u ", h.hash,
  				       ((char *) de - base));
  			}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
277
  			space += EXT4_DIR_REC_LEN(de->name_len);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
278
279
  			names++;
  		}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
280
  		de = (struct ext4_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
  	}
  	printk("(%i)
  ", names);
  	return (struct stats) { names, space, 1 };
  }
  
  struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
  			     struct dx_entry *entries, int levels)
  {
  	unsigned blocksize = dir->i_sb->s_blocksize;
  	unsigned count = dx_get_count (entries), names = 0, space = 0, i;
  	unsigned bcount = 0;
  	struct buffer_head *bh;
  	int err;
  	printk("%i indexed blocks...
  ", count);
  	for (i = 0; i < count; i++, entries++)
  	{
  		u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0;
  		u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash;
  		struct stats stats;
  		printk("%s%3u:%03u hash %8x/%8x ",levels?"":"   ", i, block, hash, range);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
303
  		if (!(bh = ext4_bread (NULL,dir, block, 0,&err))) continue;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
304
305
  		stats = levels?
  		   dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
306
  		   dx_show_leaf(hinfo, (struct ext4_dir_entry_2 *) bh->b_data, blocksize, 0);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
  		names += stats.names;
  		space += stats.space;
  		bcount += stats.bcount;
  		brelse (bh);
  	}
  	if (bcount)
  		printk("%snames %u, fullness %u (%u%%)
  ", levels?"":"   ",
  			names, space/bcount,(space/bcount)*100/blocksize);
  	return (struct stats) { names, space, bcount};
  }
  #endif /* DX_DEBUG */
  
  /*
   * Probe for a directory leaf block to search.
   *
   * dx_probe can return ERR_BAD_DX_DIR, which means there was a format
   * error in the directory index, and the caller should fall back to
   * searching the directory normally.  The callers of dx_probe **MUST**
   * check for this error code, and make sure it never gets reflected
   * back to userspace.
   */
  static struct dx_frame *
  dx_probe(struct dentry *dentry, struct inode *dir,
  	 struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
  {
  	unsigned count, indirect;
  	struct dx_entry *at, *entries, *p, *q, *m;
  	struct dx_root *root;
  	struct buffer_head *bh;
  	struct dx_frame *frame = frame_in;
  	u32 hash;
  
  	frame->bh = NULL;
  	if (dentry)
  		dir = dentry->d_parent->d_inode;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
343
  	if (!(bh = ext4_bread (NULL,dir, 0, 0, err)))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
344
345
346
347
348
  		goto fail;
  	root = (struct dx_root *) bh->b_data;
  	if (root->info.hash_version != DX_HASH_TEA &&
  	    root->info.hash_version != DX_HASH_HALF_MD4 &&
  	    root->info.hash_version != DX_HASH_LEGACY) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
349
  		ext4_warning(dir->i_sb, __FUNCTION__,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
350
351
352
353
354
355
356
  			     "Unrecognised inode hash code %d",
  			     root->info.hash_version);
  		brelse(bh);
  		*err = ERR_BAD_DX_DIR;
  		goto fail;
  	}
  	hinfo->hash_version = root->info.hash_version;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
357
  	hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
358
  	if (dentry)
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
359
  		ext4fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
360
361
362
  	hash = hinfo->hash;
  
  	if (root->info.unused_flags & 1) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
363
  		ext4_warning(dir->i_sb, __FUNCTION__,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
364
365
366
367
368
369
370
371
  			     "Unimplemented inode hash flags: %#06x",
  			     root->info.unused_flags);
  		brelse(bh);
  		*err = ERR_BAD_DX_DIR;
  		goto fail;
  	}
  
  	if ((indirect = root->info.indirect_levels) > 1) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
372
  		ext4_warning(dir->i_sb, __FUNCTION__,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
  			     "Unimplemented inode hash depth: %#06x",
  			     root->info.indirect_levels);
  		brelse(bh);
  		*err = ERR_BAD_DX_DIR;
  		goto fail;
  	}
  
  	entries = (struct dx_entry *) (((char *)&root->info) +
  				       root->info.info_length);
  	assert(dx_get_limit(entries) == dx_root_limit(dir,
  						      root->info.info_length));
  	dxtrace (printk("Look up %x", hash));
  	while (1)
  	{
  		count = dx_get_count(entries);
  		assert (count && count <= dx_get_limit(entries));
  		p = entries + 1;
  		q = entries + count - 1;
  		while (p <= q)
  		{
  			m = p + (q - p)/2;
  			dxtrace(printk("."));
  			if (dx_get_hash(m) > hash)
  				q = m - 1;
  			else
  				p = m + 1;
  		}
  
  		if (0) // linear search cross check
  		{
  			unsigned n = count - 1;
  			at = entries;
  			while (n--)
  			{
  				dxtrace(printk(","));
  				if (dx_get_hash(++at) > hash)
  				{
  					at--;
  					break;
  				}
  			}
  			assert (at == p - 1);
  		}
  
  		at = p - 1;
  		dxtrace(printk(" %x->%u
  ", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
  		frame->bh = bh;
  		frame->entries = entries;
  		frame->at = at;
  		if (!indirect--) return frame;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
424
  		if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err)))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
  			goto fail2;
  		at = entries = ((struct dx_node *) bh->b_data)->entries;
  		assert (dx_get_limit(entries) == dx_node_limit (dir));
  		frame++;
  	}
  fail2:
  	while (frame >= frame_in) {
  		brelse(frame->bh);
  		frame--;
  	}
  fail:
  	return NULL;
  }
  
  static void dx_release (struct dx_frame *frames)
  {
  	if (frames[0].bh == NULL)
  		return;
  
  	if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels)
  		brelse(frames[1].bh);
  	brelse(frames[0].bh);
  }
  
  /*
   * This function increments the frame pointer to search the next leaf
   * block, and reads in the necessary intervening nodes if the search
   * should be necessary.  Whether or not the search is necessary is
   * controlled by the hash parameter.  If the hash value is even, then
   * the search is only continued if the next block starts with that
   * hash value.  This is used if we are searching for a specific file.
   *
   * If the hash value is HASH_NB_ALWAYS, then always go to the next block.
   *
   * This function returns 1 if the caller should continue to search,
   * or 0 if it should not.  If there is an error reading one of the
   * index blocks, it will a negative error code.
   *
   * If start_hash is non-null, it will be filled in with the starting
   * hash of the next page.
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
466
  static int ext4_htree_next_block(struct inode *dir, __u32 hash,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
  				 struct dx_frame *frame,
  				 struct dx_frame *frames,
  				 __u32 *start_hash)
  {
  	struct dx_frame *p;
  	struct buffer_head *bh;
  	int err, num_frames = 0;
  	__u32 bhash;
  
  	p = frame;
  	/*
  	 * Find the next leaf page by incrementing the frame pointer.
  	 * If we run out of entries in the interior node, loop around and
  	 * increment pointer in the parent node.  When we break out of
  	 * this loop, num_frames indicates the number of interior
  	 * nodes need to be read.
  	 */
  	while (1) {
  		if (++(p->at) < p->entries + dx_get_count(p->entries))
  			break;
  		if (p == frames)
  			return 0;
  		num_frames++;
  		p--;
  	}
  
  	/*
  	 * If the hash is 1, then continue only if the next page has a
  	 * continuation hash of any value.  This is used for readdir
  	 * handling.  Otherwise, check to see if the hash matches the
  	 * desired contiuation hash.  If it doesn't, return since
  	 * there's no point to read in the successive index pages.
  	 */
  	bhash = dx_get_hash(p->at);
  	if (start_hash)
  		*start_hash = bhash;
  	if ((hash & 1) == 0) {
  		if ((bhash & ~1) != hash)
  			return 0;
  	}
  	/*
  	 * If the hash is HASH_NB_ALWAYS, we always go to the next
  	 * block so no check is necessary
  	 */
  	while (num_frames--) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
512
  		if (!(bh = ext4_bread(NULL, dir, dx_get_block(p->at),
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
  				      0, &err)))
  			return err; /* Failure */
  		p++;
  		brelse (p->bh);
  		p->bh = bh;
  		p->at = p->entries = ((struct dx_node *) bh->b_data)->entries;
  	}
  	return 1;
  }
  
  
  /*
   * p is at least 6 bytes before the end of page
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
527
  static inline struct ext4_dir_entry_2 *ext4_next_entry(struct ext4_dir_entry_2 *p)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
528
  {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
529
  	return (struct ext4_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
530
531
532
533
534
535
536
537
538
539
540
541
542
  }
  
  /*
   * This function fills a red-black tree with information from a
   * directory block.  It returns the number directory entries loaded
   * into the tree.  If there is an error it is returned in err.
   */
  static int htree_dirblock_to_tree(struct file *dir_file,
  				  struct inode *dir, int block,
  				  struct dx_hash_info *hinfo,
  				  __u32 start_hash, __u32 start_minor_hash)
  {
  	struct buffer_head *bh;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
543
  	struct ext4_dir_entry_2 *de, *top;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
544
545
546
547
  	int err, count = 0;
  
  	dxtrace(printk("In htree dirblock_to_tree: block %d
  ", block));
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
548
  	if (!(bh = ext4_bread (NULL, dir, block, 0, &err)))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
549
  		return err;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
550
551
  	de = (struct ext4_dir_entry_2 *) bh->b_data;
  	top = (struct ext4_dir_entry_2 *) ((char *) de +
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
552
  					   dir->i_sb->s_blocksize -
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
553
554
  					   EXT4_DIR_REC_LEN(0));
  	for (; de < top; de = ext4_next_entry(de)) {
e6c402119   Eric Sandeen   [PATCH] handle ex...
555
556
557
558
559
560
561
562
563
  		if (!ext4_check_dir_entry("htree_dirblock_to_tree", dir, de, bh,
  					(block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb))
  						+((char *)de - bh->b_data))) {
  			/* On error, skip the f_pos to the next block. */
  			dir_file->f_pos = (dir_file->f_pos |
  					(dir->i_sb->s_blocksize - 1)) + 1;
  			brelse (bh);
  			return count;
  		}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
564
  		ext4fs_dirhash(de->name, de->name_len, hinfo);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
565
566
567
568
569
570
  		if ((hinfo->hash < start_hash) ||
  		    ((hinfo->hash == start_hash) &&
  		     (hinfo->minor_hash < start_minor_hash)))
  			continue;
  		if (de->inode == 0)
  			continue;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
571
  		if ((err = ext4_htree_store_dirent(dir_file,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
  				   hinfo->hash, hinfo->minor_hash, de)) != 0) {
  			brelse(bh);
  			return err;
  		}
  		count++;
  	}
  	brelse(bh);
  	return count;
  }
  
  
  /*
   * This function fills a red-black tree with information from a
   * directory.  We start scanning the directory in hash order, starting
   * at start_hash and start_minor_hash.
   *
   * This function returns the number of entries inserted into the tree,
   * or a negative error code.
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
591
  int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
592
593
594
  			 __u32 start_minor_hash, __u32 *next_hash)
  {
  	struct dx_hash_info hinfo;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
595
  	struct ext4_dir_entry_2 *de;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
596
597
598
599
600
601
602
603
604
605
  	struct dx_frame frames[2], *frame;
  	struct inode *dir;
  	int block, err;
  	int count = 0;
  	int ret;
  	__u32 hashval;
  
  	dxtrace(printk("In htree_fill_tree, start hash: %x:%x
  ", start_hash,
  		       start_minor_hash));
9d549890e   Josef "Jeff" Sipek   [PATCH] ext4: cha...
606
  	dir = dir_file->f_path.dentry->d_inode;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
607
608
609
  	if (!(EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) {
  		hinfo.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
  		hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
610
611
612
613
614
615
616
  		count = htree_dirblock_to_tree(dir_file, dir, 0, &hinfo,
  					       start_hash, start_minor_hash);
  		*next_hash = ~0;
  		return count;
  	}
  	hinfo.hash = start_hash;
  	hinfo.minor_hash = 0;
9d549890e   Josef "Jeff" Sipek   [PATCH] ext4: cha...
617
  	frame = dx_probe(NULL, dir_file->f_path.dentry->d_inode, &hinfo, frames, &err);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
618
619
620
621
622
  	if (!frame)
  		return err;
  
  	/* Add '.' and '..' from the htree header */
  	if (!start_hash && !start_minor_hash) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
623
624
  		de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data;
  		if ((err = ext4_htree_store_dirent(dir_file, 0, 0, de)) != 0)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
625
626
627
628
  			goto errout;
  		count++;
  	}
  	if (start_hash < 2 || (start_hash ==2 && start_minor_hash==0)) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
629
630
631
  		de = (struct ext4_dir_entry_2 *) frames[0].bh->b_data;
  		de = ext4_next_entry(de);
  		if ((err = ext4_htree_store_dirent(dir_file, 2, 0, de)) != 0)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
632
633
634
635
636
637
638
639
640
641
642
643
644
645
  			goto errout;
  		count++;
  	}
  
  	while (1) {
  		block = dx_get_block(frame->at);
  		ret = htree_dirblock_to_tree(dir_file, dir, block, &hinfo,
  					     start_hash, start_minor_hash);
  		if (ret < 0) {
  			err = ret;
  			goto errout;
  		}
  		count += ret;
  		hashval = ~0;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
646
  		ret = ext4_htree_next_block(dir, HASH_NB_ALWAYS,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
  					    frame, frames, &hashval);
  		*next_hash = hashval;
  		if (ret < 0) {
  			err = ret;
  			goto errout;
  		}
  		/*
  		 * Stop if:  (a) there are no more entries, or
  		 * (b) we have inserted at least one entry and the
  		 * next hash value is not a continuation
  		 */
  		if ((ret == 0) ||
  		    (count && ((hashval & 1) == 0)))
  			break;
  	}
  	dx_release(frames);
  	dxtrace(printk("Fill tree: returned %d entries, next hash: %x
  ",
  		       count, *next_hash));
  	return count;
  errout:
  	dx_release(frames);
  	return (err);
  }
  
  
  /*
   * Directory block splitting, compacting
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
676
  static int dx_make_map (struct ext4_dir_entry_2 *de, int size,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
677
678
679
680
681
682
683
684
685
  			struct dx_hash_info *hinfo, struct dx_map_entry *map_tail)
  {
  	int count = 0;
  	char *base = (char *) de;
  	struct dx_hash_info h = *hinfo;
  
  	while ((char *) de < base + size)
  	{
  		if (de->name_len && de->inode) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
686
  			ext4fs_dirhash(de->name, de->name_len, &h);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
687
688
689
690
691
692
693
  			map_tail--;
  			map_tail->hash = h.hash;
  			map_tail->offs = (u32) ((char *) de - base);
  			count++;
  			cond_resched();
  		}
  		/* XXX: do we need to check rec_len == 0 case? -Chris */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
694
  		de = (struct ext4_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
695
696
697
698
699
700
  	}
  	return count;
  }
  
  static void dx_sort_map (struct dx_map_entry *map, unsigned count)
  {
63f579335   Andrew Morton   [PATCH] ext4 whit...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
  	struct dx_map_entry *p, *q, *top = map + count - 1;
  	int more;
  	/* Combsort until bubble sort doesn't suck */
  	while (count > 2) {
  		count = count*10/13;
  		if (count - 9 < 2) /* 9, 10 -> 11 */
  			count = 11;
  		for (p = top, q = p - count; q >= map; p--, q--)
  			if (p->hash < q->hash)
  				swap(*p, *q);
  	}
  	/* Garden variety bubble sort */
  	do {
  		more = 0;
  		q = top;
  		while (q-- > map) {
  			if (q[1].hash >= q[0].hash)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
718
  				continue;
63f579335   Andrew Morton   [PATCH] ext4 whit...
719
720
  			swap(*(q+1), *q);
  			more = 1;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
  		}
  	} while(more);
  }
  
  static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block)
  {
  	struct dx_entry *entries = frame->entries;
  	struct dx_entry *old = frame->at, *new = old + 1;
  	int count = dx_get_count(entries);
  
  	assert(count < dx_get_limit(entries));
  	assert(old < entries + count);
  	memmove(new + 1, new, (char *)(entries + count) - (char *)(new));
  	dx_set_hash(new, hash);
  	dx_set_block(new, block);
  	dx_set_count(entries, count + 1);
  }
  #endif
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
739
  static void ext4_update_dx_flag(struct inode *inode)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
740
  {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
741
742
743
  	if (!EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
  				     EXT4_FEATURE_COMPAT_DIR_INDEX))
  		EXT4_I(inode)->i_flags &= ~EXT4_INDEX_FL;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
744
745
746
  }
  
  /*
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
747
   * NOTE! unlike strncmp, ext4_match returns 1 for success, 0 for failure.
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
748
   *
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
749
   * `len <= EXT4_NAME_LEN' is guaranteed by caller.
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
750
751
   * `de != NULL' is guaranteed by caller.
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
752
753
  static inline int ext4_match (int len, const char * const name,
  			      struct ext4_dir_entry_2 * de)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
  {
  	if (len != de->name_len)
  		return 0;
  	if (!de->inode)
  		return 0;
  	return !memcmp(name, de->name, len);
  }
  
  /*
   * Returns 0 if not found, -1 on failure, and 1 on success
   */
  static inline int search_dirblock(struct buffer_head * bh,
  				  struct inode *dir,
  				  struct dentry *dentry,
  				  unsigned long offset,
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
769
  				  struct ext4_dir_entry_2 ** res_dir)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
770
  {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
771
  	struct ext4_dir_entry_2 * de;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
772
773
774
775
  	char * dlimit;
  	int de_len;
  	const char *name = dentry->d_name.name;
  	int namelen = dentry->d_name.len;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
776
  	de = (struct ext4_dir_entry_2 *) bh->b_data;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
777
778
779
780
781
782
  	dlimit = bh->b_data + dir->i_sb->s_blocksize;
  	while ((char *) de < dlimit) {
  		/* this code is executed quadratically often */
  		/* do minimal checking `by hand' */
  
  		if ((char *) de + namelen <= dlimit &&
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
783
  		    ext4_match (namelen, name, de)) {
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
784
  			/* found a match - just to be sure, do a full check */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
785
  			if (!ext4_check_dir_entry("ext4_find_entry",
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
786
787
788
789
790
791
792
793
794
795
  						  dir, de, bh, offset))
  				return -1;
  			*res_dir = de;
  			return 1;
  		}
  		/* prevent looping on a bad block */
  		de_len = le16_to_cpu(de->rec_len);
  		if (de_len <= 0)
  			return -1;
  		offset += de_len;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
796
  		de = (struct ext4_dir_entry_2 *) ((char *) de + de_len);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
797
798
799
800
801
802
  	}
  	return 0;
  }
  
  
  /*
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
803
   *	ext4_find_entry()
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
804
805
806
807
808
809
810
811
812
   *
   * finds an entry in the specified directory with the wanted name. It
   * returns the cache buffer in which the entry was found, and the entry
   * itself (as a parameter - res_dir). It does NOT read the inode of the
   * entry - you'll have to do that yourself if you want to.
   *
   * The returned buffer_head has ->b_count elevated.  The caller is expected
   * to brelse() it when appropriate.
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
813
814
  static struct buffer_head * ext4_find_entry (struct dentry *dentry,
  					struct ext4_dir_entry_2 ** res_dir)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
  {
  	struct super_block * sb;
  	struct buffer_head * bh_use[NAMEI_RA_SIZE];
  	struct buffer_head * bh, *ret = NULL;
  	unsigned long start, block, b;
  	int ra_max = 0;		/* Number of bh's in the readahead
  				   buffer, bh_use[] */
  	int ra_ptr = 0;		/* Current index into readahead
  				   buffer */
  	int num = 0;
  	int nblocks, i, err;
  	struct inode *dir = dentry->d_parent->d_inode;
  	int namelen;
  	const u8 *name;
  	unsigned blocksize;
  
  	*res_dir = NULL;
  	sb = dir->i_sb;
  	blocksize = sb->s_blocksize;
  	namelen = dentry->d_name.len;
  	name = dentry->d_name.name;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
836
  	if (namelen > EXT4_NAME_LEN)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
837
  		return NULL;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
838
  #ifdef CONFIG_EXT4_INDEX
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
839
  	if (is_dx(dir)) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
840
  		bh = ext4_dx_find_entry(dentry, res_dir, &err);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
841
842
843
844
845
846
847
  		/*
  		 * On success, or if the error was file not found,
  		 * return.  Otherwise, fall back to doing a search the
  		 * old fashioned way.
  		 */
  		if (bh || (err != ERR_BAD_DX_DIR))
  			return bh;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
848
849
  		dxtrace(printk("ext4_find_entry: dx failed, falling back
  "));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
850
851
  	}
  #endif
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
852
853
  	nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb);
  	start = EXT4_I(dir)->i_dir_start_lookup;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
  	if (start >= nblocks)
  		start = 0;
  	block = start;
  restart:
  	do {
  		/*
  		 * We deal with the read-ahead logic here.
  		 */
  		if (ra_ptr >= ra_max) {
  			/* Refill the readahead buffer */
  			ra_ptr = 0;
  			b = block;
  			for (ra_max = 0; ra_max < NAMEI_RA_SIZE; ra_max++) {
  				/*
  				 * Terminate if we reach the end of the
  				 * directory and must wrap, or if our
  				 * search has finished at this block.
  				 */
  				if (b >= nblocks || (num && block == start)) {
  					bh_use[ra_max] = NULL;
  					break;
  				}
  				num++;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
877
  				bh = ext4_getblk(NULL, dir, b++, 0, &err);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
878
879
880
881
882
883
884
885
886
887
  				bh_use[ra_max] = bh;
  				if (bh)
  					ll_rw_block(READ_META, 1, &bh);
  			}
  		}
  		if ((bh = bh_use[ra_ptr++]) == NULL)
  			goto next;
  		wait_on_buffer(bh);
  		if (!buffer_uptodate(bh)) {
  			/* read error, skip block & hope for the best */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
888
  			ext4_error(sb, __FUNCTION__, "reading directory #%lu "
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
889
890
891
892
893
  				   "offset %lu", dir->i_ino, block);
  			brelse(bh);
  			goto next;
  		}
  		i = search_dirblock(bh, dir, dentry,
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
894
  			    block << EXT4_BLOCK_SIZE_BITS(sb), res_dir);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
895
  		if (i == 1) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
896
  			EXT4_I(dir)->i_dir_start_lookup = block;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
  			ret = bh;
  			goto cleanup_and_exit;
  		} else {
  			brelse(bh);
  			if (i < 0)
  				goto cleanup_and_exit;
  		}
  	next:
  		if (++block >= nblocks)
  			block = 0;
  	} while (block != start);
  
  	/*
  	 * If the directory has grown while we were searching, then
  	 * search the last part of the directory before giving up.
  	 */
  	block = nblocks;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
914
  	nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
915
916
917
918
919
920
921
922
923
924
925
  	if (block < nblocks) {
  		start = 0;
  		goto restart;
  	}
  
  cleanup_and_exit:
  	/* Clean up the read-ahead blocks */
  	for (; ra_ptr < ra_max; ra_ptr++)
  		brelse (bh_use[ra_ptr]);
  	return ret;
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
926
927
928
  #ifdef CONFIG_EXT4_INDEX
  static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry,
  		       struct ext4_dir_entry_2 **res_dir, int *err)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
929
930
931
932
933
  {
  	struct super_block * sb;
  	struct dx_hash_info	hinfo;
  	u32 hash;
  	struct dx_frame frames[2], *frame;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
934
  	struct ext4_dir_entry_2 *de, *top;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
  	struct buffer_head *bh;
  	unsigned long block;
  	int retval;
  	int namelen = dentry->d_name.len;
  	const u8 *name = dentry->d_name.name;
  	struct inode *dir = dentry->d_parent->d_inode;
  
  	sb = dir->i_sb;
  	/* NFS may look up ".." - look at dx_root directory block */
  	if (namelen > 2 || name[0] != '.'||(name[1] != '.' && name[1] != '\0')){
  		if (!(frame = dx_probe(dentry, NULL, &hinfo, frames, err)))
  			return NULL;
  	} else {
  		frame = frames;
  		frame->bh = NULL;			/* for dx_release() */
  		frame->at = (struct dx_entry *)frames;	/* hack for zero entry*/
  		dx_set_block(frame->at, 0);		/* dx_root block is 0 */
  	}
  	hash = hinfo.hash;
  	do {
  		block = dx_get_block(frame->at);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
956
  		if (!(bh = ext4_bread (NULL,dir, block, 0, err)))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
957
  			goto errout;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
958
959
960
961
962
963
  		de = (struct ext4_dir_entry_2 *) bh->b_data;
  		top = (struct ext4_dir_entry_2 *) ((char *) de + sb->s_blocksize -
  				       EXT4_DIR_REC_LEN(0));
  		for (; de < top; de = ext4_next_entry(de))
  		if (ext4_match (namelen, name, de)) {
  			if (!ext4_check_dir_entry("ext4_find_entry",
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
964
  						  dir, de, bh,
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
965
  				  (block<<EXT4_BLOCK_SIZE_BITS(sb))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
966
967
  					  +((char *)de - bh->b_data))) {
  				brelse (bh);
fedee54d8   Dmitriy Monakhov   ext3: dirindex er...
968
  				*err = ERR_BAD_DX_DIR;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
969
970
971
972
973
974
975
976
  				goto errout;
  			}
  			*res_dir = de;
  			dx_release (frames);
  			return bh;
  		}
  		brelse (bh);
  		/* Check to see if we should continue to search */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
977
  		retval = ext4_htree_next_block(dir, hash, frame,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
978
979
  					       frames, NULL);
  		if (retval < 0) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
980
  			ext4_warning(sb, __FUNCTION__,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
  			     "error reading index page in directory #%lu",
  			     dir->i_ino);
  			*err = retval;
  			goto errout;
  		}
  	} while (retval == 1);
  
  	*err = -ENOENT;
  errout:
  	dxtrace(printk("%s not found
  ", name));
  	dx_release (frames);
  	return NULL;
  }
  #endif
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
996
  static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
997
998
  {
  	struct inode * inode;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
999
  	struct ext4_dir_entry_2 * de;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1000
  	struct buffer_head * bh;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1001
  	if (dentry->d_name.len > EXT4_NAME_LEN)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1002
  		return ERR_PTR(-ENAMETOOLONG);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1003
  	bh = ext4_find_entry(dentry, &de);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1004
1005
1006
1007
  	inode = NULL;
  	if (bh) {
  		unsigned long ino = le32_to_cpu(de->inode);
  		brelse (bh);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1008
1009
  		if (!ext4_valid_inum(dir->i_sb, ino)) {
  			ext4_error(dir->i_sb, "ext4_lookup",
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1010
1011
1012
1013
1014
1015
1016
  				   "bad inode number: %lu", ino);
  			inode = NULL;
  		} else
  			inode = iget(dir->i_sb, ino);
  
  		if (!inode)
  			return ERR_PTR(-EACCES);
a6c15c2b0   Vasily Averin   ext3/ext4: orphan...
1017
1018
1019
1020
1021
  
  		if (is_bad_inode(inode)) {
  			iput(inode);
  			return ERR_PTR(-ENOENT);
  		}
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1022
1023
1024
  	}
  	return d_splice_alias(inode, dentry);
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1025
  struct dentry *ext4_get_parent(struct dentry *child)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1026
1027
1028
1029
1030
  {
  	unsigned long ino;
  	struct dentry *parent;
  	struct inode *inode;
  	struct dentry dotdot;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1031
  	struct ext4_dir_entry_2 * de;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1032
1033
1034
1035
1036
  	struct buffer_head *bh;
  
  	dotdot.d_name.name = "..";
  	dotdot.d_name.len = 2;
  	dotdot.d_parent = child; /* confusing, isn't it! */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1037
  	bh = ext4_find_entry(&dotdot, &de);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1038
1039
1040
1041
1042
  	inode = NULL;
  	if (!bh)
  		return ERR_PTR(-ENOENT);
  	ino = le32_to_cpu(de->inode);
  	brelse(bh);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1043
1044
  	if (!ext4_valid_inum(child->d_inode->i_sb, ino)) {
  		ext4_error(child->d_inode->i_sb, "ext4_get_parent",
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1045
1046
1047
1048
1049
1050
1051
  			   "bad inode number: %lu", ino);
  		inode = NULL;
  	} else
  		inode = iget(child->d_inode->i_sb, ino);
  
  	if (!inode)
  		return ERR_PTR(-EACCES);
a6c15c2b0   Vasily Averin   ext3/ext4: orphan...
1052
1053
1054
1055
  	if (is_bad_inode(inode)) {
  		iput(inode);
  		return ERR_PTR(-ENOENT);
  	}
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1056
1057
1058
1059
1060
1061
1062
1063
1064
  	parent = d_alloc_anon(inode);
  	if (!parent) {
  		iput(inode);
  		parent = ERR_PTR(-ENOMEM);
  	}
  	return parent;
  }
  
  #define S_SHIFT 12
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1065
1066
1067
1068
1069
1070
1071
1072
  static unsigned char ext4_type_by_mode[S_IFMT >> S_SHIFT] = {
  	[S_IFREG >> S_SHIFT]	= EXT4_FT_REG_FILE,
  	[S_IFDIR >> S_SHIFT]	= EXT4_FT_DIR,
  	[S_IFCHR >> S_SHIFT]	= EXT4_FT_CHRDEV,
  	[S_IFBLK >> S_SHIFT]	= EXT4_FT_BLKDEV,
  	[S_IFIFO >> S_SHIFT]	= EXT4_FT_FIFO,
  	[S_IFSOCK >> S_SHIFT]	= EXT4_FT_SOCK,
  	[S_IFLNK >> S_SHIFT]	= EXT4_FT_SYMLINK,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1073
  };
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1074
1075
  static inline void ext4_set_de_type(struct super_block *sb,
  				struct ext4_dir_entry_2 *de,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1076
  				umode_t mode) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1077
1078
  	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FILETYPE))
  		de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT];
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1079
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1080
1081
  #ifdef CONFIG_EXT4_INDEX
  static struct ext4_dir_entry_2 *
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1082
1083
1084
1085
1086
  dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count)
  {
  	unsigned rec_len = 0;
  
  	while (count--) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1087
1088
  		struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) (from + map->offs);
  		rec_len = EXT4_DIR_REC_LEN(de->name_len);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1089
  		memcpy (to, de, rec_len);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1090
  		((struct ext4_dir_entry_2 *) to)->rec_len =
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1091
1092
1093
1094
1095
  				cpu_to_le16(rec_len);
  		de->inode = 0;
  		map++;
  		to += rec_len;
  	}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1096
  	return (struct ext4_dir_entry_2 *) (to - rec_len);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1097
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1098
  static struct ext4_dir_entry_2* dx_pack_dirents(char *base, int size)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1099
  {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1100
  	struct ext4_dir_entry_2 *next, *to, *prev, *de = (struct ext4_dir_entry_2 *) base;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1101
1102
1103
1104
  	unsigned rec_len = 0;
  
  	prev = to = de;
  	while ((char*)de < base + size) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1105
  		next = (struct ext4_dir_entry_2 *) ((char *) de +
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1106
1107
  						    le16_to_cpu(de->rec_len));
  		if (de->inode && de->name_len) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1108
  			rec_len = EXT4_DIR_REC_LEN(de->name_len);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1109
1110
1111
1112
  			if (de > to)
  				memmove(to, de, rec_len);
  			to->rec_len = cpu_to_le16(rec_len);
  			prev = to;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1113
  			to = (struct ext4_dir_entry_2 *) (((char *) to) + rec_len);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1114
1115
1116
1117
1118
  		}
  		de = next;
  	}
  	return prev;
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1119
  static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
  			struct buffer_head **bh,struct dx_frame *frame,
  			struct dx_hash_info *hinfo, int *error)
  {
  	unsigned blocksize = dir->i_sb->s_blocksize;
  	unsigned count, continued;
  	struct buffer_head *bh2;
  	u32 newblock;
  	u32 hash2;
  	struct dx_map_entry *map;
  	char *data1 = (*bh)->b_data, *data2;
  	unsigned split;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1131
  	struct ext4_dir_entry_2 *de = NULL, *de2;
fedee54d8   Dmitriy Monakhov   ext3: dirindex er...
1132
  	int	err = 0;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1133

fedee54d8   Dmitriy Monakhov   ext3: dirindex er...
1134
  	bh2 = ext4_append (handle, dir, &newblock, &err);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1135
1136
1137
1138
1139
1140
1141
  	if (!(bh2)) {
  		brelse(*bh);
  		*bh = NULL;
  		goto errout;
  	}
  
  	BUFFER_TRACE(*bh, "get_write_access");
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1142
  	err = ext4_journal_get_write_access(handle, *bh);
fedee54d8   Dmitriy Monakhov   ext3: dirindex er...
1143
1144
  	if (err)
  		goto journal_error;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1145
  	BUFFER_TRACE(frame->bh, "get_write_access");
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1146
  	err = ext4_journal_get_write_access(handle, frame->bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1147
1148
1149
1150
1151
1152
1153
  	if (err)
  		goto journal_error;
  
  	data2 = bh2->b_data;
  
  	/* create map in the end of data2 block */
  	map = (struct dx_map_entry *) (data2 + blocksize);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1154
  	count = dx_make_map ((struct ext4_dir_entry_2 *) data1,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
  			     blocksize, hinfo, map);
  	map -= count;
  	split = count/2; // need to adjust to actual middle
  	dx_sort_map (map, count);
  	hash2 = map[split].hash;
  	continued = hash2 == map[split - 1].hash;
  	dxtrace(printk("Split block %i at %x, %i/%i
  ",
  		dx_get_block(frame->at), hash2, split, count-split));
  
  	/* Fancy dance to stay within two buffers */
  	de2 = dx_move_dirents(data1, data2, map + split, count - split);
  	de = dx_pack_dirents(data1,blocksize);
  	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
  	de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1170
1171
  	dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data1, blocksize, 1));
  	dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data2, blocksize, 1));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1172
1173
1174
1175
1176
1177
1178
1179
  
  	/* Which block gets the new entry? */
  	if (hinfo->hash >= hash2)
  	{
  		swap(*bh, bh2);
  		de = de2;
  	}
  	dx_insert_block (frame, hash2 + continued, newblock);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1180
  	err = ext4_journal_dirty_metadata (handle, bh2);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1181
1182
  	if (err)
  		goto journal_error;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1183
  	err = ext4_journal_dirty_metadata (handle, frame->bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1184
1185
1186
1187
  	if (err)
  		goto journal_error;
  	brelse (bh2);
  	dxtrace(dx_show_index ("frame", frame->entries));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1188
  	return de;
fedee54d8   Dmitriy Monakhov   ext3: dirindex er...
1189
1190
1191
1192
1193
1194
1195
1196
1197
  
  journal_error:
  	brelse(*bh);
  	brelse(bh2);
  	*bh = NULL;
  	ext4_std_error(dir->i_sb, err);
  errout:
  	*error = err;
  	return NULL;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
  }
  #endif
  
  
  /*
   * Add a new entry into a directory (leaf) block.  If de is non-NULL,
   * it points to a directory entry which is guaranteed to be large
   * enough for new directory entry.  If de is NULL, then
   * add_dirent_to_buf will attempt search the directory block for
   * space.  It will return -ENOSPC if no space is available, and -EIO
   * and -EEXIST if directory entry already exists.
   *
   * NOTE!  bh is NOT released in the case where ENOSPC is returned.  In
   * all other cases bh is released.
   */
  static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1214
  			     struct inode *inode, struct ext4_dir_entry_2 *de,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1215
1216
1217
1218
1219
1220
1221
1222
1223
  			     struct buffer_head * bh)
  {
  	struct inode	*dir = dentry->d_parent->d_inode;
  	const char	*name = dentry->d_name.name;
  	int		namelen = dentry->d_name.len;
  	unsigned long	offset = 0;
  	unsigned short	reclen;
  	int		nlen, rlen, err;
  	char		*top;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1224
  	reclen = EXT4_DIR_REC_LEN(namelen);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1225
  	if (!de) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1226
  		de = (struct ext4_dir_entry_2 *)bh->b_data;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1227
1228
  		top = bh->b_data + dir->i_sb->s_blocksize - reclen;
  		while ((char *) de <= top) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1229
  			if (!ext4_check_dir_entry("ext4_add_entry", dir, de,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1230
1231
1232
1233
  						  bh, offset)) {
  				brelse (bh);
  				return -EIO;
  			}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1234
  			if (ext4_match (namelen, name, de)) {
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1235
1236
1237
  				brelse (bh);
  				return -EEXIST;
  			}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1238
  			nlen = EXT4_DIR_REC_LEN(de->name_len);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1239
1240
1241
  			rlen = le16_to_cpu(de->rec_len);
  			if ((de->inode? rlen - nlen: rlen) >= reclen)
  				break;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1242
  			de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1243
1244
1245
1246
1247
1248
  			offset += rlen;
  		}
  		if ((char *) de > top)
  			return -ENOSPC;
  	}
  	BUFFER_TRACE(bh, "get_write_access");
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1249
  	err = ext4_journal_get_write_access(handle, bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1250
  	if (err) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1251
  		ext4_std_error(dir->i_sb, err);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1252
1253
1254
1255
1256
  		brelse(bh);
  		return err;
  	}
  
  	/* By now the buffer is marked for journaling */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1257
  	nlen = EXT4_DIR_REC_LEN(de->name_len);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1258
1259
  	rlen = le16_to_cpu(de->rec_len);
  	if (de->inode) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1260
  		struct ext4_dir_entry_2 *de1 = (struct ext4_dir_entry_2 *)((char *)de + nlen);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1261
1262
1263
1264
  		de1->rec_len = cpu_to_le16(rlen - nlen);
  		de->rec_len = cpu_to_le16(nlen);
  		de = de1;
  	}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1265
  	de->file_type = EXT4_FT_UNKNOWN;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1266
1267
  	if (inode) {
  		de->inode = cpu_to_le32(inode->i_ino);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1268
  		ext4_set_de_type(dir->i_sb, de, inode->i_mode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
  	} else
  		de->inode = 0;
  	de->name_len = namelen;
  	memcpy (de->name, name, namelen);
  	/*
  	 * XXX shouldn't update any times until successful
  	 * completion of syscall, but too many callers depend
  	 * on this.
  	 *
  	 * XXX similarly, too many callers depend on
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1279
  	 * ext4_new_inode() setting the times, but error
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1280
1281
1282
1283
  	 * recovery deletes the inode, so the worst that can
  	 * happen is that the times are slightly out of date
  	 * and/or different from the directory change time.
  	 */
ef7f38359   Kalpak Shah   ext4: Add nanosec...
1284
  	dir->i_mtime = dir->i_ctime = ext4_current_time(dir);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1285
  	ext4_update_dx_flag(dir);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1286
  	dir->i_version++;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1287
1288
1289
  	ext4_mark_inode_dirty(handle, dir);
  	BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
  	err = ext4_journal_dirty_metadata(handle, bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1290
  	if (err)
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1291
  		ext4_std_error(dir->i_sb, err);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1292
1293
1294
  	brelse(bh);
  	return 0;
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1295
  #ifdef CONFIG_EXT4_INDEX
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
  /*
   * This converts a one block unindexed directory to a 3 block indexed
   * directory, and adds the dentry to the indexed directory.
   */
  static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
  			    struct inode *inode, struct buffer_head *bh)
  {
  	struct inode	*dir = dentry->d_parent->d_inode;
  	const char	*name = dentry->d_name.name;
  	int		namelen = dentry->d_name.len;
  	struct buffer_head *bh2;
  	struct dx_root	*root;
  	struct dx_frame	frames[2], *frame;
  	struct dx_entry *entries;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1310
  	struct ext4_dir_entry_2	*de, *de2;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
  	char		*data1, *top;
  	unsigned	len;
  	int		retval;
  	unsigned	blocksize;
  	struct dx_hash_info hinfo;
  	u32		block;
  	struct fake_dirent *fde;
  
  	blocksize =  dir->i_sb->s_blocksize;
  	dxtrace(printk("Creating index
  "));
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1322
  	retval = ext4_journal_get_write_access(handle, bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1323
  	if (retval) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1324
  		ext4_std_error(dir->i_sb, retval);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1325
1326
1327
1328
  		brelse(bh);
  		return retval;
  	}
  	root = (struct dx_root *) bh->b_data;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1329
  	bh2 = ext4_append (handle, dir, &block, &retval);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1330
1331
1332
1333
  	if (!(bh2)) {
  		brelse(bh);
  		return retval;
  	}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1334
  	EXT4_I(dir)->i_flags |= EXT4_INDEX_FL;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1335
1336
1337
1338
  	data1 = bh2->b_data;
  
  	/* The 0th block becomes the root, move the dirents out */
  	fde = &root->dotdot;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1339
  	de = (struct ext4_dir_entry_2 *)((char *)fde + le16_to_cpu(fde->rec_len));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1340
1341
  	len = ((char *) root) + blocksize - (char *) de;
  	memcpy (data1, de, len);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1342
  	de = (struct ext4_dir_entry_2 *) data1;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1343
1344
1345
1346
1347
  	top = data1 + len;
  	while ((char *)(de2=(void*)de+le16_to_cpu(de->rec_len)) < top)
  		de = de2;
  	de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de);
  	/* Initialize the root; the dot dirents already exist */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1348
1349
  	de = (struct ext4_dir_entry_2 *) (&root->dotdot);
  	de->rec_len = cpu_to_le16(blocksize - EXT4_DIR_REC_LEN(2));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1350
1351
  	memset (&root->info, 0, sizeof(root->info));
  	root->info.info_length = sizeof(root->info);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1352
  	root->info.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1353
1354
1355
1356
1357
1358
1359
  	entries = root->entries;
  	dx_set_block (entries, 1);
  	dx_set_count (entries, 1);
  	dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info)));
  
  	/* Initialize as for dx_probe */
  	hinfo.hash_version = root->info.hash_version;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1360
1361
  	hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
  	ext4fs_dirhash(name, namelen, &hinfo);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
  	frame = frames;
  	frame->entries = entries;
  	frame->at = entries;
  	frame->bh = bh;
  	bh = bh2;
  	de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
  	dx_release (frames);
  	if (!(de))
  		return retval;
  
  	return add_dirent_to_buf(handle, dentry, inode, de, bh);
  }
  #endif
  
  /*
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1377
   *	ext4_add_entry()
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1378
1379
   *
   * adds a file entry to the specified directory, using the same
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1380
   * semantics as ext4_find_entry(). It returns NULL if it failed.
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1381
1382
1383
1384
1385
   *
   * NOTE!! The inode part of 'de' is left at 0 - which means you
   * may not sleep between calling this and putting something into
   * the entry, as someone else might have used it while you slept.
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1386
  static int ext4_add_entry (handle_t *handle, struct dentry *dentry,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1387
1388
1389
1390
1391
  	struct inode *inode)
  {
  	struct inode *dir = dentry->d_parent->d_inode;
  	unsigned long offset;
  	struct buffer_head * bh;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1392
  	struct ext4_dir_entry_2 *de;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1393
1394
  	struct super_block * sb;
  	int	retval;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1395
  #ifdef CONFIG_EXT4_INDEX
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1396
1397
1398
1399
1400
1401
1402
1403
1404
  	int	dx_fallback=0;
  #endif
  	unsigned blocksize;
  	u32 block, blocks;
  
  	sb = dir->i_sb;
  	blocksize = sb->s_blocksize;
  	if (!dentry->d_name.len)
  		return -EINVAL;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1405
  #ifdef CONFIG_EXT4_INDEX
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1406
  	if (is_dx(dir)) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1407
  		retval = ext4_dx_add_entry(handle, dentry, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1408
1409
  		if (!retval || (retval != ERR_BAD_DX_DIR))
  			return retval;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1410
  		EXT4_I(dir)->i_flags &= ~EXT4_INDEX_FL;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1411
  		dx_fallback++;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1412
  		ext4_mark_inode_dirty(handle, dir);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1413
1414
1415
1416
  	}
  #endif
  	blocks = dir->i_size >> sb->s_blocksize_bits;
  	for (block = 0, offset = 0; block < blocks; block++) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1417
  		bh = ext4_bread(handle, dir, block, 0, &retval);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1418
1419
1420
1421
1422
  		if(!bh)
  			return retval;
  		retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
  		if (retval != -ENOSPC)
  			return retval;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1423
  #ifdef CONFIG_EXT4_INDEX
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1424
  		if (blocks == 1 && !dx_fallback &&
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1425
  		    EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1426
1427
1428
1429
  			return make_indexed_dir(handle, dentry, inode, bh);
  #endif
  		brelse(bh);
  	}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1430
  	bh = ext4_append(handle, dir, &block, &retval);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1431
1432
  	if (!bh)
  		return retval;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1433
  	de = (struct ext4_dir_entry_2 *) bh->b_data;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1434
1435
1436
1437
  	de->inode = 0;
  	de->rec_len = cpu_to_le16(blocksize);
  	return add_dirent_to_buf(handle, dentry, inode, de, bh);
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1438
  #ifdef CONFIG_EXT4_INDEX
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1439
1440
1441
  /*
   * Returns 0 for success, or a negative error value
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1442
  static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1443
1444
1445
1446
1447
1448
1449
1450
  			     struct inode *inode)
  {
  	struct dx_frame frames[2], *frame;
  	struct dx_entry *entries, *at;
  	struct dx_hash_info hinfo;
  	struct buffer_head * bh;
  	struct inode *dir = dentry->d_parent->d_inode;
  	struct super_block * sb = dir->i_sb;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1451
  	struct ext4_dir_entry_2 *de;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1452
1453
1454
1455
1456
1457
1458
  	int err;
  
  	frame = dx_probe(dentry, NULL, &hinfo, frames, &err);
  	if (!frame)
  		return err;
  	entries = frame->entries;
  	at = frame->at;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1459
  	if (!(bh = ext4_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1460
1461
1462
  		goto cleanup;
  
  	BUFFER_TRACE(bh, "get_write_access");
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1463
  	err = ext4_journal_get_write_access(handle, bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
  	if (err)
  		goto journal_error;
  
  	err = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
  	if (err != -ENOSPC) {
  		bh = NULL;
  		goto cleanup;
  	}
  
  	/* Block full, should compress but for now just split */
  	dxtrace(printk("using %u of %u node entries
  ",
  		       dx_get_count(entries), dx_get_limit(entries)));
  	/* Need to split index? */
  	if (dx_get_count(entries) == dx_get_limit(entries)) {
  		u32 newblock;
  		unsigned icount = dx_get_count(entries);
  		int levels = frame - frames;
  		struct dx_entry *entries2;
  		struct dx_node *node2;
  		struct buffer_head *bh2;
  
  		if (levels && (dx_get_count(frames->entries) ==
  			       dx_get_limit(frames->entries))) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1488
  			ext4_warning(sb, __FUNCTION__,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1489
1490
1491
1492
  				     "Directory index full!");
  			err = -ENOSPC;
  			goto cleanup;
  		}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1493
  		bh2 = ext4_append (handle, dir, &newblock, &err);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1494
1495
1496
1497
1498
1499
1500
  		if (!(bh2))
  			goto cleanup;
  		node2 = (struct dx_node *)(bh2->b_data);
  		entries2 = node2->entries;
  		node2->fake.rec_len = cpu_to_le16(sb->s_blocksize);
  		node2->fake.inode = 0;
  		BUFFER_TRACE(frame->bh, "get_write_access");
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1501
  		err = ext4_journal_get_write_access(handle, frame->bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1502
1503
1504
1505
1506
1507
1508
1509
1510
  		if (err)
  			goto journal_error;
  		if (levels) {
  			unsigned icount1 = icount/2, icount2 = icount - icount1;
  			unsigned hash2 = dx_get_hash(entries + icount1);
  			dxtrace(printk("Split index %i/%i
  ", icount1, icount2));
  
  			BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1511
  			err = ext4_journal_get_write_access(handle,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
  							     frames[0].bh);
  			if (err)
  				goto journal_error;
  
  			memcpy ((char *) entries2, (char *) (entries + icount1),
  				icount2 * sizeof(struct dx_entry));
  			dx_set_count (entries, icount1);
  			dx_set_count (entries2, icount2);
  			dx_set_limit (entries2, dx_node_limit(dir));
  
  			/* Which index block gets the new entry? */
  			if (at - entries >= icount1) {
  				frame->at = at = at - entries - icount1 + entries2;
  				frame->entries = entries = entries2;
  				swap(frame->bh, bh2);
  			}
  			dx_insert_block (frames + 0, hash2, newblock);
  			dxtrace(dx_show_index ("node", frames[1].entries));
  			dxtrace(dx_show_index ("node",
  			       ((struct dx_node *) bh2->b_data)->entries));
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1532
  			err = ext4_journal_dirty_metadata(handle, bh2);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
  			if (err)
  				goto journal_error;
  			brelse (bh2);
  		} else {
  			dxtrace(printk("Creating second level index...
  "));
  			memcpy((char *) entries2, (char *) entries,
  			       icount * sizeof(struct dx_entry));
  			dx_set_limit(entries2, dx_node_limit(dir));
  
  			/* Set up root */
  			dx_set_count(entries, 1);
  			dx_set_block(entries + 0, newblock);
  			((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1;
  
  			/* Add new access path frame */
  			frame = frames + 1;
  			frame->at = at = at - entries + entries2;
  			frame->entries = entries = entries2;
  			frame->bh = bh2;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1553
  			err = ext4_journal_get_write_access(handle,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1554
1555
1556
1557
  							     frame->bh);
  			if (err)
  				goto journal_error;
  		}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1558
  		ext4_journal_dirty_metadata(handle, frames[0].bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1559
1560
1561
1562
1563
1564
1565
1566
1567
  	}
  	de = do_split(handle, dir, &bh, frame, &hinfo, &err);
  	if (!de)
  		goto cleanup;
  	err = add_dirent_to_buf(handle, dentry, inode, de, bh);
  	bh = NULL;
  	goto cleanup;
  
  journal_error:
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1568
  	ext4_std_error(dir->i_sb, err);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1569
1570
1571
1572
1573
1574
1575
1576
1577
  cleanup:
  	if (bh)
  		brelse(bh);
  	dx_release(frames);
  	return err;
  }
  #endif
  
  /*
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1578
   * ext4_delete_entry deletes a directory entry by merging it with the
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1579
1580
   * previous entry
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1581
  static int ext4_delete_entry (handle_t *handle,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1582
  			      struct inode * dir,
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1583
  			      struct ext4_dir_entry_2 * de_del,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1584
1585
  			      struct buffer_head * bh)
  {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1586
  	struct ext4_dir_entry_2 * de, * pde;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1587
1588
1589
1590
  	int i;
  
  	i = 0;
  	pde = NULL;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1591
  	de = (struct ext4_dir_entry_2 *) bh->b_data;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1592
  	while (i < bh->b_size) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1593
  		if (!ext4_check_dir_entry("ext4_delete_entry", dir, de, bh, i))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1594
1595
1596
  			return -EIO;
  		if (de == de_del)  {
  			BUFFER_TRACE(bh, "get_write_access");
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1597
  			ext4_journal_get_write_access(handle, bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1598
1599
1600
1601
1602
1603
1604
  			if (pde)
  				pde->rec_len =
  					cpu_to_le16(le16_to_cpu(pde->rec_len) +
  						    le16_to_cpu(de->rec_len));
  			else
  				de->inode = 0;
  			dir->i_version++;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1605
1606
  			BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata");
  			ext4_journal_dirty_metadata(handle, bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1607
1608
1609
1610
  			return 0;
  		}
  		i += le16_to_cpu(de->rec_len);
  		pde = de;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1611
  		de = (struct ext4_dir_entry_2 *)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1612
1613
1614
1615
  			((char *) de + le16_to_cpu(de->rec_len));
  	}
  	return -ENOENT;
  }
f8628a14a   Andreas Dilger   ext4: Remove 6500...
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
  /*
   * DIR_NLINK feature is set if 1) nlinks > EXT4_LINK_MAX or 2) nlinks == 2,
   * since this indicates that nlinks count was previously 1.
   */
  static void ext4_inc_count(handle_t *handle, struct inode *inode)
  {
  	inc_nlink(inode);
  	if (is_dx(inode) && inode->i_nlink > 1) {
  		/* limit is 16-bit i_links_count */
  		if (inode->i_nlink >= EXT4_LINK_MAX || inode->i_nlink == 2) {
  			inode->i_nlink = 1;
  			EXT4_SET_RO_COMPAT_FEATURE(inode->i_sb,
  					      EXT4_FEATURE_RO_COMPAT_DIR_NLINK);
  		}
  	}
  }
  
  /*
   * If a directory had nlink == 1, then we should let it be 1. This indicates
   * directory has >EXT4_LINK_MAX subdirs.
   */
  static void ext4_dec_count(handle_t *handle, struct inode *inode)
  {
  	drop_nlink(inode);
  	if (S_ISDIR(inode->i_mode) && inode->i_nlink == 0)
  		inc_nlink(inode);
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1643
  static int ext4_add_nondir(handle_t *handle,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1644
1645
  		struct dentry *dentry, struct inode *inode)
  {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1646
  	int err = ext4_add_entry(handle, dentry, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1647
  	if (!err) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1648
  		ext4_mark_inode_dirty(handle, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1649
1650
1651
  		d_instantiate(dentry, inode);
  		return 0;
  	}
731b9a549   Eric Sandeen   [PATCH] remove ex...
1652
  	drop_nlink(inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
  	iput(inode);
  	return err;
  }
  
  /*
   * By the time this is called, we already have created
   * the directory cache entry for the new file, but it
   * is so far negative - it has no inode.
   *
   * If the create succeeds, we fill in the inode information
   * with d_instantiate().
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1665
  static int ext4_create (struct inode * dir, struct dentry * dentry, int mode,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1666
1667
1668
1669
1670
1671
1672
  		struct nameidata *nd)
  {
  	handle_t *handle;
  	struct inode * inode;
  	int err, retries = 0;
  
  retry:
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1673
1674
1675
  	handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
  					EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
  					2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1676
1677
1678
1679
1680
  	if (IS_ERR(handle))
  		return PTR_ERR(handle);
  
  	if (IS_DIRSYNC(dir))
  		handle->h_sync = 1;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1681
  	inode = ext4_new_inode (handle, dir, mode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1682
1683
  	err = PTR_ERR(inode);
  	if (!IS_ERR(inode)) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1684
1685
1686
1687
  		inode->i_op = &ext4_file_inode_operations;
  		inode->i_fop = &ext4_file_operations;
  		ext4_set_aops(inode);
  		err = ext4_add_nondir(handle, dentry, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1688
  	}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1689
1690
  	ext4_journal_stop(handle);
  	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1691
1692
1693
  		goto retry;
  	return err;
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1694
  static int ext4_mknod (struct inode * dir, struct dentry *dentry,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
  			int mode, dev_t rdev)
  {
  	handle_t *handle;
  	struct inode *inode;
  	int err, retries = 0;
  
  	if (!new_valid_dev(rdev))
  		return -EINVAL;
  
  retry:
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1705
1706
1707
  	handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
  					EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
  					2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1708
1709
1710
1711
1712
  	if (IS_ERR(handle))
  		return PTR_ERR(handle);
  
  	if (IS_DIRSYNC(dir))
  		handle->h_sync = 1;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1713
  	inode = ext4_new_inode (handle, dir, mode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1714
1715
1716
  	err = PTR_ERR(inode);
  	if (!IS_ERR(inode)) {
  		init_special_inode(inode, inode->i_mode, rdev);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1717
1718
  #ifdef CONFIG_EXT4DEV_FS_XATTR
  		inode->i_op = &ext4_special_inode_operations;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1719
  #endif
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1720
  		err = ext4_add_nondir(handle, dentry, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1721
  	}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1722
1723
  	ext4_journal_stop(handle);
  	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1724
1725
1726
  		goto retry;
  	return err;
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1727
  static int ext4_mkdir(struct inode * dir, struct dentry * dentry, int mode)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1728
1729
1730
1731
  {
  	handle_t *handle;
  	struct inode * inode;
  	struct buffer_head * dir_block;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1732
  	struct ext4_dir_entry_2 * de;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1733
  	int err, retries = 0;
f8628a14a   Andreas Dilger   ext4: Remove 6500...
1734
  	if (EXT4_DIR_LINK_MAX(dir))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1735
1736
1737
  		return -EMLINK;
  
  retry:
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1738
1739
1740
  	handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
  					EXT4_INDEX_EXTRA_TRANS_BLOCKS + 3 +
  					2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1741
1742
1743
1744
1745
  	if (IS_ERR(handle))
  		return PTR_ERR(handle);
  
  	if (IS_DIRSYNC(dir))
  		handle->h_sync = 1;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1746
  	inode = ext4_new_inode (handle, dir, S_IFDIR | mode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1747
1748
1749
  	err = PTR_ERR(inode);
  	if (IS_ERR(inode))
  		goto out_stop;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1750
1751
1752
1753
  	inode->i_op = &ext4_dir_inode_operations;
  	inode->i_fop = &ext4_dir_operations;
  	inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
  	dir_block = ext4_bread (handle, inode, 0, 1, &err);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1754
  	if (!dir_block) {
f8628a14a   Andreas Dilger   ext4: Remove 6500...
1755
  		ext4_dec_count(handle, inode); /* is this nlink == 0? */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1756
  		ext4_mark_inode_dirty(handle, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1757
1758
1759
1760
  		iput (inode);
  		goto out_stop;
  	}
  	BUFFER_TRACE(dir_block, "get_write_access");
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1761
1762
  	ext4_journal_get_write_access(handle, dir_block);
  	de = (struct ext4_dir_entry_2 *) dir_block->b_data;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1763
1764
  	de->inode = cpu_to_le32(inode->i_ino);
  	de->name_len = 1;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1765
  	de->rec_len = cpu_to_le16(EXT4_DIR_REC_LEN(de->name_len));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1766
  	strcpy (de->name, ".");
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1767
1768
  	ext4_set_de_type(dir->i_sb, de, S_IFDIR);
  	de = (struct ext4_dir_entry_2 *)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1769
1770
  			((char *) de + le16_to_cpu(de->rec_len));
  	de->inode = cpu_to_le32(dir->i_ino);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1771
  	de->rec_len = cpu_to_le16(inode->i_sb->s_blocksize-EXT4_DIR_REC_LEN(1));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1772
1773
  	de->name_len = 2;
  	strcpy (de->name, "..");
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1774
  	ext4_set_de_type(dir->i_sb, de, S_IFDIR);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1775
  	inode->i_nlink = 2;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1776
1777
  	BUFFER_TRACE(dir_block, "call ext4_journal_dirty_metadata");
  	ext4_journal_dirty_metadata(handle, dir_block);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1778
  	brelse (dir_block);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1779
1780
  	ext4_mark_inode_dirty(handle, inode);
  	err = ext4_add_entry (handle, dentry, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1781
1782
  	if (err) {
  		inode->i_nlink = 0;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1783
  		ext4_mark_inode_dirty(handle, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1784
1785
1786
  		iput (inode);
  		goto out_stop;
  	}
f8628a14a   Andreas Dilger   ext4: Remove 6500...
1787
  	ext4_inc_count(handle, dir);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1788
1789
  	ext4_update_dx_flag(dir);
  	ext4_mark_inode_dirty(handle, dir);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1790
1791
  	d_instantiate(dentry, inode);
  out_stop:
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1792
1793
  	ext4_journal_stop(handle);
  	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
  		goto retry;
  	return err;
  }
  
  /*
   * routine to check that the specified directory is empty (for rmdir)
   */
  static int empty_dir (struct inode * inode)
  {
  	unsigned long offset;
  	struct buffer_head * bh;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1805
  	struct ext4_dir_entry_2 * de, * de1;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1806
1807
1808
1809
  	struct super_block * sb;
  	int err = 0;
  
  	sb = inode->i_sb;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1810
1811
  	if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2) ||
  	    !(bh = ext4_bread (NULL, inode, 0, 0, &err))) {
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1812
  		if (err)
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1813
  			ext4_error(inode->i_sb, __FUNCTION__,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1814
1815
1816
  				   "error %d reading directory #%lu offset 0",
  				   err, inode->i_ino);
  		else
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1817
  			ext4_warning(inode->i_sb, __FUNCTION__,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1818
1819
1820
1821
  				     "bad directory (dir #%lu) - no data block",
  				     inode->i_ino);
  		return 1;
  	}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1822
1823
  	de = (struct ext4_dir_entry_2 *) bh->b_data;
  	de1 = (struct ext4_dir_entry_2 *)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1824
1825
1826
1827
1828
  			((char *) de + le16_to_cpu(de->rec_len));
  	if (le32_to_cpu(de->inode) != inode->i_ino ||
  			!le32_to_cpu(de1->inode) ||
  			strcmp (".", de->name) ||
  			strcmp ("..", de1->name)) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1829
  		ext4_warning (inode->i_sb, "empty_dir",
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1830
1831
1832
1833
1834
1835
  			      "bad directory (dir #%lu) - no `.' or `..'",
  			      inode->i_ino);
  		brelse (bh);
  		return 1;
  	}
  	offset = le16_to_cpu(de->rec_len) + le16_to_cpu(de1->rec_len);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1836
  	de = (struct ext4_dir_entry_2 *)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1837
1838
1839
1840
1841
1842
  			((char *) de1 + le16_to_cpu(de1->rec_len));
  	while (offset < inode->i_size ) {
  		if (!bh ||
  			(void *) de >= (void *) (bh->b_data+sb->s_blocksize)) {
  			err = 0;
  			brelse (bh);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1843
1844
  			bh = ext4_bread (NULL, inode,
  				offset >> EXT4_BLOCK_SIZE_BITS(sb), 0, &err);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1845
1846
  			if (!bh) {
  				if (err)
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1847
  					ext4_error(sb, __FUNCTION__,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1848
1849
1850
1851
1852
1853
  						   "error %d reading directory"
  						   " #%lu offset %lu",
  						   err, inode->i_ino, offset);
  				offset += sb->s_blocksize;
  				continue;
  			}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1854
  			de = (struct ext4_dir_entry_2 *) bh->b_data;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1855
  		}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1856
1857
  		if (!ext4_check_dir_entry("empty_dir", inode, de, bh, offset)) {
  			de = (struct ext4_dir_entry_2 *)(bh->b_data +
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1858
1859
1860
1861
1862
1863
1864
1865
1866
  							 sb->s_blocksize);
  			offset = (offset | (sb->s_blocksize - 1)) + 1;
  			continue;
  		}
  		if (le32_to_cpu(de->inode)) {
  			brelse (bh);
  			return 0;
  		}
  		offset += le16_to_cpu(de->rec_len);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1867
  		de = (struct ext4_dir_entry_2 *)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1868
1869
1870
1871
1872
  				((char *) de + le16_to_cpu(de->rec_len));
  	}
  	brelse (bh);
  	return 1;
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1873
  /* ext4_orphan_add() links an unlinked or truncated inode into a list of
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1874
1875
1876
1877
1878
   * such inodes, starting at the superblock, in case we crash before the
   * file is closed/deleted, or in case the inode truncate spans multiple
   * transactions and the last transaction is not recovered after a crash.
   *
   * At filesystem recovery time, we walk this list deleting unlinked
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1879
   * inodes and truncating linked inodes in ext4_orphan_cleanup().
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1880
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1881
  int ext4_orphan_add(handle_t *handle, struct inode *inode)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1882
1883
  {
  	struct super_block *sb = inode->i_sb;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1884
  	struct ext4_iloc iloc;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1885
1886
1887
  	int err = 0, rc;
  
  	lock_super(sb);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1888
  	if (!list_empty(&EXT4_I(inode)->i_orphan))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1889
1890
1891
1892
1893
1894
  		goto out_unlock;
  
  	/* Orphan handling is only valid for files with data blocks
  	 * being truncated, or files being unlinked. */
  
  	/* @@@ FIXME: Observation from aviro:
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1895
1896
  	 * I think I can trigger J_ASSERT in ext4_orphan_add().  We block
  	 * here (on lock_super()), so race with ext4_link() which might bump
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1897
1898
1899
1900
1901
  	 * ->i_nlink. For, say it, character device. Not a regular file,
  	 * not a directory, not a symlink and ->i_nlink > 0.
  	 */
  	J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
  		S_ISLNK(inode->i_mode)) || inode->i_nlink == 0);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1902
1903
  	BUFFER_TRACE(EXT4_SB(sb)->s_sbh, "get_write_access");
  	err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1904
1905
  	if (err)
  		goto out_unlock;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1906
  	err = ext4_reserve_inode_write(handle, inode, &iloc);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1907
1908
1909
1910
  	if (err)
  		goto out_unlock;
  
  	/* Insert this inode at the head of the on-disk orphan list... */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1911
1912
1913
1914
  	NEXT_ORPHAN(inode) = le32_to_cpu(EXT4_SB(sb)->s_es->s_last_orphan);
  	EXT4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);
  	err = ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh);
  	rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
  	if (!err)
  		err = rc;
  
  	/* Only add to the head of the in-memory list if all the
  	 * previous operations succeeded.  If the orphan_add is going to
  	 * fail (possibly taking the journal offline), we can't risk
  	 * leaving the inode on the orphan list: stray orphan-list
  	 * entries can cause panics at unmount time.
  	 *
  	 * This is safe: on error we're going to ignore the orphan list
  	 * anyway on the next recovery. */
  	if (!err)
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1927
  		list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1928
1929
1930
1931
1932
1933
1934
1935
  
  	jbd_debug(4, "superblock will point to %lu
  ", inode->i_ino);
  	jbd_debug(4, "orphan inode %lu will point to %d
  ",
  			inode->i_ino, NEXT_ORPHAN(inode));
  out_unlock:
  	unlock_super(sb);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1936
  	ext4_std_error(inode->i_sb, err);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1937
1938
1939
1940
  	return err;
  }
  
  /*
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1941
   * ext4_orphan_del() removes an unlinked or truncated inode from the list
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1942
1943
   * of such inodes stored on disk, because it is finally being cleaned up.
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1944
  int ext4_orphan_del(handle_t *handle, struct inode *inode)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1945
1946
  {
  	struct list_head *prev;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1947
1948
  	struct ext4_inode_info *ei = EXT4_I(inode);
  	struct ext4_sb_info *sbi;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1949
  	unsigned long ino_next;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1950
  	struct ext4_iloc iloc;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
  	int err = 0;
  
  	lock_super(inode->i_sb);
  	if (list_empty(&ei->i_orphan)) {
  		unlock_super(inode->i_sb);
  		return 0;
  	}
  
  	ino_next = NEXT_ORPHAN(inode);
  	prev = ei->i_orphan.prev;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1961
  	sbi = EXT4_SB(inode->i_sb);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
  
  	jbd_debug(4, "remove inode %lu from orphan list
  ", inode->i_ino);
  
  	list_del_init(&ei->i_orphan);
  
  	/* If we're on an error path, we may not have a valid
  	 * transaction handle with which to update the orphan list on
  	 * disk, but we still need to remove the inode from the linked
  	 * list in memory. */
  	if (!handle)
  		goto out;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1974
  	err = ext4_reserve_inode_write(handle, inode, &iloc);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1975
1976
1977
1978
1979
1980
1981
  	if (err)
  		goto out_err;
  
  	if (prev == &sbi->s_orphan) {
  		jbd_debug(4, "superblock will point to %lu
  ", ino_next);
  		BUFFER_TRACE(sbi->s_sbh, "get_write_access");
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1982
  		err = ext4_journal_get_write_access(handle, sbi->s_sbh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1983
1984
1985
  		if (err)
  			goto out_brelse;
  		sbi->s_es->s_last_orphan = cpu_to_le32(ino_next);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1986
  		err = ext4_journal_dirty_metadata(handle, sbi->s_sbh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1987
  	} else {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1988
  		struct ext4_iloc iloc2;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1989
  		struct inode *i_prev =
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1990
  			&list_entry(prev, struct ext4_inode_info, i_orphan)->vfs_inode;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1991
1992
1993
1994
  
  		jbd_debug(4, "orphan inode %lu will point to %lu
  ",
  			  i_prev->i_ino, ino_next);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1995
  		err = ext4_reserve_inode_write(handle, i_prev, &iloc2);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
1996
1997
1998
  		if (err)
  			goto out_brelse;
  		NEXT_ORPHAN(i_prev) = ino_next;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
1999
  		err = ext4_mark_iloc_dirty(handle, i_prev, &iloc2);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2000
2001
2002
2003
  	}
  	if (err)
  		goto out_brelse;
  	NEXT_ORPHAN(inode) = 0;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2004
  	err = ext4_mark_iloc_dirty(handle, inode, &iloc);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2005
2006
  
  out_err:
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2007
  	ext4_std_error(inode->i_sb, err);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2008
2009
2010
2011
2012
2013
2014
2015
  out:
  	unlock_super(inode->i_sb);
  	return err;
  
  out_brelse:
  	brelse(iloc.bh);
  	goto out_err;
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2016
  static int ext4_rmdir (struct inode * dir, struct dentry *dentry)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2017
2018
2019
2020
  {
  	int retval;
  	struct inode * inode;
  	struct buffer_head * bh;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2021
  	struct ext4_dir_entry_2 * de;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2022
2023
2024
2025
2026
  	handle_t *handle;
  
  	/* Initialize quotas before so that eventual writes go in
  	 * separate transaction */
  	DQUOT_INIT(dentry->d_inode);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2027
  	handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2028
2029
2030
2031
  	if (IS_ERR(handle))
  		return PTR_ERR(handle);
  
  	retval = -ENOENT;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2032
  	bh = ext4_find_entry (dentry, &de);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
  	if (!bh)
  		goto end_rmdir;
  
  	if (IS_DIRSYNC(dir))
  		handle->h_sync = 1;
  
  	inode = dentry->d_inode;
  
  	retval = -EIO;
  	if (le32_to_cpu(de->inode) != inode->i_ino)
  		goto end_rmdir;
  
  	retval = -ENOTEMPTY;
  	if (!empty_dir (inode))
  		goto end_rmdir;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2048
  	retval = ext4_delete_entry(handle, dir, de, bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2049
2050
  	if (retval)
  		goto end_rmdir;
f8628a14a   Andreas Dilger   ext4: Remove 6500...
2051
  	if (!EXT4_DIR_LINK_EMPTY(inode))
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2052
  		ext4_warning (inode->i_sb, "ext4_rmdir",
f8628a14a   Andreas Dilger   ext4: Remove 6500...
2053
  			      "empty directory has too many links (%d)",
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2054
2055
2056
2057
2058
2059
2060
  			      inode->i_nlink);
  	inode->i_version++;
  	clear_nlink(inode);
  	/* There's no need to set i_disksize: the fact that i_nlink is
  	 * zero will ensure that the right thing happens during any
  	 * recovery. */
  	inode->i_size = 0;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2061
  	ext4_orphan_add(handle, inode);
ef7f38359   Kalpak Shah   ext4: Add nanosec...
2062
  	inode->i_ctime = dir->i_ctime = dir->i_mtime = ext4_current_time(inode);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2063
  	ext4_mark_inode_dirty(handle, inode);
f8628a14a   Andreas Dilger   ext4: Remove 6500...
2064
  	ext4_dec_count(handle, dir);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2065
2066
  	ext4_update_dx_flag(dir);
  	ext4_mark_inode_dirty(handle, dir);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2067
2068
  
  end_rmdir:
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2069
  	ext4_journal_stop(handle);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2070
2071
2072
  	brelse (bh);
  	return retval;
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2073
  static int ext4_unlink(struct inode * dir, struct dentry *dentry)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2074
2075
2076
2077
  {
  	int retval;
  	struct inode * inode;
  	struct buffer_head * bh;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2078
  	struct ext4_dir_entry_2 * de;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2079
2080
2081
2082
2083
  	handle_t *handle;
  
  	/* Initialize quotas before so that eventual writes go
  	 * in separate transaction */
  	DQUOT_INIT(dentry->d_inode);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2084
  	handle = ext4_journal_start(dir, EXT4_DELETE_TRANS_BLOCKS(dir->i_sb));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2085
2086
2087
2088
2089
2090
2091
  	if (IS_ERR(handle))
  		return PTR_ERR(handle);
  
  	if (IS_DIRSYNC(dir))
  		handle->h_sync = 1;
  
  	retval = -ENOENT;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2092
  	bh = ext4_find_entry (dentry, &de);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
  	if (!bh)
  		goto end_unlink;
  
  	inode = dentry->d_inode;
  
  	retval = -EIO;
  	if (le32_to_cpu(de->inode) != inode->i_ino)
  		goto end_unlink;
  
  	if (!inode->i_nlink) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2103
  		ext4_warning (inode->i_sb, "ext4_unlink",
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2104
2105
2106
2107
  			      "Deleting nonexistent file (%lu), %d",
  			      inode->i_ino, inode->i_nlink);
  		inode->i_nlink = 1;
  	}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2108
  	retval = ext4_delete_entry(handle, dir, de, bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2109
2110
  	if (retval)
  		goto end_unlink;
ef7f38359   Kalpak Shah   ext4: Add nanosec...
2111
  	dir->i_ctime = dir->i_mtime = ext4_current_time(dir);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2112
2113
  	ext4_update_dx_flag(dir);
  	ext4_mark_inode_dirty(handle, dir);
f8628a14a   Andreas Dilger   ext4: Remove 6500...
2114
  	ext4_dec_count(handle, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2115
  	if (!inode->i_nlink)
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2116
  		ext4_orphan_add(handle, inode);
ef7f38359   Kalpak Shah   ext4: Add nanosec...
2117
  	inode->i_ctime = ext4_current_time(inode);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2118
  	ext4_mark_inode_dirty(handle, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2119
2120
2121
  	retval = 0;
  
  end_unlink:
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2122
  	ext4_journal_stop(handle);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2123
2124
2125
  	brelse (bh);
  	return retval;
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2126
  static int ext4_symlink (struct inode * dir,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
  		struct dentry *dentry, const char * symname)
  {
  	handle_t *handle;
  	struct inode * inode;
  	int l, err, retries = 0;
  
  	l = strlen(symname)+1;
  	if (l > dir->i_sb->s_blocksize)
  		return -ENAMETOOLONG;
  
  retry:
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2138
2139
2140
  	handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
  					EXT4_INDEX_EXTRA_TRANS_BLOCKS + 5 +
  					2*EXT4_QUOTA_INIT_BLOCKS(dir->i_sb));
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2141
2142
2143
2144
2145
  	if (IS_ERR(handle))
  		return PTR_ERR(handle);
  
  	if (IS_DIRSYNC(dir))
  		handle->h_sync = 1;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2146
  	inode = ext4_new_inode (handle, dir, S_IFLNK|S_IRWXUGO);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2147
2148
2149
  	err = PTR_ERR(inode);
  	if (IS_ERR(inode))
  		goto out_stop;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2150
2151
2152
  	if (l > sizeof (EXT4_I(inode)->i_data)) {
  		inode->i_op = &ext4_symlink_inode_operations;
  		ext4_set_aops(inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2153
  		/*
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2154
  		 * page_symlink() calls into ext4_prepare/commit_write.
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2155
2156
2157
2158
2159
2160
  		 * We have a transaction open.  All is sweetness.  It also sets
  		 * i_size in generic_commit_write().
  		 */
  		err = __page_symlink(inode, symname, l,
  				mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
  		if (err) {
f8628a14a   Andreas Dilger   ext4: Remove 6500...
2161
  			ext4_dec_count(handle, inode);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2162
  			ext4_mark_inode_dirty(handle, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2163
2164
2165
2166
  			iput (inode);
  			goto out_stop;
  		}
  	} else {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2167
2168
  		inode->i_op = &ext4_fast_symlink_inode_operations;
  		memcpy((char*)&EXT4_I(inode)->i_data,symname,l);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2169
2170
  		inode->i_size = l-1;
  	}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2171
2172
  	EXT4_I(inode)->i_disksize = inode->i_size;
  	err = ext4_add_nondir(handle, dentry, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2173
  out_stop:
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2174
2175
  	ext4_journal_stop(handle);
  	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2176
2177
2178
  		goto retry;
  	return err;
  }
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2179
  static int ext4_link (struct dentry * old_dentry,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2180
2181
2182
2183
2184
  		struct inode * dir, struct dentry *dentry)
  {
  	handle_t *handle;
  	struct inode *inode = old_dentry->d_inode;
  	int err, retries = 0;
f8628a14a   Andreas Dilger   ext4: Remove 6500...
2185
  	if (EXT4_DIR_LINK_MAX(inode))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2186
  		return -EMLINK;
f8628a14a   Andreas Dilger   ext4: Remove 6500...
2187

2988a7740   Eric Sandeen   [PATCH] return EN...
2188
2189
2190
2191
2192
2193
  	/*
  	 * Return -ENOENT if we've raced with unlink and i_nlink is 0.  Doing
  	 * otherwise has the potential to corrupt the orphan inode list.
  	 */
  	if (inode->i_nlink == 0)
  		return -ENOENT;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2194
2195
  
  retry:
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2196
2197
  	handle = ext4_journal_start(dir, EXT4_DATA_TRANS_BLOCKS(dir->i_sb) +
  					EXT4_INDEX_EXTRA_TRANS_BLOCKS);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2198
2199
2200
2201
2202
  	if (IS_ERR(handle))
  		return PTR_ERR(handle);
  
  	if (IS_DIRSYNC(dir))
  		handle->h_sync = 1;
ef7f38359   Kalpak Shah   ext4: Add nanosec...
2203
  	inode->i_ctime = ext4_current_time(inode);
f8628a14a   Andreas Dilger   ext4: Remove 6500...
2204
  	ext4_inc_count(handle, inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2205
  	atomic_inc(&inode->i_count);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2206
2207
2208
  	err = ext4_add_nondir(handle, dentry, inode);
  	ext4_journal_stop(handle);
  	if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2209
2210
2211
2212
2213
  		goto retry;
  	return err;
  }
  
  #define PARENT_INO(buffer) \
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2214
2215
  	((struct ext4_dir_entry_2 *) ((char *) buffer + \
  	le16_to_cpu(((struct ext4_dir_entry_2 *) buffer)->rec_len)))->inode
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2216
2217
2218
2219
2220
  
  /*
   * Anybody can rename anything with this: the permission checks are left to the
   * higher-level routines.
   */
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2221
  static int ext4_rename (struct inode * old_dir, struct dentry *old_dentry,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2222
2223
2224
2225
2226
  			   struct inode * new_dir,struct dentry *new_dentry)
  {
  	handle_t *handle;
  	struct inode * old_inode, * new_inode;
  	struct buffer_head * old_bh, * new_bh, * dir_bh;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2227
  	struct ext4_dir_entry_2 * old_de, * new_de;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2228
2229
2230
2231
2232
2233
2234
2235
  	int retval;
  
  	old_bh = new_bh = dir_bh = NULL;
  
  	/* Initialize quotas before so that eventual writes go
  	 * in separate transaction */
  	if (new_dentry->d_inode)
  		DQUOT_INIT(new_dentry->d_inode);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2236
2237
2238
  	handle = ext4_journal_start(old_dir, 2 *
  					EXT4_DATA_TRANS_BLOCKS(old_dir->i_sb) +
  					EXT4_INDEX_EXTRA_TRANS_BLOCKS + 2);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2239
2240
2241
2242
2243
  	if (IS_ERR(handle))
  		return PTR_ERR(handle);
  
  	if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
  		handle->h_sync = 1;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2244
  	old_bh = ext4_find_entry (old_dentry, &old_de);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
  	/*
  	 *  Check for inode number is _not_ due to possible IO errors.
  	 *  We might rmdir the source, keep it as pwd of some process
  	 *  and merrily kill the link to whatever was created under the
  	 *  same name. Goodbye sticky bit ;-<
  	 */
  	old_inode = old_dentry->d_inode;
  	retval = -ENOENT;
  	if (!old_bh || le32_to_cpu(old_de->inode) != old_inode->i_ino)
  		goto end_rename;
  
  	new_inode = new_dentry->d_inode;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2257
  	new_bh = ext4_find_entry (new_dentry, &new_de);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
  	if (new_bh) {
  		if (!new_inode) {
  			brelse (new_bh);
  			new_bh = NULL;
  		}
  	}
  	if (S_ISDIR(old_inode->i_mode)) {
  		if (new_inode) {
  			retval = -ENOTEMPTY;
  			if (!empty_dir (new_inode))
  				goto end_rename;
  		}
  		retval = -EIO;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2271
  		dir_bh = ext4_bread (handle, old_inode, 0, 0, &retval);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2272
2273
2274
2275
2276
2277
  		if (!dir_bh)
  			goto end_rename;
  		if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino)
  			goto end_rename;
  		retval = -EMLINK;
  		if (!new_inode && new_dir!=old_dir &&
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2278
  				new_dir->i_nlink >= EXT4_LINK_MAX)
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2279
2280
2281
  			goto end_rename;
  	}
  	if (!new_bh) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2282
  		retval = ext4_add_entry (handle, new_dentry, old_inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2283
2284
2285
2286
  		if (retval)
  			goto end_rename;
  	} else {
  		BUFFER_TRACE(new_bh, "get write access");
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2287
  		ext4_journal_get_write_access(handle, new_bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2288
  		new_de->inode = cpu_to_le32(old_inode->i_ino);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2289
2290
  		if (EXT4_HAS_INCOMPAT_FEATURE(new_dir->i_sb,
  					      EXT4_FEATURE_INCOMPAT_FILETYPE))
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2291
2292
  			new_de->file_type = old_de->file_type;
  		new_dir->i_version++;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2293
2294
  		BUFFER_TRACE(new_bh, "call ext4_journal_dirty_metadata");
  		ext4_journal_dirty_metadata(handle, new_bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2295
2296
2297
2298
2299
2300
2301
2302
  		brelse(new_bh);
  		new_bh = NULL;
  	}
  
  	/*
  	 * Like most other Unix systems, set the ctime for inodes on a
  	 * rename.
  	 */
ef7f38359   Kalpak Shah   ext4: Add nanosec...
2303
  	old_inode->i_ctime = ext4_current_time(old_inode);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2304
  	ext4_mark_inode_dirty(handle, old_inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2305
2306
2307
2308
2309
2310
2311
  
  	/*
  	 * ok, that's it
  	 */
  	if (le32_to_cpu(old_de->inode) != old_inode->i_ino ||
  	    old_de->name_len != old_dentry->d_name.len ||
  	    strncmp(old_de->name, old_dentry->d_name.name, old_de->name_len) ||
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2312
  	    (retval = ext4_delete_entry(handle, old_dir,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2313
2314
2315
2316
2317
2318
  					old_de, old_bh)) == -ENOENT) {
  		/* old_de could have moved from under us during htree split, so
  		 * make sure that we are deleting the right entry.  We might
  		 * also be pointing to a stale entry in the unused part of
  		 * old_bh so just checking inum and the name isn't enough. */
  		struct buffer_head *old_bh2;
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2319
  		struct ext4_dir_entry_2 *old_de2;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2320

617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2321
  		old_bh2 = ext4_find_entry(old_dentry, &old_de2);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2322
  		if (old_bh2) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2323
  			retval = ext4_delete_entry(handle, old_dir,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2324
2325
2326
2327
2328
  						   old_de2, old_bh2);
  			brelse(old_bh2);
  		}
  	}
  	if (retval) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2329
  		ext4_warning(old_dir->i_sb, "ext4_rename",
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2330
2331
2332
2333
2334
  				"Deleting old file (%lu), %d, error=%d",
  				old_dir->i_ino, old_dir->i_nlink, retval);
  	}
  
  	if (new_inode) {
f8628a14a   Andreas Dilger   ext4: Remove 6500...
2335
  		ext4_dec_count(handle, new_inode);
ef7f38359   Kalpak Shah   ext4: Add nanosec...
2336
  		new_inode->i_ctime = ext4_current_time(new_inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2337
  	}
ef7f38359   Kalpak Shah   ext4: Add nanosec...
2338
  	old_dir->i_ctime = old_dir->i_mtime = ext4_current_time(old_dir);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2339
  	ext4_update_dx_flag(old_dir);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2340
2341
  	if (dir_bh) {
  		BUFFER_TRACE(dir_bh, "get_write_access");
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2342
  		ext4_journal_get_write_access(handle, dir_bh);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2343
  		PARENT_INO(dir_bh->b_data) = cpu_to_le32(new_dir->i_ino);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2344
2345
  		BUFFER_TRACE(dir_bh, "call ext4_journal_dirty_metadata");
  		ext4_journal_dirty_metadata(handle, dir_bh);
f8628a14a   Andreas Dilger   ext4: Remove 6500...
2346
  		ext4_dec_count(handle, old_dir);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2347
  		if (new_inode) {
f8628a14a   Andreas Dilger   ext4: Remove 6500...
2348
2349
2350
  			/* checked empty_dir above, can't have another parent,
  			 * ext3_dec_count() won't work for many-linked dirs */
  			new_inode->i_nlink = 0;
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2351
  		} else {
f8628a14a   Andreas Dilger   ext4: Remove 6500...
2352
  			ext4_inc_count(handle, new_dir);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2353
2354
  			ext4_update_dx_flag(new_dir);
  			ext4_mark_inode_dirty(handle, new_dir);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2355
2356
  		}
  	}
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2357
  	ext4_mark_inode_dirty(handle, old_dir);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2358
  	if (new_inode) {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2359
  		ext4_mark_inode_dirty(handle, new_inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2360
  		if (!new_inode->i_nlink)
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2361
  			ext4_orphan_add(handle, new_inode);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2362
2363
2364
2365
2366
2367
2368
  	}
  	retval = 0;
  
  end_rename:
  	brelse (dir_bh);
  	brelse (old_bh);
  	brelse (new_bh);
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2369
  	ext4_journal_stop(handle);
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2370
2371
2372
2373
2374
2375
  	return retval;
  }
  
  /*
   * directories can handle most operations...
   */
754661f14   Arjan van de Ven   [PATCH] mark stru...
2376
  const struct inode_operations ext4_dir_inode_operations = {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
  	.create		= ext4_create,
  	.lookup		= ext4_lookup,
  	.link		= ext4_link,
  	.unlink		= ext4_unlink,
  	.symlink	= ext4_symlink,
  	.mkdir		= ext4_mkdir,
  	.rmdir		= ext4_rmdir,
  	.mknod		= ext4_mknod,
  	.rename		= ext4_rename,
  	.setattr	= ext4_setattr,
  #ifdef CONFIG_EXT4DEV_FS_XATTR
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2388
2389
  	.setxattr	= generic_setxattr,
  	.getxattr	= generic_getxattr,
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2390
  	.listxattr	= ext4_listxattr,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2391
2392
  	.removexattr	= generic_removexattr,
  #endif
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2393
  	.permission	= ext4_permission,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2394
  };
754661f14   Arjan van de Ven   [PATCH] mark stru...
2395
  const struct inode_operations ext4_special_inode_operations = {
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2396
2397
  	.setattr	= ext4_setattr,
  #ifdef CONFIG_EXT4DEV_FS_XATTR
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2398
2399
  	.setxattr	= generic_setxattr,
  	.getxattr	= generic_getxattr,
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2400
  	.listxattr	= ext4_listxattr,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2401
2402
  	.removexattr	= generic_removexattr,
  #endif
617ba13b3   Mingming Cao   [PATCH] ext4: ren...
2403
  	.permission	= ext4_permission,
ac27a0ec1   Dave Kleikamp   [PATCH] ext4: ini...
2404
  };