aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/vfs_dir.c
diff options
context:
space:
mode:
authorEric Van Hensbergen <ericvh@gmail.com>2008-10-13 21:36:15 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2008-10-17 12:04:43 -0400
commit06b55b464ee5b305aca75cb7d9424b184bf07f68 (patch)
treefb2bba4546ad4b800f1e49a75774b01fc6fcdb6b /fs/9p/vfs_dir.c
parentdfb0ec2e13a906ff19a0bbfa9208caab50cfc2e3 (diff)
9p: move dirread to fs layer
Currently reading a directory is implemented in the client code. This function is not actually a wire operation, but a meta operation which calls read operations and processes the results. This patch moves this functionality to the fs layer and calls component wire operations instead of constructing their packets. This provides a cleaner separation and will help when we reorganize the client functions and protocol processing methods. Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'fs/9p/vfs_dir.c')
-rw-r--r--fs/9p/vfs_dir.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index e298fe19409..d7d0ac5a2ca 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -69,32 +69,54 @@ static inline int dt_type(struct p9_stat *mistat)
69static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) 69static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
70{ 70{
71 int over; 71 int over;
72 struct p9_stat st;
73 int err;
72 struct p9_fid *fid; 74 struct p9_fid *fid;
73 struct v9fs_session_info *v9ses; 75 int buflen;
74 struct inode *inode; 76 char *statbuf;
75 struct p9_stat *st; 77 int n, i = 0;
76 78
77 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); 79 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
78 inode = filp->f_path.dentry->d_inode;
79 v9ses = v9fs_inode2v9ses(inode);
80 fid = filp->private_data; 80 fid = filp->private_data;
81 while ((st = p9_client_dirread(fid, filp->f_pos)) != NULL) {
82 if (IS_ERR(st))
83 return PTR_ERR(st);
84 81
85 over = filldir(dirent, st->name.str, st->name.len, filp->f_pos, 82 buflen = fid->clnt->msize - P9_IOHDRSZ;
86 v9fs_qid2ino(&st->qid), dt_type(st)); 83 statbuf = kmalloc(buflen, GFP_KERNEL);
84 if (!statbuf)
85 return -ENOMEM;
87 86
88 if (over) 87 while (1) {
88 err = v9fs_file_readn(filp, statbuf, NULL, fid->rdir_fpos,
89 buflen);
90 if (err <= 0)
89 break; 91 break;
90 92
91 filp->f_pos += st->size; 93 n = err;
92 kfree(st); 94 while (i < n) {
93 st = NULL; 95 err = p9_deserialize_stat(statbuf + i, buflen-i, &st,
96 fid->clnt->dotu);
97 if (!err) {
98 err = -EIO;
99 goto free_and_exit;
100 }
101
102 i += err;
103 fid->rdir_fpos += err;
104
105 over = filldir(dirent, st.name.str, st.name.len,
106 filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st));
107
108 filp->f_pos += st.size;
109
110 if (over) {
111 err = 0;
112 goto free_and_exit;
113 }
114 }
94 } 115 }
95 116
96 kfree(st); 117free_and_exit:
97 return 0; 118 kfree(statbuf);
119 return err;
98} 120}
99 121
100 122