diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-05-16 01:09:37 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 04:46:50 -0400 |
commit | 5add2ee198723c3fec3ce4a7d77de298344f6ba8 (patch) | |
tree | 4afd9d9caafe268071cd8ad16a857e5ba18756c6 /fs/udf/dir.c | |
parent | 5ded75ec4c576577cae7d556e671d11d0c80c2fc (diff) |
[readdir] convert udf
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/udf/dir.c')
-rw-r--r-- | fs/udf/dir.c | 63 |
1 files changed, 26 insertions, 37 deletions
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index b3e93f5e17c3..a012c51caffd 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -35,14 +35,16 @@ | |||
35 | #include "udf_i.h" | 35 | #include "udf_i.h" |
36 | #include "udf_sb.h" | 36 | #include "udf_sb.h" |
37 | 37 | ||
38 | static int do_udf_readdir(struct inode *dir, struct file *filp, | 38 | |
39 | filldir_t filldir, void *dirent) | 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 | struct udf_fileident_bh fibh = { .sbh = NULL, .ebh = NULL}; | 43 | struct udf_fileident_bh fibh = { .sbh = NULL, .ebh = NULL}; |
42 | struct fileIdentDesc *fi = NULL; | 44 | struct fileIdentDesc *fi = NULL; |
43 | struct fileIdentDesc cfi; | 45 | struct fileIdentDesc cfi; |
44 | int block, iblock; | 46 | int block, iblock; |
45 | loff_t nf_pos = (filp->f_pos - 1) << 2; | 47 | loff_t nf_pos; |
46 | int flen; | 48 | int flen; |
47 | unsigned char *fname = NULL; | 49 | unsigned char *fname = NULL; |
48 | unsigned char *nameptr; | 50 | unsigned char *nameptr; |
@@ -54,10 +56,14 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
54 | uint32_t elen; | 56 | uint32_t elen; |
55 | sector_t offset; | 57 | sector_t offset; |
56 | int i, num, ret = 0; | 58 | int i, num, ret = 0; |
57 | unsigned int dt_type; | ||
58 | struct extent_position epos = { NULL, 0, {0, 0} }; | 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 | if (nf_pos >= size) | 67 | if (nf_pos >= size) |
62 | goto out; | 68 | goto out; |
63 | 69 | ||
@@ -71,7 +77,6 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
71 | nf_pos = udf_ext0_offset(dir); | 77 | nf_pos = udf_ext0_offset(dir); |
72 | 78 | ||
73 | fibh.soffset = fibh.eoffset = nf_pos & (dir->i_sb->s_blocksize - 1); | 79 | fibh.soffset = fibh.eoffset = nf_pos & (dir->i_sb->s_blocksize - 1); |
74 | iinfo = UDF_I(dir); | ||
75 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 80 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
76 | if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits, | 81 | if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits, |
77 | &epos, &eloc, &elen, &offset) | 82 | &epos, &eloc, &elen, &offset) |
@@ -116,7 +121,9 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
116 | } | 121 | } |
117 | 122 | ||
118 | while (nf_pos < size) { | 123 | while (nf_pos < size) { |
119 | filp->f_pos = (nf_pos >> 2) + 1; | 124 | struct kernel_lb_addr tloc; |
125 | |||
126 | ctx->pos = (nf_pos >> 2) + 1; | ||
120 | 127 | ||
121 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, | 128 | fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, |
122 | &elen, &offset); | 129 | &elen, &offset); |
@@ -155,24 +162,22 @@ static int do_udf_readdir(struct inode *dir, struct file *filp, | |||
155 | } | 162 | } |
156 | 163 | ||
157 | if (cfi.fileCharacteristics & FID_FILE_CHAR_PARENT) { | 164 | if (cfi.fileCharacteristics & FID_FILE_CHAR_PARENT) { |
158 | iblock = parent_ino(filp->f_path.dentry); | 165 | if (!dir_emit_dotdot(file, ctx)) |
159 | flen = 2; | 166 | goto out; |
160 | memcpy(fname, "..", flen); | 167 | continue; |
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; | ||
168 | } | 168 | } |
169 | 169 | ||
170 | if (flen && filldir(dirent, fname, flen, filp->f_pos, | 170 | flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); |
171 | iblock, dt_type) < 0) | 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 | goto out; | 177 | goto out; |
173 | } /* end while */ | 178 | } /* end while */ |
174 | 179 | ||
175 | filp->f_pos = (nf_pos >> 2) + 1; | 180 | ctx->pos = (nf_pos >> 2) + 1; |
176 | 181 | ||
177 | out: | 182 | out: |
178 | if (fibh.sbh != fibh.ebh) | 183 | if (fibh.sbh != fibh.ebh) |
@@ -184,27 +189,11 @@ out: | |||
184 | return ret; | 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 | /* readdir and lookup functions */ | 192 | /* readdir and lookup functions */ |
204 | const struct file_operations udf_dir_operations = { | 193 | const struct file_operations udf_dir_operations = { |
205 | .llseek = generic_file_llseek, | 194 | .llseek = generic_file_llseek, |
206 | .read = generic_read_dir, | 195 | .read = generic_read_dir, |
207 | .readdir = udf_readdir, | 196 | .iterate = udf_readdir, |
208 | .unlocked_ioctl = udf_ioctl, | 197 | .unlocked_ioctl = udf_ioctl, |
209 | .fsync = generic_file_fsync, | 198 | .fsync = generic_file_fsync, |
210 | }; | 199 | }; |