aboutsummaryrefslogtreecommitdiffstats
path: root/fs/affs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-05-17 17:44:42 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:56:44 -0400
commit0edf977d2ae32b492780828d4b5bd41c5d51cb02 (patch)
tree5c6461e41ef1fb49beba2b179e2cc89b1733925b /fs/affs
parent2638ffbac9e2f411e911ff8194dc8d69c46f9f78 (diff)
[readdir] convert affs
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/affs')
-rw-r--r--fs/affs/dir.c69
1 files changed, 24 insertions, 45 deletions
diff --git a/fs/affs/dir.c b/fs/affs/dir.c
index fd11a6d608ee..f1eba8c3644e 100644
--- a/fs/affs/dir.c
+++ b/fs/affs/dir.c
@@ -15,12 +15,12 @@
15 15
16#include "affs.h" 16#include "affs.h"
17 17
18static int affs_readdir(struct file *, void *, filldir_t); 18static int affs_readdir(struct file *, struct dir_context *);
19 19
20const struct file_operations affs_dir_operations = { 20const struct file_operations affs_dir_operations = {
21 .read = generic_read_dir, 21 .read = generic_read_dir,
22 .llseek = generic_file_llseek, 22 .llseek = generic_file_llseek,
23 .readdir = affs_readdir, 23 .iterate = affs_readdir,
24 .fsync = affs_file_fsync, 24 .fsync = affs_file_fsync,
25}; 25};
26 26
@@ -40,52 +40,35 @@ const struct inode_operations affs_dir_inode_operations = {
40}; 40};
41 41
42static int 42static int
43affs_readdir(struct file *filp, void *dirent, filldir_t filldir) 43affs_readdir(struct file *file, struct dir_context *ctx)
44{ 44{
45 struct inode *inode = file_inode(filp); 45 struct inode *inode = file_inode(file);
46 struct super_block *sb = inode->i_sb; 46 struct super_block *sb = inode->i_sb;
47 struct buffer_head *dir_bh; 47 struct buffer_head *dir_bh = NULL;
48 struct buffer_head *fh_bh; 48 struct buffer_head *fh_bh = NULL;
49 unsigned char *name; 49 unsigned char *name;
50 int namelen; 50 int namelen;
51 u32 i; 51 u32 i;
52 int hash_pos; 52 int hash_pos;
53 int chain_pos; 53 int chain_pos;
54 u32 f_pos;
55 u32 ino; 54 u32 ino;
56 int stored;
57 int res;
58 55
59 pr_debug("AFFS: readdir(ino=%lu,f_pos=%lx)\n",inode->i_ino,(unsigned long)filp->f_pos); 56 pr_debug("AFFS: readdir(ino=%lu,f_pos=%lx)\n",inode->i_ino,(unsigned long)ctx->pos);
60 57
61 stored = 0; 58 if (ctx->pos < 2) {
62 res = -EIO; 59 file->private_data = (void *)0;
63 dir_bh = NULL; 60 if (!dir_emit_dots(file, ctx))
64 fh_bh = NULL;
65 f_pos = filp->f_pos;
66
67 if (f_pos == 0) {
68 filp->private_data = (void *)0;
69 if (filldir(dirent, ".", 1, f_pos, inode->i_ino, DT_DIR) < 0)
70 return 0; 61 return 0;
71 filp->f_pos = f_pos = 1;
72 stored++;
73 }
74 if (f_pos == 1) {
75 if (filldir(dirent, "..", 2, f_pos, parent_ino(filp->f_path.dentry), DT_DIR) < 0)
76 return stored;
77 filp->f_pos = f_pos = 2;
78 stored++;
79 } 62 }
80 63
81 affs_lock_dir(inode); 64 affs_lock_dir(inode);
82 chain_pos = (f_pos - 2) & 0xffff; 65 chain_pos = (ctx->pos - 2) & 0xffff;
83 hash_pos = (f_pos - 2) >> 16; 66 hash_pos = (ctx->pos - 2) >> 16;
84 if (chain_pos == 0xffff) { 67 if (chain_pos == 0xffff) {
85 affs_warning(sb, "readdir", "More than 65535 entries in chain"); 68 affs_warning(sb, "readdir", "More than 65535 entries in chain");
86 chain_pos = 0; 69 chain_pos = 0;
87 hash_pos++; 70 hash_pos++;
88 filp->f_pos = ((hash_pos << 16) | chain_pos) + 2; 71 ctx->pos = ((hash_pos << 16) | chain_pos) + 2;
89 } 72 }
90 dir_bh = affs_bread(sb, inode->i_ino); 73 dir_bh = affs_bread(sb, inode->i_ino);
91 if (!dir_bh) 74 if (!dir_bh)
@@ -94,8 +77,8 @@ affs_readdir(struct file *filp, void *dirent, filldir_t filldir)
94 /* If the directory hasn't changed since the last call to readdir(), 77 /* If the directory hasn't changed since the last call to readdir(),
95 * we can jump directly to where we left off. 78 * we can jump directly to where we left off.
96 */ 79 */
97 ino = (u32)(long)filp->private_data; 80 ino = (u32)(long)file->private_data;
98 if (ino && filp->f_version == inode->i_version) { 81 if (ino && file->f_version == inode->i_version) {
99 pr_debug("AFFS: readdir() left off=%d\n", ino); 82 pr_debug("AFFS: readdir() left off=%d\n", ino);
100 goto inside; 83 goto inside;
101 } 84 }
@@ -105,7 +88,7 @@ affs_readdir(struct file *filp, void *dirent, filldir_t filldir)
105 fh_bh = affs_bread(sb, ino); 88 fh_bh = affs_bread(sb, ino);
106 if (!fh_bh) { 89 if (!fh_bh) {
107 affs_error(sb, "readdir","Cannot read block %d", i); 90 affs_error(sb, "readdir","Cannot read block %d", i);
108 goto readdir_out; 91 return -EIO;
109 } 92 }
110 ino = be32_to_cpu(AFFS_TAIL(sb, fh_bh)->hash_chain); 93 ino = be32_to_cpu(AFFS_TAIL(sb, fh_bh)->hash_chain);
111 affs_brelse(fh_bh); 94 affs_brelse(fh_bh);
@@ -119,38 +102,34 @@ affs_readdir(struct file *filp, void *dirent, filldir_t filldir)
119 ino = be32_to_cpu(AFFS_HEAD(dir_bh)->table[hash_pos]); 102 ino = be32_to_cpu(AFFS_HEAD(dir_bh)->table[hash_pos]);
120 if (!ino) 103 if (!ino)
121 continue; 104 continue;
122 f_pos = (hash_pos << 16) + 2; 105 ctx->pos = (hash_pos << 16) + 2;
123inside: 106inside:
124 do { 107 do {
125 fh_bh = affs_bread(sb, ino); 108 fh_bh = affs_bread(sb, ino);
126 if (!fh_bh) { 109 if (!fh_bh) {
127 affs_error(sb, "readdir","Cannot read block %d", ino); 110 affs_error(sb, "readdir","Cannot read block %d", ino);
128 goto readdir_done; 111 break;
129 } 112 }
130 113
131 namelen = min(AFFS_TAIL(sb, fh_bh)->name[0], (u8)30); 114 namelen = min(AFFS_TAIL(sb, fh_bh)->name[0], (u8)30);
132 name = AFFS_TAIL(sb, fh_bh)->name + 1; 115 name = AFFS_TAIL(sb, fh_bh)->name + 1;
133 pr_debug("AFFS: readdir(): filldir(\"%.*s\", ino=%u), hash=%d, f_pos=%x\n", 116 pr_debug("AFFS: readdir(): filldir(\"%.*s\", ino=%u), hash=%d, f_pos=%x\n",
134 namelen, name, ino, hash_pos, f_pos); 117 namelen, name, ino, hash_pos, (u32)ctx->pos);
135 if (filldir(dirent, name, namelen, f_pos, ino, DT_UNKNOWN) < 0) 118 if (!dir_emit(ctx, name, namelen, ino, DT_UNKNOWN))
136 goto readdir_done; 119 goto readdir_done;
137 stored++; 120 ctx->pos++;
138 f_pos++;
139 ino = be32_to_cpu(AFFS_TAIL(sb, fh_bh)->hash_chain); 121 ino = be32_to_cpu(AFFS_TAIL(sb, fh_bh)->hash_chain);
140 affs_brelse(fh_bh); 122 affs_brelse(fh_bh);
141 fh_bh = NULL; 123 fh_bh = NULL;
142 } while (ino); 124 } while (ino);
143 } 125 }
144readdir_done: 126readdir_done:
145 filp->f_pos = f_pos; 127 file->f_version = inode->i_version;
146 filp->f_version = inode->i_version; 128 file->private_data = (void *)(long)ino;
147 filp->private_data = (void *)(long)ino;
148 res = stored;
149 129
150readdir_out: 130readdir_out:
151 affs_brelse(dir_bh); 131 affs_brelse(dir_bh);
152 affs_brelse(fh_bh); 132 affs_brelse(fh_bh);
153 affs_unlock_dir(inode); 133 affs_unlock_dir(inode);
154 pr_debug("AFFS: readdir()=%d\n", stored); 134 return 0;
155 return res;
156} 135}