dir.c 18.5 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
 *  linux/fs/ext4/dir.c
4 5 6 7 8 9 10 11 12 13 14 15
 *
 * 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/dir.c
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 *
16
 *  ext4 directory handling functions
17 18 19 20 21 22 23 24 25 26 27
 *
 *  Big-endian to little-endian byte-swapping/bitmaps by
 *        David S. Miller (davem@caip.rutgers.edu), 1995
 *
 * Hash Tree Directory indexing (c) 2001  Daniel Phillips
 *
 */

#include <linux/fs.h>
#include <linux/buffer_head.h>
#include <linux/slab.h>
J
Jeff Layton 已提交
28
#include <linux/iversion.h>
29
#include <linux/unicode.h>
30
#include "ext4.h"
T
Tao Ma 已提交
31
#include "xattr.h"
32

A
Al Viro 已提交
33
static int ext4_dx_readdir(struct file *, struct dir_context *);
34

35
/**
36 37 38
 * is_dx_dir() - check if a directory is using htree indexing
 * @inode: directory inode
 *
39
 * Check if the given dir-inode refers to an htree-indexed directory
40
 * (or a directory which could potentially get converted to use htree
41 42 43 44 45 46 47 48
 * indexing).
 *
 * Return 1 if it is a dx dir, 0 if not
 */
static int is_dx_dir(struct inode *inode)
{
	struct super_block *sb = inode->i_sb;

49
	if (ext4_has_feature_dir_index(inode->i_sb) &&
50
	    ((ext4_test_inode_flag(inode, EXT4_INODE_INDEX)) ||
51 52
	     ((inode->i_size >> sb->s_blocksize_bits) == 1) ||
	     ext4_has_inline_data(inode)))
53 54 55 56 57
		return 1;

	return 0;
}

58 59 60 61
/*
 * Return 0 if the directory entry is OK, and 1 if there is a problem
 *
 * Note: this is the opposite of what ext2 and ext3 historically returned...
T
Tao Ma 已提交
62 63 64
 *
 * bh passed here can be an inode block or a dir data block, depending
 * on the inode inline data flag.
65
 */
66
int __ext4_check_dir_entry(const char *function, unsigned int line,
67
			   struct inode *dir, struct file *filp,
68
			   struct ext4_dir_entry_2 *de,
69
			   struct buffer_head *bh, char *buf, int size,
70
			   unsigned int offset)
71
{
72
	const char *error_msg = NULL;
73 74
	const int rlen = ext4_rec_len_from_disk(de->rec_len,
						dir->i_sb->s_blocksize);
75
	const int next_offset = ((char *) de - buf) + rlen;
76

77
	if (unlikely(rlen < EXT4_DIR_REC_LEN(1)))
78
		error_msg = "rec_len is smaller than minimal";
79
	else if (unlikely(rlen % 4 != 0))
80
		error_msg = "rec_len % 4 != 0";
81
	else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len)))
82
		error_msg = "rec_len is too small for name_len";
83
	else if (unlikely(next_offset > size))
84
		error_msg = "directory entry overrun";
85 86
	else if (unlikely(next_offset > size - EXT4_DIR_REC_LEN(1) &&
			  next_offset != size))
87
		error_msg = "directory entry too close to block end";
88 89
	else if (unlikely(le32_to_cpu(de->inode) >
			le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count)))
90
		error_msg = "inode out of bounds";
91 92 93
	else
		return 0;

94
	if (filp)
95
		ext4_error_file(filp, function, line, bh->b_blocknr,
96 97 98 99
				"bad entry in directory: %s - offset=%u, "
				"inode=%u, rec_len=%d, name_len=%d, size=%d",
				error_msg, offset, le32_to_cpu(de->inode),
				rlen, de->name_len, size);
100
	else
101
		ext4_error_inode(dir, function, line, bh->b_blocknr,
102 103 104 105
				"bad entry in directory: %s - offset=%u, "
				"inode=%u, rec_len=%d, name_len=%d, size=%d",
				 error_msg, offset, le32_to_cpu(de->inode),
				 rlen, de->name_len, size);
