diff options
Diffstat (limited to 'fs/9p/vfs_dir.c')
-rw-r--r-- | fs/9p/vfs_dir.c | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index e298fe194093..873cd31baa47 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -45,7 +45,7 @@ | |||
45 | * | 45 | * |
46 | */ | 46 | */ |
47 | 47 | ||
48 | static inline int dt_type(struct p9_stat *mistat) | 48 | static inline int dt_type(struct p9_wstat *mistat) |
49 | { | 49 | { |
50 | unsigned long perm = mistat->mode; | 50 | unsigned long perm = mistat->mode; |
51 | int rettype = DT_REG; | 51 | int rettype = DT_REG; |
@@ -69,32 +69,58 @@ static inline int dt_type(struct p9_stat *mistat) | |||
69 | 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) |
70 | { | 70 | { |
71 | int over; | 71 | int over; |
72 | struct p9_wstat 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, buflen, | ||
89 | fid->rdir_fpos); | ||
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 = p9stat_read(statbuf + i, buflen-i, &st, |
96 | fid->clnt->dotu); | ||
97 | if (err) { | ||
98 | P9_DPRINTK(P9_DEBUG_VFS, "returned %d\n", err); | ||
99 | err = -EIO; | ||
100 | p9stat_free(&st); | ||
101 | goto free_and_exit; | ||
102 | } | ||
103 | |||
104 | i += st.size+2; | ||
105 | fid->rdir_fpos += st.size+2; | ||
106 | |||
107 | over = filldir(dirent, st.name, strlen(st.name), | ||
108 | filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st)); | ||
109 | |||
110 | filp->f_pos += st.size+2; | ||
111 | |||
112 | p9stat_free(&st); | ||
113 | |||
114 | if (over) { | ||
115 | err = 0; | ||
116 | goto free_and_exit; | ||
117 | } | ||
118 | } | ||
94 | } | 119 | } |
95 | 120 | ||
96 | kfree(st); | 121 | free_and_exit: |
97 | return 0; | 122 | kfree(statbuf); |
123 | return err; | ||
98 | } | 124 | } |
99 | 125 | ||
100 | 126 | ||