diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-05-16 13:48:17 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 04:56:34 -0400 |
commit | 75811d4fdaad3ac6fd27ec36773541ef6bbc104a (patch) | |
tree | cf8c1f0312ec6b10be2fd495cd1c649b4a320e69 /fs/exofs/dir.c | |
parent | 81b9f66e6b5cd8bc8aa4502dc69a923b3e68f664 (diff) |
[readdir] convert exofs
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/exofs/dir.c')
-rw-r--r-- | fs/exofs/dir.c | 38 |
1 files changed, 16 insertions, 22 deletions
diff --git a/fs/exofs/dir.c b/fs/exofs/dir.c index 46375896cfc0..49f51ab4caac 100644 --- a/fs/exofs/dir.c +++ b/fs/exofs/dir.c | |||
@@ -239,22 +239,19 @@ void exofs_set_de_type(struct exofs_dir_entry *de, struct inode *inode) | |||
239 | } | 239 | } |
240 | 240 | ||
241 | static int | 241 | static int |
242 | exofs_readdir(struct file *filp, void *dirent, filldir_t filldir) | 242 | exofs_readdir(struct file *file, struct dir_context *ctx) |
243 | { | 243 | { |
244 | loff_t pos = filp->f_pos; | 244 | loff_t pos = ctx->pos; |
245 | struct inode *inode = file_inode(filp); | 245 | struct inode *inode = file_inode(file); |
246 | unsigned int offset = pos & ~PAGE_CACHE_MASK; | 246 | unsigned int offset = pos & ~PAGE_CACHE_MASK; |
247 | unsigned long n = pos >> PAGE_CACHE_SHIFT; | 247 | unsigned long n = pos >> PAGE_CACHE_SHIFT; |
248 | unsigned long npages = dir_pages(inode); | 248 | unsigned long npages = dir_pages(inode); |
249 | unsigned chunk_mask = ~(exofs_chunk_size(inode)-1); | 249 | unsigned chunk_mask = ~(exofs_chunk_size(inode)-1); |
250 | unsigned char *types = NULL; | 250 | int need_revalidate = (file->f_version != inode->i_version); |
251 | int need_revalidate = (filp->f_version != inode->i_version); | ||
252 | 251 | ||
253 | if (pos > inode->i_size - EXOFS_DIR_REC_LEN(1)) | 252 | if (pos > inode->i_size - EXOFS_DIR_REC_LEN(1)) |
254 | return 0; | 253 | return 0; |
255 | 254 | ||
256 | types = exofs_filetype_table; | ||
257 | |||
258 | for ( ; n < npages; n++, offset = 0) { | 255 | for ( ; n < npages; n++, offset = 0) { |
259 | char *kaddr, *limit; | 256 | char *kaddr, *limit; |
260 | struct exofs_dir_entry *de; | 257 | struct exofs_dir_entry *de; |
@@ -263,7 +260,7 @@ exofs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
263 | if (IS_ERR(page)) { | 260 | if (IS_ERR(page)) { |
264 | EXOFS_ERR("ERROR: bad page in directory(0x%lx)\n", | 261 | EXOFS_ERR("ERROR: bad page in directory(0x%lx)\n", |
265 | inode->i_ino); | 262 | inode->i_ino); |
266 | filp->f_pos += PAGE_CACHE_SIZE - offset; | 263 | ctx->pos += PAGE_CACHE_SIZE - offset; |
267 | return PTR_ERR(page); | 264 | return PTR_ERR(page); |
268 | } | 265 | } |
269 | kaddr = page_address(page); | 266 | kaddr = page_address(page); |
@@ -271,9 +268,9 @@ exofs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
271 | if (offset) { | 268 | if (offset) { |
272 | offset = exofs_validate_entry(kaddr, offset, | 269 | offset = exofs_validate_entry(kaddr, offset, |
273 | chunk_mask); | 270 | chunk_mask); |
274 | filp->f_pos = (n<<PAGE_CACHE_SHIFT) + offset; | 271 | ctx->pos = (n<<PAGE_CACHE_SHIFT) + offset; |
275 | } | 272 | } |
276 | filp->f_version = inode->i_version; | 273 | file->f_version = inode->i_version; |
277 | need_revalidate = 0; | 274 | need_revalidate = 0; |
278 | } | 275 | } |
279 | de = (struct exofs_dir_entry *)(kaddr + offset); | 276 | de = (struct exofs_dir_entry *)(kaddr + offset); |
@@ -288,27 +285,24 @@ exofs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
288 | return -EIO; | 285 | return -EIO; |
289 | } | 286 | } |
290 | if (de->inode_no) { | 287 | if (de->inode_no) { |
291 | int over; | 288 | unsigned char t; |
292 | unsigned char d_type = DT_UNKNOWN; | ||
293 | 289 | ||
294 | if (types && de->file_type < EXOFS_FT_MAX) | 290 | if (de->file_type < EXOFS_FT_MAX) |
295 | d_type = types[de->file_type]; | 291 | t = exofs_filetype_table[de->file_type]; |
292 | else | ||
293 | t = DT_UNKNOWN; | ||
296 | 294 | ||
297 | offset = (char *)de - kaddr; | 295 | if (!dir_emit(ctx, de->name, de->name_len, |
298 | over = filldir(dirent, de->name, de->name_len, | ||
299 | (n<<PAGE_CACHE_SHIFT) | offset, | ||
300 | le64_to_cpu(de->inode_no), | 296 | le64_to_cpu(de->inode_no), |
301 | d_type); | 297 | t)) { |
302 | if (over) { | ||
303 | exofs_put_page(page); | 298 | exofs_put_page(page); |
304 | return 0; | 299 | return 0; |
305 | } | 300 | } |
306 | } | 301 | } |
307 | filp->f_pos += le16_to_cpu(de->rec_len); | 302 | ctx->pos += le16_to_cpu(de->rec_len); |
308 | } | 303 | } |
309 | exofs_put_page(page); | 304 | exofs_put_page(page); |
310 | } | 305 | } |
311 | |||
312 | return 0; | 306 | return 0; |
313 | } | 307 | } |
314 | 308 | ||
@@ -669,5 +663,5 @@ not_empty: | |||
669 | const struct file_operations exofs_dir_operations = { | 663 | const struct file_operations exofs_dir_operations = { |
670 | .llseek = generic_file_llseek, | 664 | .llseek = generic_file_llseek, |
671 | .read = generic_read_dir, | 665 | .read = generic_read_dir, |
672 | .readdir = exofs_readdir, | 666 | .iterate = exofs_readdir, |
673 | }; | 667 | }; |