| .. | .. |
|---|
| 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) |
|---|