aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/vfs_dir.c
diff options
context:
space:
mode:
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 e298fe194093..d7d0ac5a2ca3 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