diff options
Diffstat (limited to 'fs/9p/vfs_dir.c')
-rw-r--r-- | fs/9p/vfs_dir.c | 155 |
1 files changed, 34 insertions, 121 deletions
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 1dd86ee90bc5..0924d4477da3 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -32,11 +32,10 @@ | |||
32 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
33 | #include <linux/inet.h> | 33 | #include <linux/inet.h> |
34 | #include <linux/idr.h> | 34 | #include <linux/idr.h> |
35 | #include <net/9p/9p.h> | ||
36 | #include <net/9p/client.h> | ||
35 | 37 | ||
36 | #include "debug.h" | ||
37 | #include "v9fs.h" | 38 | #include "v9fs.h" |
38 | #include "9p.h" | ||
39 | #include "conv.h" | ||
40 | #include "v9fs_vfs.h" | 39 | #include "v9fs_vfs.h" |
41 | #include "fid.h" | 40 | #include "fid.h" |
42 | 41 | ||
@@ -46,14 +45,14 @@ | |||
46 | * | 45 | * |
47 | */ | 46 | */ |
48 | 47 | ||
49 | static inline int dt_type(struct v9fs_stat *mistat) | 48 | static inline int dt_type(struct p9_stat *mistat) |
50 | { | 49 | { |
51 | unsigned long perm = mistat->mode; | 50 | unsigned long perm = mistat->mode; |
52 | int rettype = DT_REG; | 51 | int rettype = DT_REG; |
53 | 52 | ||
54 | if (perm & V9FS_DMDIR) | 53 | if (perm & P9_DMDIR) |
55 | rettype = DT_DIR; | 54 | rettype = DT_DIR; |
56 | if (perm & V9FS_DMSYMLINK) | 55 | if (perm & P9_DMSYMLINK) |
57 | rettype = DT_LNK; | 56 | rettype = DT_LNK; |
58 | 57 | ||
59 | return rettype; | 58 | return rettype; |
@@ -69,106 +68,36 @@ static inline int dt_type(struct v9fs_stat *mistat) | |||
69 | 68 | ||
70 | static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | 69 | static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) |
71 | { | 70 | { |
72 | struct v9fs_fcall *fcall = NULL; | 71 | int over; |
73 | struct inode *inode = filp->f_path.dentry->d_inode; | 72 | struct p9_fid *fid; |
74 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 73 | struct v9fs_session_info *v9ses; |
75 | struct v9fs_fid *file = filp->private_data; | 74 | struct inode *inode; |
76 | unsigned int i, n, s; | 75 | struct p9_stat *st; |
77 | int fid = -1; | 76 | |
78 | int ret = 0; | 77 | P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); |
79 | struct v9fs_stat stat; | 78 | inode = filp->f_path.dentry->d_inode; |
80 | int over = 0; | 79 | v9ses = v9fs_inode2v9ses(inode); |
81 | 80 | fid = filp->private_data; | |
82 | dprintk(DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); | 81 | while ((st = p9_client_dirread(fid, filp->f_pos)) != NULL) { |
83 | 82 | if (IS_ERR(st)) | |
84 | fid = file->fid; | 83 | return PTR_ERR(st); |
85 | 84 | ||
86 | if (file->rdir_fcall && (filp->f_pos != file->rdir_pos)) { | 85 | over = filldir(dirent, st->name.str, st->name.len, filp->f_pos, |
87 | kfree(file->rdir_fcall); | 86 | v9fs_qid2ino(&st->qid), dt_type(st)); |
88 | file->rdir_fcall = NULL; | 87 | |
89 | } | 88 | if (over) |
90 | |||
91 | if (file->rdir_fcall) { | ||
92 | n = file->rdir_fcall->params.rread.count; | ||
93 | i = file->rdir_fpos; | ||
94 | while (i < n) { | ||
95 | s = v9fs_deserialize_stat( | ||
96 | file->rdir_fcall->params.rread.data + i, | ||
97 | n - i, &stat, v9ses->extended); | ||
98 | |||
99 | if (s == 0) { | ||
100 | dprintk(DEBUG_ERROR, | ||
101 | "error while deserializing stat\n"); | ||
102 | ret = -EIO; | ||
103 | goto FreeStructs; | ||
104 | } | ||
105 | |||
106 | over = filldir(dirent, stat.name.str, stat.name.len, | ||
107 | filp->f_pos, v9fs_qid2ino(&stat.qid), | ||
108 | dt_type(&stat)); | ||
109 | |||
110 | if (over) { | ||
111 | file->rdir_fpos = i; | ||
112 | file->rdir_pos = filp->f_pos; | ||
113 | break; | ||
114 | } | ||
115 | |||
116 | i += s; | ||
117 | filp->f_pos += s; | ||
118 | } | ||
119 | |||
120 | if (!over) { | ||
121 | kfree(file->rdir_fcall); | ||
122 | file->rdir_fcall = NULL; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | while (!over) { | ||
127 | ret = v9fs_t_read(v9ses, fid, filp->f_pos, | ||
128 | v9ses->maxdata-V9FS_IOHDRSZ, &fcall); | ||
129 | if (ret < 0) { | ||
130 | dprintk(DEBUG_ERROR, "error while reading: %d: %p\n", | ||
131 | ret, fcall); | ||
132 | goto FreeStructs; | ||
133 | } else if (ret == 0) | ||
134 | break; | 89 | break; |
135 | 90 | ||
136 | n = ret; | 91 | filp->f_pos += st->size; |
137 | i = 0; | 92 | kfree(st); |
138 | while (i < n) { | 93 | st = NULL; |
139 | s = v9fs_deserialize_stat(fcall->params.rread.data + i, | ||
140 | n - i, &stat, v9ses->extended); | ||
141 | |||
142 | if (s == 0) { | ||
143 | dprintk(DEBUG_ERROR, | ||
144 | "error while deserializing stat\n"); | ||
145 | return -EIO; | ||
146 | } | ||
147 | |||
148 | over = filldir(dirent, stat.name.str, stat.name.len, | ||
149 | filp->f_pos, v9fs_qid2ino(&stat.qid), | ||
150 | dt_type(&stat)); | ||
151 | |||
152 | if (over) { | ||
153 | file->rdir_fcall = fcall; | ||
154 | file->rdir_fpos = i; | ||
155 | file->rdir_pos = filp->f_pos; | ||
156 | fcall = NULL; | ||
157 | break; | ||
158 | } | ||
159 | |||
160 | i += s; | ||
161 | filp->f_pos += s; | ||
162 | } | ||
163 | |||
164 | kfree(fcall); | ||
165 | } | 94 | } |
166 | 95 | ||
167 | FreeStructs: | 96 | kfree(st); |
168 | kfree(fcall); | 97 | return 0; |
169 | return ret; | ||
170 | } | 98 | } |
171 | 99 | ||
100 | |||
172 | /** | 101 | /** |
173 | * v9fs_dir_release - close a directory | 102 | * v9fs_dir_release - close a directory |
174 | * @inode: inode of the directory | 103 | * @inode: inode of the directory |
@@ -178,29 +107,13 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
178 | 107 | ||
179 | int v9fs_dir_release(struct inode *inode, struct file *filp) | 108 | int v9fs_dir_release(struct inode *inode, struct file *filp) |
180 | { | 109 | { |
181 | struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | 110 | struct p9_fid *fid; |
182 | struct v9fs_fid *fid = filp->private_data; | ||
183 | int fidnum = -1; | ||
184 | |||
185 | dprintk(DEBUG_VFS, "inode: %p filp: %p fid: %d\n", inode, filp, | ||
186 | fid->fid); | ||
187 | fidnum = fid->fid; | ||
188 | 111 | ||
112 | fid = filp->private_data; | ||
113 | P9_DPRINTK(P9_DEBUG_VFS, | ||
114 | "inode: %p filp: %p fid: %d\n", inode, filp, fid->fid); | ||
189 | filemap_write_and_wait(inode->i_mapping); | 115 | filemap_write_and_wait(inode->i_mapping); |
190 | 116 | p9_client_clunk(fid); | |
191 | if (fidnum >= 0) { | ||
192 | dprintk(DEBUG_VFS, "fidopen: %d v9f->fid: %d\n", fid->fidopen, | ||
193 | fid->fid); | ||
194 | |||
195 | if (v9fs_t_clunk(v9ses, fidnum)) | ||
196 | dprintk(DEBUG_ERROR, "clunk failed\n"); | ||
197 | |||
198 | kfree(fid->rdir_fcall); | ||
199 | kfree(fid); | ||
200 | |||
201 | filp->private_data = NULL; | ||
202 | } | ||
203 | |||
204 | return 0; | 117 | return 0; |
205 | } | 118 | } |
206 | 119 | ||