aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext2/dir.c27
-rw-r--r--fs/minix/dir.c42
-rw-r--r--fs/sysv/dir.c37
-rw-r--r--fs/ufs/dir.c28
4 files changed, 59 insertions, 75 deletions
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 4237722bfd27..6e1d4ab09d72 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -287,17 +287,17 @@ static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode)
287} 287}
288 288
289static int 289static int
290ext2_readdir (struct file * filp, void * dirent, filldir_t filldir) 290ext2_readdir(struct file *file, struct dir_context *ctx)
291{ 291{
292 loff_t pos = filp->f_pos; 292 loff_t pos = ctx->pos;
293 struct inode *inode = file_inode(filp); 293 struct inode *inode = file_inode(file);
294 struct super_block *sb = inode->i_sb; 294 struct super_block *sb = inode->i_sb;
295 unsigned int offset = pos & ~PAGE_CACHE_MASK; 295 unsigned int offset = pos & ~PAGE_CACHE_MASK;
296 unsigned long n = pos >> PAGE_CACHE_SHIFT; 296 unsigned long n = pos >> PAGE_CACHE_SHIFT;
297 unsigned long npages = dir_pages(inode); 297 unsigned long npages = dir_pages(inode);
298 unsigned chunk_mask = ~(ext2_chunk_size(inode)-1); 298 unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
299 unsigned char *types = NULL; 299 unsigned char *types = NULL;
300 int need_revalidate = filp->f_version != inode->i_version; 300 int need_revalidate = file->f_version != inode->i_version;
301 301
302 if (pos > inode->i_size - EXT2_DIR_REC_LEN(1)) 302 if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
303 return 0; 303 return 0;
@@ -314,16 +314,16 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
314 ext2_error(sb, __func__, 314 ext2_error(sb, __func__,
315 "bad page in #%lu", 315 "bad page in #%lu",
316 inode->i_ino); 316 inode->i_ino);
317 filp->f_pos += PAGE_CACHE_SIZE - offset; 317 ctx->pos += PAGE_CACHE_SIZE - offset;
318 return PTR_ERR(page); 318 return PTR_ERR(page);
319 } 319 }
320 kaddr = page_address(page); 320 kaddr = page_address(page);
321 if (unlikely(need_revalidate)) { 321 if (unlikely(need_revalidate)) {
322 if (offset) { 322 if (offset) {
323 offset = ext2_validate_entry(kaddr, offset, chunk_mask); 323 offset = ext2_validate_entry(kaddr, offset, chunk_mask);
324 filp->f_pos = (n<<PAGE_CACHE_SHIFT) + offset; 324 ctx->pos = (n<<PAGE_CACHE_SHIFT) + offset;
325 } 325 }
326 filp->f_version = inode->i_version; 326 file->f_version = inode->i_version;
327 need_revalidate = 0; 327 need_revalidate = 0;
328 } 328 }
329 de = (ext2_dirent *)(kaddr+offset); 329 de = (ext2_dirent *)(kaddr+offset);
@@ -336,22 +336,19 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
336 return -EIO; 336 return -EIO;
337 } 337 }
338 if (de->inode) { 338 if (de->inode) {
339 int over;
340 unsigned char d_type = DT_UNKNOWN; 339 unsigned char d_type = DT_UNKNOWN;
341 340
342 if (types && de->file_type < EXT2_FT_MAX) 341 if (types && de->file_type < EXT2_FT_MAX)
343 d_type = types[de->file_type]; 342 d_type = types[de->file_type];
344 343
345 offset = (char *)de - kaddr; 344 if (!dir_emit(ctx, de->name, de->name_len,
346 over = filldir(dirent, de->name, de->name_len, 345 le32_to_cpu(de->inode),
347 (n<<PAGE_CACHE_SHIFT) | offset, 346 d_type)) {
348 le32_to_cpu(de->inode), d_type);
349 if (over) {
350 ext2_put_page(page); 347 ext2_put_page(page);
351 return 0; 348 return 0;
352 } 349 }
353 } 350 }
354 filp->f_pos += ext2_rec_len_from_disk(de->rec_len); 351 ctx->pos += ext2_rec_len_from_disk(de->rec_len);
355 } 352 }
356 ext2_put_page(page); 353 ext2_put_page(page);
357 } 354 }
@@ -724,7 +721,7 @@ not_empty:
724const struct file_operations ext2_dir_operations = { 721const struct file_operations ext2_dir_operations = {
725 .llseek = generic_file_llseek, 722 .llseek = generic_file_llseek,
726 .read = generic_read_dir, 723 .read = generic_read_dir,
727 .readdir = ext2_readdir, 724 .iterate = ext2_readdir,
728 .unlocked_ioctl = ext2_ioctl, 725 .unlocked_ioctl = ext2_ioctl,
729#ifdef CONFIG_COMPAT 726#ifdef CONFIG_COMPAT
730 .compat_ioctl = ext2_compat_ioctl, 727 .compat_ioctl = ext2_compat_ioctl,
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index a9ed6f36e6ea..08c442902fcd 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -16,12 +16,12 @@
16typedef struct minix_dir_entry minix_dirent; 16typedef struct minix_dir_entry minix_dirent;
17typedef struct minix3_dir_entry minix3_dirent; 17typedef struct minix3_dir_entry minix3_dirent;
18 18
19static int minix_readdir(struct file *, void *, filldir_t); 19static int minix_readdir(struct file *, struct dir_context *);
20 20
21const struct file_operations minix_dir_operations = { 21const struct file_operations minix_dir_operations = {
22 .llseek = generic_file_llseek, 22 .llseek = generic_file_llseek,
23 .read = generic_read_dir, 23 .read = generic_read_dir,
24 .readdir = minix_readdir, 24 .iterate = minix_readdir,
25 .fsync = generic_file_fsync, 25 .fsync = generic_file_fsync,
26}; 26};
27 27
@@ -82,22 +82,23 @@ static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi)
82 return (void*)((char*)de + sbi->s_dirsize); 82 return (void*)((char*)de + sbi->s_dirsize);
83} 83}
84 84
85static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir) 85static int minix_readdir(struct file *file, struct dir_context *ctx)
86{ 86{
87 unsigned long pos = filp->f_pos; 87 struct inode *inode = file_inode(file);
88 struct inode *inode = file_inode(filp);
89 struct super_block *sb = inode->i_sb; 88 struct super_block *sb = inode->i_sb;
90 unsigned offset = pos & ~PAGE_CACHE_MASK;
91 unsigned long n = pos >> PAGE_CACHE_SHIFT;
92 unsigned long npages = dir_pages(inode);
93 struct minix_sb_info *sbi = minix_sb(sb); 89 struct minix_sb_info *sbi = minix_sb(sb);
94 unsigned chunk_size = sbi->s_dirsize; 90 unsigned chunk_size = sbi->s_dirsize;
95 char *name; 91 unsigned long npages = dir_pages(inode);
96 __u32 inumber; 92 unsigned long pos = ctx->pos;
93 unsigned offset;
94 unsigned long n;
97 95
98 pos = (pos + chunk_size-1) & ~(chunk_size-1); 96 ctx->pos = pos = (pos + chunk_size-1) & ~(chunk_size-1);
99 if (pos >= inode->i_size) 97 if (pos >= inode->i_size)
100 goto done; 98 return 0;
99
100 offset = pos & ~PAGE_CACHE_MASK;
101 n = pos >> PAGE_CACHE_SHIFT;
101 102
102 for ( ; n < npages; n++, offset = 0) { 103 for ( ; n < npages; n++, offset = 0) {
103 char *p, *kaddr, *limit; 104 char *p, *kaddr, *limit;
@@ -109,6 +110,8 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
109 p = kaddr+offset; 110 p = kaddr+offset;
110 limit = kaddr + minix_last_byte(inode, n) - chunk_size; 111 limit = kaddr + minix_last_byte(inode, n) - chunk_size;
111 for ( ; p <= limit; p = minix_next_entry(p, sbi)) { 112 for ( ; p <= limit; p = minix_next_entry(p, sbi)) {
113 const char *name;
114 __u32 inumber;
112 if (sbi->s_version == MINIX_V3) { 115 if (sbi->s_version == MINIX_V3) {
113 minix3_dirent *de3 = (minix3_dirent *)p; 116 minix3_dirent *de3 = (minix3_dirent *)p;
114 name = de3->name; 117 name = de3->name;
@@ -119,24 +122,17 @@ static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
119 inumber = de->inode; 122 inumber = de->inode;
120 } 123 }
121 if (inumber) { 124 if (inumber) {
122 int over;
123
124 unsigned l = strnlen(name, sbi->s_namelen); 125 unsigned l = strnlen(name, sbi->s_namelen);
125 offset = p - kaddr; 126 if (!dir_emit(ctx, name, l,
126 over = filldir(dirent, name, l, 127 inumber, DT_UNKNOWN)) {
127 (n << PAGE_CACHE_SHIFT) | offset,
128 inumber, DT_UNKNOWN);
129 if (over) {
130 dir_put_page(page); 128 dir_put_page(page);
131 goto done; 129 return 0;
132 } 130 }
133 } 131 }
132 ctx->pos += chunk_size;
134 } 133 }
135 dir_put_page(page); 134 dir_put_page(page);
136 } 135 }
137
138done:
139 filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
140 return 0; 136 return 0;
141} 137}
142 138
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index 3799e8dac3eb..d42291d08215 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -18,12 +18,12 @@
18#include <linux/swap.h> 18#include <linux/swap.h>
19#include "sysv.h" 19#include "sysv.h"
20 20
21static int sysv_readdir(struct file *, void *, filldir_t); 21static int sysv_readdir(struct file *, struct dir_context *);
22 22
23const struct file_operations sysv_dir_operations = { 23const struct file_operations sysv_dir_operations = {
24 .llseek = generic_file_llseek, 24 .llseek = generic_file_llseek,
25 .read = generic_read_dir, 25 .read = generic_read_dir,
26 .readdir = sysv_readdir, 26 .iterate = sysv_readdir,
27 .fsync = generic_file_fsync, 27 .fsync = generic_file_fsync,
28}; 28};
29 29
@@ -65,18 +65,21 @@ static struct page * dir_get_page(struct inode *dir, unsigned long n)
65 return page; 65 return page;
66} 66}
67 67
68static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir) 68static int sysv_readdir(struct file *file, struct dir_context *ctx)
69{ 69{
70 unsigned long pos = filp->f_pos; 70 unsigned long pos = ctx->pos;
71 struct inode *inode = file_inode(filp); 71 struct inode *inode = file_inode(file);
72 struct super_block *sb = inode->i_sb; 72 struct super_block *sb = inode->i_sb;
73 unsigned offset = pos & ~PAGE_CACHE_MASK;
74 unsigned long n = pos >> PAGE_CACHE_SHIFT;
75 unsigned long npages = dir_pages(inode); 73 unsigned long npages = dir_pages(inode);
74 unsigned offset;
75 unsigned long n;
76 76
77 pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1); 77 ctx->pos = pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1);
78 if (pos >= inode->i_size) 78 if (pos >= inode->i_size)
79 goto done; 79 return 0;
80
81 offset = pos & ~PAGE_CACHE_MASK;
82 n = pos >> PAGE_CACHE_SHIFT;
80 83
81 for ( ; n < npages; n++, offset = 0) { 84 for ( ; n < npages; n++, offset = 0) {
82 char *kaddr, *limit; 85 char *kaddr, *limit;
@@ -88,29 +91,21 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
88 kaddr = (char *)page_address(page); 91 kaddr = (char *)page_address(page);
89 de = (struct sysv_dir_entry *)(kaddr+offset); 92 de = (struct sysv_dir_entry *)(kaddr+offset);
90 limit = kaddr + PAGE_CACHE_SIZE - SYSV_DIRSIZE; 93 limit = kaddr + PAGE_CACHE_SIZE - SYSV_DIRSIZE;
91 for ( ;(char*)de <= limit; de++) { 94 for ( ;(char*)de <= limit; de++, ctx->pos += sizeof(*de)) {
92 char *name = de->name; 95 char *name = de->name;
93 int over;
94 96
95 if (!de->inode) 97 if (!de->inode)
96 continue; 98 continue;
97 99
98 offset = (char *)de - kaddr; 100 if (!dir_emit(ctx, name, strnlen(name,SYSV_NAMELEN),
99
100 over = filldir(dirent, name, strnlen(name,SYSV_NAMELEN),
101 ((loff_t)n<<PAGE_CACHE_SHIFT) | offset,
102 fs16_to_cpu(SYSV_SB(sb), de->inode), 101 fs16_to_cpu(SYSV_SB(sb), de->inode),
103 DT_UNKNOWN); 102 DT_UNKNOWN)) {
104 if (over) {
105 dir_put_page(page); 103 dir_put_page(page);
106 goto done; 104 return 0;
107 } 105 }
108 } 106 }
109 dir_put_page(page); 107 dir_put_page(page);
110 } 108 }
111
112done:
113 filp->f_pos = ((loff_t)n << PAGE_CACHE_SHIFT) | offset;
114 return 0; 109 return 0;
115} 110}
116 111
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 3a75ca09c506..0ecc2cebed8f 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -430,16 +430,16 @@ ufs_validate_entry(struct super_block *sb, char *base,
430 * This is blatantly stolen from ext2fs 430 * This is blatantly stolen from ext2fs
431 */ 431 */
432static int 432static int
433ufs_readdir(struct file *filp, void *dirent, filldir_t filldir) 433ufs_readdir(struct file *file, struct dir_context *ctx)
434{ 434{
435 loff_t pos = filp->f_pos; 435 loff_t pos = ctx->pos;
436 struct inode *inode = file_inode(filp); 436 struct inode *inode = file_inode(file);
437 struct super_block *sb = inode->i_sb; 437 struct super_block *sb = inode->i_sb;
438 unsigned int offset = pos & ~PAGE_CACHE_MASK; 438 unsigned int offset = pos & ~PAGE_CACHE_MASK;
439 unsigned long n = pos >> PAGE_CACHE_SHIFT; 439 unsigned long n = pos >> PAGE_CACHE_SHIFT;
440 unsigned long npages = ufs_dir_pages(inode); 440 unsigned long npages = ufs_dir_pages(inode);
441 unsigned chunk_mask = ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1); 441 unsigned chunk_mask = ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
442 int need_revalidate = filp->f_version != inode->i_version; 442 int need_revalidate = file->f_version != inode->i_version;
443 unsigned flags = UFS_SB(sb)->s_flags; 443 unsigned flags = UFS_SB(sb)->s_flags;
444 444
445 UFSD("BEGIN\n"); 445 UFSD("BEGIN\n");
@@ -457,16 +457,16 @@ ufs_readdir(struct file *filp, void *dirent, filldir_t filldir)
457 ufs_error(sb, __func__, 457 ufs_error(sb, __func__,
458 "bad page in #%lu", 458 "bad page in #%lu",
459 inode->i_ino); 459 inode->i_ino);
460 filp->f_pos += PAGE_CACHE_SIZE - offset; 460 ctx->pos += PAGE_CACHE_SIZE - offset;
461 return -EIO; 461 return -EIO;
462 } 462 }
463 kaddr = page_address(page); 463 kaddr = page_address(page);
464 if (unlikely(need_revalidate)) { 464 if (unlikely(need_revalidate)) {
465 if (offset) { 465 if (offset) {
466 offset = ufs_validate_entry(sb, kaddr, offset, chunk_mask); 466 offset = ufs_validate_entry(sb, kaddr, offset, chunk_mask);
467 filp->f_pos = (n<<PAGE_CACHE_SHIFT) + offset; 467 ctx->pos = (n<<PAGE_CACHE_SHIFT) + offset;
468 } 468 }
469 filp->f_version = inode->i_version; 469 file->f_version = inode->i_version;
470 need_revalidate = 0; 470 need_revalidate = 0;
471 } 471 }
472 de = (struct ufs_dir_entry *)(kaddr+offset); 472 de = (struct ufs_dir_entry *)(kaddr+offset);
@@ -479,11 +479,8 @@ ufs_readdir(struct file *filp, void *dirent, filldir_t filldir)
479 return -EIO; 479 return -EIO;
480 } 480 }
481 if (de->d_ino) { 481 if (de->d_ino) {
482 int over;
483 unsigned char d_type = DT_UNKNOWN; 482 unsigned char d_type = DT_UNKNOWN;
484 483
485 offset = (char *)de - kaddr;
486
487 UFSD("filldir(%s,%u)\n", de->d_name, 484 UFSD("filldir(%s,%u)\n", de->d_name,
488 fs32_to_cpu(sb, de->d_ino)); 485 fs32_to_cpu(sb, de->d_ino));
489 UFSD("namlen %u\n", ufs_get_de_namlen(sb, de)); 486 UFSD("namlen %u\n", ufs_get_de_namlen(sb, de));
@@ -491,16 +488,15 @@ ufs_readdir(struct file *filp, void *dirent, filldir_t filldir)
491 if ((flags & UFS_DE_MASK) == UFS_DE_44BSD) 488 if ((flags & UFS_DE_MASK) == UFS_DE_44BSD)
492 d_type = de->d_u.d_44.d_type; 489 d_type = de->d_u.d_44.d_type;
493 490
494 over = filldir(dirent, de->d_name, 491 if (!dir_emit(ctx, de->d_name,
495 ufs_get_de_namlen(sb, de), 492 ufs_get_de_namlen(sb, de),
496 (n<<PAGE_CACHE_SHIFT) | offset, 493 fs32_to_cpu(sb, de->d_ino),
497 fs32_to_cpu(sb, de->d_ino), d_type); 494 d_type)) {
498 if (over) {
499 ufs_put_page(page); 495 ufs_put_page(page);
500 return 0; 496 return 0;
501 } 497 }
502 } 498 }
503 filp->f_pos += fs16_to_cpu(sb, de->d_reclen); 499 ctx->pos += fs16_to_cpu(sb, de->d_reclen);
504 } 500 }
505 ufs_put_page(page); 501 ufs_put_page(page);
506 } 502 }
@@ -660,7 +656,7 @@ not_empty:
660 656
661const struct file_operations ufs_dir_operations = { 657const struct file_operations ufs_dir_operations = {
662 .read = generic_read_dir, 658 .read = generic_read_dir,
663 .readdir = ufs_readdir, 659 .iterate = ufs_readdir,
664 .fsync = generic_file_fsync, 660 .fsync = generic_file_fsync,
665 .llseek = generic_file_llseek, 661 .llseek = generic_file_llseek,
666}; 662};