106

107
	return 1;
108 109
}

A
Al Viro 已提交
110
static int ext4_readdir(struct file *file, struct dir_context *ctx)
111
{
112
	unsigned int offset;
113
	int i;
114
	struct ext4_dir_entry_2 *de;
115
	int err;
A
Al Viro 已提交
116
	struct inode *inode = file_inode(file);
117
	struct super_block *sb = inode->i_sb;
118
	struct buffer_head *bh = NULL;
119
	struct fscrypt_str fstr = FSTR_INIT(NULL, 0);
120

121
	if (IS_ENCRYPTED(inode)) {
122
		err = fscrypt_get_encryption_info(inode);
123
		if (err)
124 125 126
			return err;
	}

127
	if (is_dx_dir(inode)) {
A
Al Viro 已提交
128
		err = ext4_dx_readdir(file, ctx);
129
		if (err != ERR_BAD_DX_DIR) {
A
Al Viro 已提交
130
			return err;
131
		}
132 133 134 135 136 137 138 139
		/* Can we just clear INDEX flag to ignore htree information? */
		if (!ext4_has_metadata_csum(sb)) {
			/*
			 * We don't set the inode dirty flag since it's not
			 * critical that it gets flushed back to the disk.
			 */
			ext4_clear_inode_flag(inode, EXT4_INODE_INDEX);
		}
140
	}
141 142 143

	if (ext4_has_inline_data(inode)) {
		int has_inline_data = 1;
144
		err = ext4_read_inline_dir(file, ctx,
145 146
					   &has_inline_data);
		if (has_inline_data)
147 148 149
			return err;
	}

150
	if (IS_ENCRYPTED(inode)) {
151
		err = fscrypt_fname_alloc_buffer(inode, EXT4_NAME_LEN, &fstr);
152
		if (err < 0)
153
			return err;
154 155
	}

A
Al Viro 已提交
156
	while (ctx->pos < inode->i_size) {
157
		struct ext4_map_blocks map;
158

159 160 161 162 163
		if (fatal_signal_pending(current)) {
			err = -ERESTARTSYS;
			goto errout;
		}
		cond_resched();
T
Theodore Ts'o 已提交
164
		offset = ctx->pos & (sb->s_blocksize - 1);
A
Al Viro 已提交
165
		map.m_lblk = ctx->pos >> EXT4_BLOCK_SIZE_BITS(sb);
166 167
		map.m_len = 1;
		err = ext4_map_blocks(NULL, inode, &map, 0);
T
Theodore Ts'o 已提交
168 169 170 171 172 173 174 175
		if (err == 0) {
			/* m_len should never be zero but let's avoid
			 * an infinite loop if it somehow is */
			if (map.m_len == 0)
				map.m_len = 1;
			ctx->pos += map.m_len * sb->s_blocksize;
			continue;
		}
176
		if (err > 0) {
177
			pgoff_t index = map.m_pblk >>
178
					(PAGE_SHIFT - inode->i_blkbits);
A
Al Viro 已提交
179
			if (!ra_has_index(&file->f_ra, index))
180
				page_cache_sync_readahead(
181
					sb->s_bdev->bd_inode->i_mapping,
A
Al Viro 已提交
182
					&file->f_ra, file,
183
					index, 1);
184
			file->f_ra.prev_pos = (loff_t)index << PAGE_SHIFT;
185
			bh = ext4_bread(NULL, inode, map.m_lblk, 0);
186 187 188 189 190
			if (IS_ERR(bh)) {
				err = PTR_ERR(bh);
				bh = NULL;
				goto errout;
			}
191 192 193
		}

		if (!bh) {
194
			/* corrupt size?  Maybe no more blocks to read */
A
Al Viro 已提交
195
			if (ctx->pos > inode->i_blocks << 9)
196
				break;
A
Al Viro 已提交
197
			ctx->pos += sb->s_blocksize - offset;
198 199 200
			continue;
		}

201 202
		/* Check the checksum */
		if (!buffer_verified(bh) &&
203
		    !ext4_dirblock_csum_verify(inode, bh)) {
A
Al Viro 已提交
204
			EXT4_ERROR_FILE(file, 0, "directory fails checksum "
205
					"at offset %llu",
A
Al Viro 已提交
206 207
					(unsigned long long)ctx->pos);
			ctx->pos += sb->s_blocksize - offset;
208
			brelse(bh);
209
			bh = NULL;
210 211 212 213
			continue;
		}
		set_buffer_verified(bh);

214 215 216 217
		/* If the dir block has changed since the last call to
		 * readdir(2), then we might be pointing to an invalid
		 * dirent right now.  Scan from the start of the block
		 * to make sure. */
218
		if (!inode_eq_iversion(inode, file->f_version)) {
219
			for (i = 0; i < sb->s_blocksize && i < offset; ) {
220
				de = (struct ext4_dir_entry_2 *)
221 222 223 224 225 226 227
					(bh->b_data + i);
				/* It's too expensive to do a full
				 * dirent test each time round this
				 * loop, but we do have to test at
				 * least that it is non-zero.  A
				 * failure will be detected in the
				 * dirent test below. */
228 229
				if (ext4_rec_len_from_disk(de->rec_len,
					sb->s_blocksize) < EXT4_DIR_REC_LEN(1))
230
					break;
231 232
				i += ext4_rec_len_from_disk(de->rec_len,
							    sb->s_blocksize);
233 234
			}
			offset = i;
A
Al Viro 已提交
235
			ctx->pos = (ctx->pos & ~(sb->s_blocksize - 1))
236
				| offset;
J
Jeff Layton 已提交
237
			file->f_version = inode_query_iversion(inode);
238 239
		}

A
Al Viro 已提交
240
		while (ctx->pos < inode->i_size
241
		       && offset < sb->s_blocksize) {
242
			de = (struct ext4_dir_entry_2 *) (bh->b_data + offset);
A
Al Viro 已提交
243
			if (ext4_check_dir_entry(inode, file, de, bh,
244 245
						 bh->b_data, bh->b_size,
						 offset)) {
A
Andrew Morton 已提交
246
				/*
A
Al Viro 已提交
247
				 * On error, skip to the next block
A
Andrew Morton 已提交
248
				 */
A
Al Viro 已提交
249
				ctx->pos = (ctx->pos |
250
						(sb->s_blocksize - 1)) + 1;
A
Al Viro 已提交
251
				break;
252
			}
253 254
			offset += ext4_rec_len_from_disk(de->rec_len,
					sb->s_blocksize);
255
			if (le32_to_cpu(de->inode)) {
256
				if (!IS_ENCRYPTED(inode)) {
257 258 259 260 261 262
					if (!dir_emit(ctx, de->name,
					    de->name_len,
					    le32_to_cpu(de->inode),
					    get_dtype(sb, de->file_type)))
						goto done;
				} else {
263 264 265 266
					int save_len = fstr.len;
					struct fscrypt_str de_name =
							FSTR_INIT(de->name,
								de->name_len);
267

268
					/* Directory is encrypted */
269 270
					err = fscrypt_fname_disk_to_usr(inode,
						0, 0, &de_name, &fstr);
271
					de_name = fstr;
272
					fstr.len = save_len;
273
					if (err)
274 275
						goto errout;
					if (!dir_emit(ctx,
276
					    de_name.name, de_name.len,
277 278 279
					    le32_to_cpu(de->inode),
					    get_dtype(sb, de->file_type)))
						goto done;
A
Al Viro 已提交
280
				}
281
			}
A
Al Viro 已提交
282
			ctx->pos += ext4_rec_len_from_disk(de->rec_len,
283
						sb->s_blocksize);
284
		}
A
Al Viro 已提交
285
		if ((ctx->pos < inode->i_size) && !dir_relax_shared(inode))
286
			goto done;
287
		brelse(bh);
288 289
		bh = NULL;
		offset = 0;
290
	}
291 292 293
done:
	err = 0;
errout:
294
	fscrypt_fname_free_buffer(&fstr);
295 296
	brelse(bh);
	return err;
297 298
}

