Commit 5add2ee198723c3fec3ce4a7d77de298344f6ba8
1 parent
5ded75ec4c
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
[readdir] convert udf
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 1 changed file with 26 additions and 37 deletions Side-by-side Diff
fs/udf/dir.c
... | ... | @@ -35,14 +35,16 @@ |
35 | 35 | #include "udf_i.h" |
36 | 36 | #include "udf_sb.h" |
37 | 37 | |
38 | -static int do_udf_readdir(struct inode *dir, struct file *filp, | |
39 | - filldir_t filldir, void *dirent) | |
38 | + | |
39 | +static int udf_readdir(struct file *file, struct dir_context *ctx) | |
40 | 40 | { |
41 | + struct inode *dir = file_inode(file); | |
42 | + struct udf_inode_info *iinfo = UDF_I(dir); | |
41 | 43 | struct udf_fileident_bh fibh = { .sbh = NULL, .ebh = NULL}; |
42 | 44 | struct fileIdentDesc *fi = NULL; |
43 | 45 | struct fileIdentDesc cfi; |
44 | 46 | int block, iblock; |
45 | - loff_t nf_pos = (filp->f_pos - 1) << 2; | |
47 | + loff_t nf_pos; | |
46 | 48 | int flen; |
47 | 49 | unsigned char *fname = NULL; |
48 | 50 | unsigned char *nameptr; |
49 | 51 | |
50 | 52 | |
... | ... | @@ -54,10 +56,14 @@ |
54 | 56 | uint32_t elen; |
55 | 57 | sector_t offset; |
56 | 58 | int i, num, ret = 0; |
57 | - unsigned int dt_type; | |
58 | 59 | struct extent_position epos = { NULL, 0, {0, 0} }; |
59 | - struct udf_inode_info *iinfo; | |
60 | 60 | |
61 | + if (ctx->pos == 0) { | |
62 | + if (!dir_emit_dot(file, ctx)) | |
63 | + return 0; | |
64 | + ctx->pos = 1; | |
65 | + } | |
66 | + nf_pos = (ctx->pos - 1) << 2; | |
61 | 67 | if (nf_pos >= size) |
62 | 68 | goto out; |
63 | 69 | |
... | ... | @@ -71,7 +77,6 @@ |
71 | 77 | nf_pos = udf_ext0_offset(dir); |
72 | 78 | |
73 | 79 | fibh.soffset = fibh.eoffset = nf_pos & (dir->i_sb->s_blocksize - 1); |
74 | - iinfo = UDF_I(dir); | |
75 | 80 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
76 | 81 | if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits, |
77 | 82 | &epos, &eloc, &elen, &offset) |
78 | 83 | |
... | ... | @@ -116,8 +121,10 @@ |
116 | 121 | } |
117 | 122 | |
118 | 123 | while (nf_pos < size) { |
119 | - filp->f_pos = (nf_pos >> 2) + 1; | |
124 | + struct kernel_lb_addr tloc; | |
120 | 125 | |
126 | + ctx->pos = (nf_pos >> 2) + 1; | |
127 | + | |
121 | 128 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, |
122 | 129 | &elen, &offset); |
123 | 130 | if (!fi) |
124 | 131 | |
125 | 132 | |
... | ... | @@ -155,24 +162,22 @@ |
155 | 162 | } |
156 | 163 | |
157 | 164 | if (cfi.fileCharacteristics & FID_FILE_CHAR_PARENT) { |
158 | - iblock = parent_ino(filp->f_path.dentry); | |
159 | - flen = 2; | |
160 | - memcpy(fname, "..", flen); | |
161 | - dt_type = DT_DIR; | |
162 | - } else { | |
163 | - struct kernel_lb_addr tloc = lelb_to_cpu(cfi.icb.extLocation); | |
164 | - | |
165 | - iblock = udf_get_lb_pblock(dir->i_sb, &tloc, 0); | |
166 | - flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); | |
167 | - dt_type = DT_UNKNOWN; | |
165 | + if (!dir_emit_dotdot(file, ctx)) | |
166 | + goto out; | |
167 | + continue; | |
168 | 168 | } |
169 | 169 | |
170 | - if (flen && filldir(dirent, fname, flen, filp->f_pos, | |
171 | - iblock, dt_type) < 0) | |
170 | + flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); | |
171 | + if (!flen) | |
172 | + continue; | |
173 | + | |
174 | + tloc = lelb_to_cpu(cfi.icb.extLocation); | |
175 | + iblock = udf_get_lb_pblock(dir->i_sb, &tloc, 0); | |
176 | + if (!dir_emit(ctx, fname, flen, iblock, DT_UNKNOWN)) | |
172 | 177 | goto out; |
173 | 178 | } /* end while */ |
174 | 179 | |
175 | - filp->f_pos = (nf_pos >> 2) + 1; | |
180 | + ctx->pos = (nf_pos >> 2) + 1; | |
176 | 181 | |
177 | 182 | out: |
178 | 183 | if (fibh.sbh != fibh.ebh) |
179 | 184 | |
... | ... | @@ -184,27 +189,11 @@ |
184 | 189 | return ret; |
185 | 190 | } |
186 | 191 | |
187 | -static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) | |
188 | -{ | |
189 | - struct inode *dir = file_inode(filp); | |
190 | - int result; | |
191 | - | |
192 | - if (filp->f_pos == 0) { | |
193 | - if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino, DT_DIR) < 0) { | |
194 | - return 0; | |
195 | - } | |
196 | - filp->f_pos++; | |
197 | - } | |
198 | - | |
199 | - result = do_udf_readdir(dir, filp, filldir, dirent); | |
200 | - return result; | |
201 | -} | |
202 | - | |
203 | 192 | /* readdir and lookup functions */ |
204 | 193 | const struct file_operations udf_dir_operations = { |
205 | 194 | .llseek = generic_file_llseek, |
206 | 195 | .read = generic_read_dir, |
207 | - .readdir = udf_readdir, | |
196 | + .iterate = udf_readdir, | |
208 | 197 | .unlocked_ioctl = udf_ioctl, |
209 | 198 | .fsync = generic_file_fsync, |
210 | 199 | }; |