dir.c (ea68a3e9d14e9e0bf017d178fb4bd53b6deb1482) | dir.c (3acea5fc335420ba7ef53947cf2d98d07fac39f7) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2017-2018 HUAWEI, Inc. 4 * https://www.huawei.com/ 5 * Copyright (C) 2022, Alibaba Cloud 6 */ 7#include "internal.h" 8 --- 36 unchanged lines hidden (view full) --- 45 } 46 return 0; 47} 48 49static int erofs_readdir(struct file *f, struct dir_context *ctx) 50{ 51 struct inode *dir = file_inode(f); 52 struct erofs_buf buf = __EROFS_BUF_INITIALIZER; | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2017-2018 HUAWEI, Inc. 4 * https://www.huawei.com/ 5 * Copyright (C) 2022, Alibaba Cloud 6 */ 7#include "internal.h" 8 --- 36 unchanged lines hidden (view full) --- 45 } 46 return 0; 47} 48 49static int erofs_readdir(struct file *f, struct dir_context *ctx) 50{ 51 struct inode *dir = file_inode(f); 52 struct erofs_buf buf = __EROFS_BUF_INITIALIZER; |
53 struct super_block *sb = dir->i_sb; 54 unsigned long bsz = sb->s_blocksize; |
|
53 const size_t dirsize = i_size_read(dir); | 55 const size_t dirsize = i_size_read(dir); |
54 unsigned int i = ctx->pos / EROFS_BLKSIZ; 55 unsigned int ofs = ctx->pos % EROFS_BLKSIZ; | 56 unsigned int i = erofs_blknr(sb, ctx->pos); 57 unsigned int ofs = erofs_blkoff(sb, ctx->pos); |
56 int err = 0; 57 bool initial = true; 58 59 while (ctx->pos < dirsize) { 60 struct erofs_dirent *de; 61 unsigned int nameoff, maxsize; 62 63 de = erofs_bread(&buf, dir, i, EROFS_KMAP); 64 if (IS_ERR(de)) { | 58 int err = 0; 59 bool initial = true; 60 61 while (ctx->pos < dirsize) { 62 struct erofs_dirent *de; 63 unsigned int nameoff, maxsize; 64 65 de = erofs_bread(&buf, dir, i, EROFS_KMAP); 66 if (IS_ERR(de)) { |
65 erofs_err(dir->i_sb, 66 "fail to readdir of logical block %u of nid %llu", | 67 erofs_err(sb, "fail to readdir of logical block %u of nid %llu", |
67 i, EROFS_I(dir)->nid); 68 err = PTR_ERR(de); 69 break; 70 } 71 72 nameoff = le16_to_cpu(de->nameoff); | 68 i, EROFS_I(dir)->nid); 69 err = PTR_ERR(de); 70 break; 71 } 72 73 nameoff = le16_to_cpu(de->nameoff); |
73 if (nameoff < sizeof(struct erofs_dirent) || 74 nameoff >= EROFS_BLKSIZ) { 75 erofs_err(dir->i_sb, 76 "invalid de[0].nameoff %u @ nid %llu", | 74 if (nameoff < sizeof(struct erofs_dirent) || nameoff >= bsz) { 75 erofs_err(sb, "invalid de[0].nameoff %u @ nid %llu", |
77 nameoff, EROFS_I(dir)->nid); 78 err = -EFSCORRUPTED; 79 break; 80 } 81 | 76 nameoff, EROFS_I(dir)->nid); 77 err = -EFSCORRUPTED; 78 break; 79 } 80 |
82 maxsize = min_t(unsigned int, 83 dirsize - ctx->pos + ofs, EROFS_BLKSIZ); | 81 maxsize = min_t(unsigned int, dirsize - ctx->pos + ofs, bsz); |
84 85 /* search dirents at the arbitrary position */ 86 if (initial) { 87 initial = false; 88 89 ofs = roundup(ofs, sizeof(struct erofs_dirent)); | 82 83 /* search dirents at the arbitrary position */ 84 if (initial) { 85 initial = false; 86 87 ofs = roundup(ofs, sizeof(struct erofs_dirent)); |
90 ctx->pos = blknr_to_addr(i) + ofs; | 88 ctx->pos = erofs_pos(sb, i) + ofs; |
91 if (ofs >= nameoff) 92 goto skip_this; 93 } 94 95 err = erofs_fill_dentries(dir, ctx, de, (void *)de + ofs, 96 nameoff, maxsize); 97 if (err) 98 break; 99skip_this: | 89 if (ofs >= nameoff) 90 goto skip_this; 91 } 92 93 err = erofs_fill_dentries(dir, ctx, de, (void *)de + ofs, 94 nameoff, maxsize); 95 if (err) 96 break; 97skip_this: |
100 ctx->pos = blknr_to_addr(i) + maxsize; | 98 ctx->pos = erofs_pos(sb, i) + maxsize; |
101 ++i; 102 ofs = 0; 103 } 104 erofs_put_metabuf(&buf); 105 return err < 0 ? err : 0; 106} 107 108const struct file_operations erofs_dir_fops = { 109 .llseek = generic_file_llseek, 110 .read = generic_read_dir, 111 .iterate_shared = erofs_readdir, 112}; | 99 ++i; 100 ofs = 0; 101 } 102 erofs_put_metabuf(&buf); 103 return err < 0 ? err : 0; 104} 105 106const struct file_operations erofs_dir_fops = { 107 .llseek = generic_file_llseek, 108 .read = generic_read_dir, 109 .iterate_shared = erofs_readdir, 110}; |