299 300 301
static inline int is_32bit_api(void)
{
#ifdef CONFIG_COMPAT
302
	return in_compat_syscall();
303 304 305 306 307
#else
	return (BITS_PER_LONG == 32);
#endif
}

308 309
/*
 * These functions convert from the major/minor hash to an f_pos
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 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
 * value for dx directories
 *
 * Upper layer (for example NFS) should specify FMODE_32BITHASH or
 * FMODE_64BITHASH explicitly. On the other hand, we allow ext4 to be mounted
 * directly on both 32-bit and 64-bit nodes, under such case, neither
 * FMODE_32BITHASH nor FMODE_64BITHASH is specified.
 */
static inline loff_t hash2pos(struct file *filp, __u32 major, __u32 minor)
{
	if ((filp->f_mode & FMODE_32BITHASH) ||
	    (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api()))
		return major >> 1;
	else
		return ((__u64)(major >> 1) << 32) | (__u64)minor;
}

static inline __u32 pos2maj_hash(struct file *filp, loff_t pos)
{
	if ((filp->f_mode & FMODE_32BITHASH) ||
	    (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api()))
		return (pos << 1) & 0xffffffff;
	else
		return ((pos >> 32) << 1) & 0xffffffff;
}

static inline __u32 pos2min_hash(struct file *filp, loff_t pos)
{
	if ((filp->f_mode & FMODE_32BITHASH) ||
	    (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api()))
		return 0;
	else
		return pos & 0xffffffff;
}

