| .. | .. | 
|---|
| 252 | 252 | return (char *)p - base; | 
|---|
| 253 | 253 | } | 
|---|
| 254 | 254 |  | 
|---|
| 255 |  | -static unsigned char ext2_filetype_table[EXT2_FT_MAX] = { | 
|---|
| 256 |  | -	[EXT2_FT_UNKNOWN]	= DT_UNKNOWN, | 
|---|
| 257 |  | -	[EXT2_FT_REG_FILE]	= DT_REG, | 
|---|
| 258 |  | -	[EXT2_FT_DIR]		= DT_DIR, | 
|---|
| 259 |  | -	[EXT2_FT_CHRDEV]	= DT_CHR, | 
|---|
| 260 |  | -	[EXT2_FT_BLKDEV]	= DT_BLK, | 
|---|
| 261 |  | -	[EXT2_FT_FIFO]		= DT_FIFO, | 
|---|
| 262 |  | -	[EXT2_FT_SOCK]		= DT_SOCK, | 
|---|
| 263 |  | -	[EXT2_FT_SYMLINK]	= DT_LNK, | 
|---|
| 264 |  | -}; | 
|---|
| 265 |  | - | 
|---|
| 266 |  | -#define S_SHIFT 12 | 
|---|
| 267 |  | -static unsigned char ext2_type_by_mode[S_IFMT >> S_SHIFT] = { | 
|---|
| 268 |  | -	[S_IFREG >> S_SHIFT]	= EXT2_FT_REG_FILE, | 
|---|
| 269 |  | -	[S_IFDIR >> S_SHIFT]	= EXT2_FT_DIR, | 
|---|
| 270 |  | -	[S_IFCHR >> S_SHIFT]	= EXT2_FT_CHRDEV, | 
|---|
| 271 |  | -	[S_IFBLK >> S_SHIFT]	= EXT2_FT_BLKDEV, | 
|---|
| 272 |  | -	[S_IFIFO >> S_SHIFT]	= EXT2_FT_FIFO, | 
|---|
| 273 |  | -	[S_IFSOCK >> S_SHIFT]	= EXT2_FT_SOCK, | 
|---|
| 274 |  | -	[S_IFLNK >> S_SHIFT]	= EXT2_FT_SYMLINK, | 
|---|
| 275 |  | -}; | 
|---|
| 276 |  | - | 
|---|
| 277 | 255 | static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode) | 
|---|
| 278 | 256 | { | 
|---|
| 279 |  | -	umode_t mode = inode->i_mode; | 
|---|
| 280 | 257 | if (EXT2_HAS_INCOMPAT_FEATURE(inode->i_sb, EXT2_FEATURE_INCOMPAT_FILETYPE)) | 
|---|
| 281 |  | -		de->file_type = ext2_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; | 
|---|
|  | 258 | +		de->file_type = fs_umode_to_ftype(inode->i_mode); | 
|---|
| 282 | 259 | else | 
|---|
| 283 | 260 | de->file_type = 0; | 
|---|
| 284 | 261 | } | 
|---|
| .. | .. | 
|---|
| 293 | 270 | unsigned long n = pos >> PAGE_SHIFT; | 
|---|
| 294 | 271 | unsigned long npages = dir_pages(inode); | 
|---|
| 295 | 272 | unsigned chunk_mask = ~(ext2_chunk_size(inode)-1); | 
|---|
| 296 |  | -	unsigned char *types = NULL; | 
|---|
| 297 | 273 | bool need_revalidate = !inode_eq_iversion(inode, file->f_version); | 
|---|
|  | 274 | +	bool has_filetype; | 
|---|
| 298 | 275 |  | 
|---|
| 299 | 276 | if (pos > inode->i_size - EXT2_DIR_REC_LEN(1)) | 
|---|
| 300 | 277 | return 0; | 
|---|
| 301 | 278 |  | 
|---|
| 302 |  | -	if (EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE)) | 
|---|
| 303 |  | -		types = ext2_filetype_table; | 
|---|
|  | 279 | +	has_filetype = | 
|---|
|  | 280 | +		EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE); | 
|---|
| 304 | 281 |  | 
|---|
| 305 | 282 | for ( ; n < npages; n++, offset = 0) { | 
|---|
| 306 | 283 | char *kaddr, *limit; | 
|---|
| .. | .. | 
|---|
| 335 | 312 | if (de->inode) { | 
|---|
| 336 | 313 | unsigned char d_type = DT_UNKNOWN; | 
|---|
| 337 | 314 |  | 
|---|
| 338 |  | -				if (types && de->file_type < EXT2_FT_MAX) | 
|---|
| 339 |  | -					d_type = types[de->file_type]; | 
|---|
|  | 315 | +				if (has_filetype) | 
|---|
|  | 316 | +					d_type = fs_ftype_to_dtype(de->file_type); | 
|---|
| 340 | 317 |  | 
|---|
| 341 | 318 | if (!dir_emit(ctx, de->name, de->name_len, | 
|---|
| 342 | 319 | le32_to_cpu(de->inode), | 
|---|
| .. | .. | 
|---|
| 371 | 348 | struct page *page = NULL; | 
|---|
| 372 | 349 | struct ext2_inode_info *ei = EXT2_I(dir); | 
|---|
| 373 | 350 | ext2_dirent * de; | 
|---|
| 374 |  | -	int dir_has_error = 0; | 
|---|
| 375 | 351 |  | 
|---|
| 376 | 352 | if (npages == 0) | 
|---|
| 377 | 353 | goto out; | 
|---|
| .. | .. | 
|---|
| 385 | 361 | n = start; | 
|---|
| 386 | 362 | do { | 
|---|
| 387 | 363 | char *kaddr; | 
|---|
| 388 |  | -		page = ext2_get_page(dir, n, dir_has_error); | 
|---|
| 389 |  | -		if (!IS_ERR(page)) { | 
|---|
| 390 |  | -			kaddr = page_address(page); | 
|---|
| 391 |  | -			de = (ext2_dirent *) kaddr; | 
|---|
| 392 |  | -			kaddr += ext2_last_byte(dir, n) - reclen; | 
|---|
| 393 |  | -			while ((char *) de <= kaddr) { | 
|---|
| 394 |  | -				if (de->rec_len == 0) { | 
|---|
| 395 |  | -					ext2_error(dir->i_sb, __func__, | 
|---|
| 396 |  | -						"zero-length directory entry"); | 
|---|
| 397 |  | -					ext2_put_page(page); | 
|---|
| 398 |  | -					goto out; | 
|---|
| 399 |  | -				} | 
|---|
| 400 |  | -				if (ext2_match (namelen, name, de)) | 
|---|
| 401 |  | -					goto found; | 
|---|
| 402 |  | -				de = ext2_next_entry(de); | 
|---|
|  | 364 | +		page = ext2_get_page(dir, n, 0); | 
|---|
|  | 365 | +		if (IS_ERR(page)) | 
|---|
|  | 366 | +			return ERR_CAST(page); | 
|---|
|  | 367 | + | 
|---|
|  | 368 | +		kaddr = page_address(page); | 
|---|
|  | 369 | +		de = (ext2_dirent *) kaddr; | 
|---|
|  | 370 | +		kaddr += ext2_last_byte(dir, n) - reclen; | 
|---|
|  | 371 | +		while ((char *) de <= kaddr) { | 
|---|
|  | 372 | +			if (de->rec_len == 0) { | 
|---|
|  | 373 | +				ext2_error(dir->i_sb, __func__, | 
|---|
|  | 374 | +					"zero-length directory entry"); | 
|---|
|  | 375 | +				ext2_put_page(page); | 
|---|
|  | 376 | +				goto out; | 
|---|
| 403 | 377 | } | 
|---|
| 404 |  | -			ext2_put_page(page); | 
|---|
| 405 |  | -		} else | 
|---|
| 406 |  | -			dir_has_error = 1; | 
|---|
|  | 378 | +			if (ext2_match(namelen, name, de)) | 
|---|
|  | 379 | +				goto found; | 
|---|
|  | 380 | +			de = ext2_next_entry(de); | 
|---|
|  | 381 | +		} | 
|---|
|  | 382 | +		ext2_put_page(page); | 
|---|
| 407 | 383 |  | 
|---|
| 408 | 384 | if (++n >= npages) | 
|---|
| 409 | 385 | n = 0; | 
|---|
| .. | .. | 
|---|
| 417 | 393 | } | 
|---|
| 418 | 394 | } while (n != start); | 
|---|
| 419 | 395 | out: | 
|---|
| 420 |  | -	return NULL; | 
|---|
|  | 396 | +	return ERR_PTR(-ENOENT); | 
|---|
| 421 | 397 |  | 
|---|
| 422 | 398 | found: | 
|---|
| 423 | 399 | *res_page = page; | 
|---|
| .. | .. | 
|---|
| 437 | 413 | return de; | 
|---|
| 438 | 414 | } | 
|---|
| 439 | 415 |  | 
|---|
| 440 |  | -ino_t ext2_inode_by_name(struct inode *dir, const struct qstr *child) | 
|---|
|  | 416 | +int ext2_inode_by_name(struct inode *dir, const struct qstr *child, ino_t *ino) | 
|---|
| 441 | 417 | { | 
|---|
| 442 |  | -	ino_t res = 0; | 
|---|
| 443 | 418 | struct ext2_dir_entry_2 *de; | 
|---|
| 444 | 419 | struct page *page; | 
|---|
| 445 | 420 |  | 
|---|
| 446 |  | -	de = ext2_find_entry (dir, child, &page); | 
|---|
| 447 |  | -	if (de) { | 
|---|
| 448 |  | -		res = le32_to_cpu(de->inode); | 
|---|
| 449 |  | -		ext2_put_page(page); | 
|---|
| 450 |  | -	} | 
|---|
| 451 |  | -	return res; | 
|---|
|  | 421 | +	de = ext2_find_entry(dir, child, &page); | 
|---|
|  | 422 | +	if (IS_ERR(de)) | 
|---|
|  | 423 | +		return PTR_ERR(de); | 
|---|
|  | 424 | + | 
|---|
|  | 425 | +	*ino = le32_to_cpu(de->inode); | 
|---|
|  | 426 | +	ext2_put_page(page); | 
|---|
|  | 427 | +	return 0; | 
|---|
| 452 | 428 | } | 
|---|
| 453 | 429 |  | 
|---|
| 454 | 430 | static int ext2_prepare_chunk(struct page *page, loff_t pos, unsigned len) | 
|---|