diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-05-22 14:59:39 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 04:56:56 -0400 |
commit | e72514e7adcfb2eff1cd9233d314451accaa669a (patch) | |
tree | 5a28f5fc1d2d4b0e25c1d6b7b2131a417d173869 /fs/hfsplus | |
parent | 002f8bec854432db56f30121325867db6e248a03 (diff) |
[readdir] convert hfsplus
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/hfsplus')
-rw-r--r-- | fs/hfsplus/dir.c | 50 |
1 files changed, 23 insertions, 27 deletions
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index a37ac934732f..d8ce4bd17fc5 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -121,9 +121,9 @@ fail: | |||
121 | return ERR_PTR(err); | 121 | return ERR_PTR(err); |
122 | } | 122 | } |
123 | 123 | ||
124 | static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | 124 | static int hfsplus_readdir(struct file *file, struct dir_context *ctx) |
125 | { | 125 | { |
126 | struct inode *inode = file_inode(filp); | 126 | struct inode *inode = file_inode(file); |
127 | struct super_block *sb = inode->i_sb; | 127 | struct super_block *sb = inode->i_sb; |
128 | int len, err; | 128 | int len, err; |
129 | char strbuf[HFSPLUS_MAX_STRLEN + 1]; | 129 | char strbuf[HFSPLUS_MAX_STRLEN + 1]; |
@@ -132,7 +132,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
132 | struct hfsplus_readdir_data *rd; | 132 | struct hfsplus_readdir_data *rd; |
133 | u16 type; | 133 | u16 type; |
134 | 134 | ||
135 | if (filp->f_pos >= inode->i_size) | 135 | if (file->f_pos >= inode->i_size) |
136 | return 0; | 136 | return 0; |
137 | 137 | ||
138 | err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); | 138 | err = hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd); |
@@ -143,14 +143,13 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
143 | if (err) | 143 | if (err) |
144 | goto out; | 144 | goto out; |
145 | 145 | ||
146 | switch ((u32)filp->f_pos) { | 146 | if (ctx->pos == 0) { |
147 | case 0: | ||
148 | /* This is completely artificial... */ | 147 | /* This is completely artificial... */ |
149 | if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR)) | 148 | if (!dir_emit_dot(file, ctx)) |
150 | goto out; | 149 | goto out; |
151 | filp->f_pos++; | 150 | ctx->pos = 1; |
152 | /* fall through */ | 151 | } |
153 | case 1: | 152 | if (ctx->pos == 1) { |
154 | if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { | 153 | if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { |
155 | err = -EIO; | 154 | err = -EIO; |
156 | goto out; | 155 | goto out; |
@@ -168,19 +167,16 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
168 | err = -EIO; | 167 | err = -EIO; |
169 | goto out; | 168 | goto out; |
170 | } | 169 | } |
171 | if (filldir(dirent, "..", 2, 1, | 170 | if (!dir_emit(ctx, "..", 2, |
172 | be32_to_cpu(entry.thread.parentID), DT_DIR)) | 171 | be32_to_cpu(entry.thread.parentID), DT_DIR)) |
173 | goto out; | 172 | goto out; |
174 | filp->f_pos++; | 173 | ctx->pos = 2; |
175 | /* fall through */ | ||
176 | default: | ||
177 | if (filp->f_pos >= inode->i_size) | ||
178 | goto out; | ||
179 | err = hfs_brec_goto(&fd, filp->f_pos - 1); | ||
180 | if (err) | ||
181 | goto out; | ||
182 | } | 174 | } |
183 | 175 | if (ctx->pos >= inode->i_size) | |
176 | goto out; | ||
177 | err = hfs_brec_goto(&fd, ctx->pos - 1); | ||
178 | if (err) | ||
179 | goto out; | ||
184 | for (;;) { | 180 | for (;;) { |
185 | if (be32_to_cpu(fd.key->cat.parent) != inode->i_ino) { | 181 | if (be32_to_cpu(fd.key->cat.parent) != inode->i_ino) { |
186 | pr_err("walked past end of dir\n"); | 182 | pr_err("walked past end of dir\n"); |
@@ -211,7 +207,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
211 | HFSPLUS_SB(sb)->hidden_dir->i_ino == | 207 | HFSPLUS_SB(sb)->hidden_dir->i_ino == |
212 | be32_to_cpu(entry.folder.id)) | 208 | be32_to_cpu(entry.folder.id)) |
213 | goto next; | 209 | goto next; |
214 | if (filldir(dirent, strbuf, len, filp->f_pos, | 210 | if (!dir_emit(ctx, strbuf, len, |
215 | be32_to_cpu(entry.folder.id), DT_DIR)) | 211 | be32_to_cpu(entry.folder.id), DT_DIR)) |
216 | break; | 212 | break; |
217 | } else if (type == HFSPLUS_FILE) { | 213 | } else if (type == HFSPLUS_FILE) { |
@@ -220,7 +216,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
220 | err = -EIO; | 216 | err = -EIO; |
221 | goto out; | 217 | goto out; |
222 | } | 218 | } |
223 | if (filldir(dirent, strbuf, len, filp->f_pos, | 219 | if (!dir_emit(ctx, strbuf, len, |
224 | be32_to_cpu(entry.file.id), DT_REG)) | 220 | be32_to_cpu(entry.file.id), DT_REG)) |
225 | break; | 221 | break; |
226 | } else { | 222 | } else { |
@@ -229,22 +225,22 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
229 | goto out; | 225 | goto out; |
230 | } | 226 | } |
231 | next: | 227 | next: |
232 | filp->f_pos++; | 228 | ctx->pos++; |
233 | if (filp->f_pos >= inode->i_size) | 229 | if (ctx->pos >= inode->i_size) |
234 | goto out; | 230 | goto out; |
235 | err = hfs_brec_goto(&fd, 1); | 231 | err = hfs_brec_goto(&fd, 1); |
236 | if (err) | 232 | if (err) |
237 | goto out; | 233 | goto out; |
238 | } | 234 | } |
239 | rd = filp->private_data; | 235 | rd = file->private_data; |
240 | if (!rd) { | 236 | if (!rd) { |
241 | rd = kmalloc(sizeof(struct hfsplus_readdir_data), GFP_KERNEL); | 237 | rd = kmalloc(sizeof(struct hfsplus_readdir_data), GFP_KERNEL); |
242 | if (!rd) { | 238 | if (!rd) { |
243 | err = -ENOMEM; | 239 | err = -ENOMEM; |
244 | goto out; | 240 | goto out; |
245 | } | 241 | } |
246 | filp->private_data = rd; | 242 | file->private_data = rd; |
247 | rd->file = filp; | 243 | rd->file = file; |
248 | list_add(&rd->list, &HFSPLUS_I(inode)->open_dir_list); | 244 | list_add(&rd->list, &HFSPLUS_I(inode)->open_dir_list); |
249 | } | 245 | } |
250 | memcpy(&rd->key, fd.key, sizeof(struct hfsplus_cat_key)); | 246 | memcpy(&rd->key, fd.key, sizeof(struct hfsplus_cat_key)); |
@@ -538,7 +534,7 @@ const struct inode_operations hfsplus_dir_inode_operations = { | |||
538 | const struct file_operations hfsplus_dir_operations = { | 534 | const struct file_operations hfsplus_dir_operations = { |
539 | .fsync = hfsplus_file_fsync, | 535 | .fsync = hfsplus_file_fsync, |
540 | .read = generic_read_dir, | 536 | .read = generic_read_dir, |
541 | .readdir = hfsplus_readdir, | 537 | .iterate = hfsplus_readdir, |
542 | .unlocked_ioctl = hfsplus_ioctl, | 538 | .unlocked_ioctl = hfsplus_ioctl, |
543 | .llseek = generic_file_llseek, | 539 | .llseek = generic_file_llseek, |
544 | .release = hfsplus_dir_release, | 540 | .release = hfsplus_dir_release, |