/*
 * Return 32- or 64-bit end-of-file for dx directories
 */
static inline loff_t ext4_get_htree_eof(struct file *filp)
{
	if ((filp->f_mode & FMODE_32BITHASH) ||
	    (!(filp->f_mode & FMODE_64BITHASH) && is_32bit_api()))
		return EXT4_HTREE_EOF_32BIT;
	else
		return EXT4_HTREE_EOF_64BIT;
}


/*
358 359 360
 * ext4_dir_llseek() calls generic_file_llseek_size to handle htree
 * directories, where the "offset" is in terms of the filename hash
 * value instead of the byte offset.
361
 *
362 363 364 365 366
 * Because we may return a 64-bit hash that is well beyond offset limits,
 * we need to pass the max hash as the maximum allowable offset in
 * the htree directory case.
 *
 * For non-htree, ext4_llseek already chooses the proper max offset.
367
 */
368
static loff_t ext4_dir_llseek(struct file *file, loff_t offset, int whence)
369 370 371
{
	struct inode *inode = file->f_mapping->host;
	int dx_dir = is_dx_dir(inode);
372
	loff_t ret, htree_max = ext4_get_htree_eof(file);
373

374
	if (likely(dx_dir))
375
		ret = generic_file_llseek_size(file, offset, whence,
376 377
						    htree_max, htree_max);
	else
378 379 380
		ret = ext4_llseek(file, offset, whence);
	file->f_version = inode_peek_iversion(inode) - 1;
	return ret;
381
}
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403

/*
 * This structure holds the nodes of the red-black tree used to store
 * the directory entry in hash order.
 */
struct fname {
	__u32		hash;
	__u32		minor_hash;
	struct rb_node	rb_hash;
	struct fname	*next;
	__u32		inode;
	__u8		name_len;
	__u8		file_type;
	char		name[0];
};

/*
 * This functoin implements a non-recursive way of freeing all of the
 * nodes in the red-black tree.
 */
