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