aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysv
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-15 18:51:49 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:46:47 -0400
commit80886298c07234331458e963b5f9f57c68edd700 (patch)
tree89b2df2d0ad43dc2e6a0091b4b04c1105433cf4d /fs/sysv
parentbb6f619b3a49f940d7478112500da312d70866eb (diff)
[readdir] simple local unixlike: switch to ->iterate()
ext2, ufs, minix, sysv Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/sysv')
-rw-r--r--fs/sysv/dir.c37
1 files changed, 16 insertions, 21 deletions
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