static void free_rb_tree_fname(struct rb_root *root)
{
404 405 406
	struct fname *fname, *next;

	rbtree_postorder_for_each_entry_safe(fname, next, root, rb_hash)
407
		while (fname) {
408
			struct fname *old = fname;
409
			fname = fname->next;
410
			kfree(old);
411
		}
412 413

	*root = RB_ROOT;
414 415 416
}


417 418
static struct dir_private_info *ext4_htree_create_dir_info(struct file *filp,
							   loff_t pos)
419 420 421
{
	struct dir_private_info *p;

M
Markus Elfring 已提交
422
	p = kzalloc(sizeof(*p), GFP_KERNEL);
423 424
	if (!p)
		return NULL;
425 426
	p->curr_hash = pos2maj_hash(filp, pos);
	p->curr_minor_hash = pos2min_hash(filp, pos);
427 428 429
	return p;
}

430
void ext4_htree_free_dir_info(struct dir_private_info *p)
431 432 433 434 435 436 437
{
	free_rb_tree_fname(&p->root);
	kfree(p);
}

/*
 * Given a directory entry, enter it into the fname rb tree.
438 439 440 441
 *
 * When filename encryption is enabled, the dirent will hold the
 * encrypted filename, while the htree will hold decrypted filename.
 * The decrypted filename is passed in via ent_name.  parameter.
442
 */
443
int ext4_htree_store_dirent(struct file *dir_file, __u32 hash,
444
			     __u32 minor_hash,
445
			    struct ext4_dir_entry_2 *dirent,
446
			    struct fscrypt_str *ent_name)
447 448
{
	struct rb_node **p, *parent = NULL;
449
	struct fname *fname, *new_fn;
450 451 452
	struct dir_private_info *info;
	int len;

453
	info = dir_file->private_data;
454 455 456
	p = &info->root.rb_node;

	/* Create and allocate the fname structure */
457
	len = sizeof(struct fname) + ent_name->len + 1;
458 459 460 461 462 463
	new_fn = kzalloc(len, GFP_KERNEL);
	if (!new_fn)
		return -ENOMEM;
	new_fn->hash = hash;
	new_fn->minor_hash = minor_hash;
	new_fn->inode = le32_to_cpu(dirent->inode);
464
	new_fn->name_len = ent_name->len;
465
	new_fn->file_type = dirent->file_type;
466
	memcpy(new_fn->name, ent_name->name, ent_name->len);
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

	while (*p) {
		parent = *p;
		fname = rb_entry(parent, struct fname, rb_hash);

		/*
		 * If the hash and minor hash match up, then we put
		 * them on a linked list.  This rarely happens...
		 */
		if ((new_fn->hash == fname->hash) &&
		    (new_fn->minor_hash == fname->minor_hash)) {
			new_fn->next = fname->next;
			fname->next = new_fn;
			return 0;
		}

		if (new_fn->hash < fname->hash)
			p = &(*p)->rb_left;
		else if (new_fn->hash > fname->hash)
			p = &(*p)->rb_right;
		else if (new_fn->minor_hash < fname->minor_hash)
			p = &(*p)->rb_left;
		else /* if (new_fn->minor_hash > fname->minor_hash) */
			p = &(*p)->rb_right;
	}

	rb_link_node(&new_fn->rb_hash, parent, p);
	rb_insert_color(&new_fn->rb_hash, &info->root);
	return 0;
}



/*
501
 * This is a helper function for ext4_dx_readdir.  It calls filldir
502 503 504
 * for all entres on the fname linked list.  (Normally there is only
 * one entry on the linked list, unless there are 62 bit hash collisions.)
 */
A
Al Viro 已提交
505 506
static int call_filldir(struct file *file, struct dir_context *ctx,
			struct fname *fname)
