aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-16 01:09:37 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:46:50 -0400
commit5add2ee198723c3fec3ce4a7d77de298344f6ba8 (patch)
tree4afd9d9caafe268071cd8ad16a857e5ba18756c6 /fs
parent5ded75ec4c576577cae7d556e671d11d0c80c2fc (diff)
[readdir] convert udf
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/udf/dir.c63
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
38static int do_udf_readdir(struct inode *dir, struct file *filp, 38
39 filldir_t filldir, void *dirent) 39static 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
177out: 182out:
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
187static 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 */
204const struct file_operations udf_dir_operations = { 193const 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};