507
{
A
Al Viro 已提交
508 509 510
	struct dir_private_info *info = file->private_data;
	struct inode *inode = file_inode(file);
	struct super_block *sb = inode->i_sb;
511 512

	if (!fname) {
513 514 515
		ext4_msg(sb, KERN_ERR, "%s:%d: inode #%lu: comm %s: "
			 "called with null fname?!?", __func__, __LINE__,
			 inode->i_ino, current->comm);
516 517
		return 0;
	}
A
Al Viro 已提交
518
	ctx->pos = hash2pos(file, fname->hash, fname->minor_hash);
519
	while (fname) {
A
Al Viro 已提交
520 521
		if (!dir_emit(ctx, fname->name,
				fname->name_len,
522
				fname->inode,
A
Al Viro 已提交
523
				get_dtype(sb, fname->file_type))) {
524
			info->extra_fname = fname;
A
Al Viro 已提交
525
			return 1;
526 527 528 529 530 531
		}
		fname = fname->next;
	}
	return 0;
}

A
Al Viro 已提交
532
static int ext4_dx_readdir(struct file *file, struct dir_context *ctx)
533
{
A
Al Viro 已提交
534 535
	struct dir_private_info *info = file->private_data;
	struct inode *inode = file_inode(file);
536 537 538 539
	struct fname *fname;
	int	ret;

	if (!info) {
A
Al Viro 已提交
540
		info = ext4_htree_create_dir_info(file, ctx->pos);
541 542
		if (!info)
			return -ENOMEM;
A
Al Viro 已提交
543
		file->private_data = info;
544 545
	}

A
Al Viro 已提交
546
	if (ctx->pos == ext4_get_htree_eof(file))
547 548 549
		return 0;	/* EOF */

	/* Some one has messed with f_pos; reset the world */
A
Al Viro 已提交
550
	if (info->last_pos != ctx->pos) {
551 552 553
		free_rb_tree_fname(&info->root);
		info->curr_node = NULL;
		info->extra_fname = NULL;
A
Al Viro 已提交
554 555
		info->curr_hash = pos2maj_hash(file, ctx->pos);
		info->curr_minor_hash = pos2min_hash(file, ctx->pos);
556 557 558 559 560 561
	}

	/*
	 * If there are any leftover names on the hash collision
	 * chain, return them first.
	 */
562
	if (info->extra_fname) {
A
Al Viro 已提交
563
		if (call_filldir(file, ctx, info->extra_fname))
564 565
			goto finished;
		info->extra_fname = NULL;
566
		goto next_node;
567
	} else if (!info->curr_node)
568 569 570 571 572 573 574 575 576
		info->curr_node = rb_first(&info->root);

	while (1) {
		/*
		 * Fill the rbtree if we have no more entries,
		 * or the inode has changed since we last read in the
		 * cached entries.
		 */
		if ((!info->curr_node) ||
577
		    !inode_eq_iversion(inode, file->f_version)) {
578 579
			info->curr_node = NULL;
			free_rb_tree_fname(&info->root);
J
Jeff Layton 已提交
580
			file->f_version = inode_query_iversion(inode);
A
Al Viro 已提交
581
			ret = ext4_htree_fill_tree(file, info->curr_hash,
582 583 584 585 586
						   info->curr_minor_hash,
						   &info->next_hash);
			if (ret < 0)
				return ret;
			if (ret == 0) {
A
Al Viro 已提交
587
				ctx->pos = ext4_get_htree_eof(file);
588 589 590 591 592 593 594 595
				break;
			}
			info->curr_node = rb_first(&info->root);
		}

		fname = rb_entry(info->curr_node, struct fname, rb_hash);
		info->curr_hash = fname->hash;
		info->curr_minor_hash = fname->minor_hash;
A
Al Viro 已提交
596
		if (call_filldir(file, ctx, fname))
597
			break;
598
	next_node:
599
		info->curr_node = rb_next(info->curr_node);
600 601 602 603 604 605
		if (info->curr_node) {
			fname = rb_entry(info->curr_node, struct fname,
					 rb_hash);
			info->curr_hash = fname->hash;
			info->curr_minor_hash = fname->minor_hash;
		} else {
606
			if (info->next_hash == ~0) {
A
Al Viro 已提交
607
				ctx->pos = ext4_get_htree_eof(file);
608 609 610 611 612 613 614
				break;
			}
			info->curr_hash = info->next_hash;
			info->curr_minor_hash = 0;
		}
	}
finished:
A
Al Viro 已提交
615
	info->last_pos = ctx->pos;
616 617 618
	return 0;
}

619 620
static int ext4_dir_open(struct inode * inode, struct file * filp)
{
621
	if (IS_ENCRYPTED(inode))
622
		return fscrypt_get_encryption_info(inode) ? -EACCES : 0;
623 624 625
	return 0;
}

626
static int ext4_release_dir(struct inode *inode, struct file *filp)
627
{
A
Andrew Morton 已提交
628
	if (filp->private_data)
629
		ext4_htree_free_dir_info(filp->private_data);
630 631 632

	return 0;
}
633

634 635 636 637
int ext4_check_all_de(struct inode *dir, struct buffer_head *bh, void *buf,
		      int buf_size)
{
	struct ext4_dir_entry_2 *de;
E
Eric Engestrom 已提交
638
	int rlen;
639 640 641 642 643 644 645 646
	unsigned int offset = 0;
	char *top;

	de = (struct ext4_dir_entry_2 *)buf;
	top = buf + buf_size;
	while ((char *) de < top) {
		if (ext4_check_dir_entry(dir, NULL, de, bh,
					 buf, buf_size, offset))
647
			return -EFSCORRUPTED;
648 649 650 651 652
		rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
		de = (struct ext4_dir_entry_2 *)((char *)de + rlen);
		offset += rlen;
	}
	if ((char *) de > top)
653
		return -EFSCORRUPTED;
654 655 656 657

	return 0;
}

658 659 660
const struct file_operations ext4_dir_operations = {
	.llseek		= ext4_dir_llseek,
	.read		= generic_read_dir,
A
Al Viro 已提交
661
	.iterate_shared	= ext4_readdir,
662 663 664 665 666
	.unlocked_ioctl = ext4_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= ext4_compat_ioctl,
#endif
	.fsync		= ext4_sync_file,
667
	.open		= ext4_dir_open,
668 669
	.release	= ext4_release_dir,
};
670 671 672 673 674 675

#ifdef CONFIG_UNICODE
static int ext4_d_compare(const struct dentry *dentry, unsigned int len,
			  const char *str, const struct qstr *name)
{
	struct qstr qstr = {.name = str, .len = len };
676 677
	const struct dentry *parent = READ_ONCE(dentry->d_parent);
	const struct inode *inode = READ_ONCE(parent->d_inode);
678

679 680
	if (!inode || !IS_CASEFOLDED(inode) ||
	    !EXT4_SB(inode->i_sb)->s_encoding) {
681 682
		if (len != name->len)
			return -1;
683
		return memcmp(str, name->name, len);
684 685
	}

686
	return ext4_ci_compare(inode, name, &qstr, false);
687 688 689 690 691 692
}

static int ext4_d_hash(const struct dentry *dentry, struct qstr *str)
{
	const struct ext4_sb_info *sbi = EXT4_SB(dentry->d_sb);
	const struct unicode_map *um = sbi->s_encoding;
693
	const struct inode *inode = READ_ONCE(dentry->d_inode);
694 695 696
	unsigned char *norm;
	int len, ret = 0;

697
	if (!inode || !IS_CASEFOLDED(inode) || !um)
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720
		return 0;

	norm = kmalloc(PATH_MAX, GFP_ATOMIC);
	if (!norm)
		return -ENOMEM;

	len = utf8_casefold(um, str, norm, PATH_MAX);
	if (len < 0) {
		if (ext4_has_strict_mode(sbi))
			ret = -EINVAL;
		goto out;
	}
	str->hash = full_name_hash(dentry, norm, len);
out:
	kfree(norm);
	return ret;
}

const struct dentry_operations ext4_dentry_ops = {
	.d_hash = ext4_d_hash,
	.d_compare = ext4_d_compare,
};
#endif