static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
 {
        int over;
+       struct p9_stat st;
+       int err;
        struct p9_fid *fid;
-       struct v9fs_session_info *v9ses;
-       struct inode *inode;
-       struct p9_stat *st;
+       int buflen;
+       char *statbuf;
+       int n, i = 0;
 
        P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
-       inode = filp->f_path.dentry->d_inode;
-       v9ses = v9fs_inode2v9ses(inode);
        fid = filp->private_data;
-       while ((st = p9_client_dirread(fid, filp->f_pos)) != NULL) {
-               if (IS_ERR(st))
-                       return PTR_ERR(st);
 
-               over = filldir(dirent, st->name.str, st->name.len, filp->f_pos,
-                       v9fs_qid2ino(&st->qid), dt_type(st));
+       buflen = fid->clnt->msize - P9_IOHDRSZ;
+       statbuf = kmalloc(buflen, GFP_KERNEL);
+       if (!statbuf)
+               return -ENOMEM;
 
-               if (over)
+       while (1) {
+               err = v9fs_file_readn(filp, statbuf, NULL, fid->rdir_fpos,
+                                                                       buflen);
+               if (err <= 0)
                        break;
 
-               filp->f_pos += st->size;
-               kfree(st);
-               st = NULL;
+               n = err;
+               while (i < n) {
+                       err = p9_deserialize_stat(statbuf + i, buflen-i, &st,
+                                                       fid->clnt->dotu);
+                       if (!err) {
+                               err = -EIO;
+                               goto free_and_exit;
+                       }
+
+                       i += err;
+                       fid->rdir_fpos += err;
+
+                       over = filldir(dirent, st.name.str, st.name.len,
+                           filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st));
+
+                       filp->f_pos += st.size;
+
+                       if (over) {
+                               err = 0;
+                               goto free_and_exit;
+                       }
+               }
        }
 
-       kfree(st);
-       return 0;
+free_and_exit:
+       kfree(statbuf);
+       return err;
 }
 
 
 
  * @uid: the numeric uid of the local user who owns this handle
  * @aux: transport specific information (unused?)
  * @rdir_fpos: tracks offset of file position when reading directory contents
- * @rdir_pos: (unused?)
- * @rdir_fcall: holds response of last directory read request
  * @flist: per-client-instance fid tracking
  * @dlist: per-dentry fid tracking
  *
        void *aux;
 
        int rdir_fpos;
-       int rdir_pos;
-       struct p9_fcall *rdir_fcall;
        struct list_head flist;
        struct list_head dlist; /* list of all fids attached to a dentry */
 };
                                                        u64 offset, u32 count);
 struct p9_stat *p9_client_stat(struct p9_fid *fid);
 int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst);
-struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset);
 
 struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
 void p9_client_cb(struct p9_client *c, struct p9_req_t *req);
 
        memset(&fid->qid, 0, sizeof(struct p9_qid));
        fid->mode = -1;
        fid->rdir_fpos = 0;
-       fid->rdir_pos = 0;
-       fid->rdir_fcall = NULL;
        fid->uid = current->fsuid;
        fid->clnt = clnt;
        fid->aux = NULL;
        spin_lock(&clnt->lock);
        list_del(&fid->flist);
        spin_unlock(&clnt->lock);
-       kfree(fid->rdir_fcall);
        kfree(fid);
 }
 
        return err;
 }
 EXPORT_SYMBOL(p9_client_wstat);
-
-struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset)
-{
-       int err, n, m;
-       struct p9_fcall *tc, *rc;
-       struct p9_client *clnt;
-       struct p9_stat st, *ret;
-
-       P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu\n", fid->fid,
-                                               (long long unsigned) offset);
-       err = 0;
-       tc = NULL;
-       rc = NULL;
-       ret = NULL;
-       clnt = fid->clnt;
-
-       /* if the offset is below or above the current response, free it */
-       if (offset < fid->rdir_fpos || (fid->rdir_fcall &&
-               offset >= fid->rdir_fpos+fid->rdir_fcall->params.rread.count)) {
-               fid->rdir_pos = 0;
-               if (fid->rdir_fcall)
-                       fid->rdir_fpos += fid->rdir_fcall->params.rread.count;
-
-               kfree(fid->rdir_fcall);
-               fid->rdir_fcall = NULL;
-               if (offset < fid->rdir_fpos)
-                       fid->rdir_fpos = 0;
-       }
-
-       if (!fid->rdir_fcall) {
-               n = fid->iounit;
-               if (!n || n > clnt->msize-P9_IOHDRSZ)
-                       n = clnt->msize - P9_IOHDRSZ;
-
-               while (1) {
-                       if (fid->rdir_fcall) {
-                               fid->rdir_fpos +=
-                                       fid->rdir_fcall->params.rread.count;
-                               kfree(fid->rdir_fcall);
-                               fid->rdir_fcall = NULL;
-                       }
-
-                       tc = p9_create_tread(fid->fid, fid->rdir_fpos, n);
-                       if (IS_ERR(tc)) {
-                               err = PTR_ERR(tc);
-                               tc = NULL;
-                               goto error;
-                       }
-
-                       err = p9_client_rpc(clnt, tc, &rc);
-                       if (err)
-                               goto error;
-
-                       n = rc->params.rread.count;
-                       if (n == 0)
-                               goto done;
-
-                       fid->rdir_fcall = rc;
-                       rc = NULL;
-                       if (offset >= fid->rdir_fpos &&
-                                               offset < fid->rdir_fpos+n)
-                               break;
-               }
-
-               fid->rdir_pos = 0;
-       }
-
-       m = offset - fid->rdir_fpos;
-       if (m < 0)
-               goto done;
-
-       n = p9_deserialize_stat(fid->rdir_fcall->params.rread.data + m,
-               fid->rdir_fcall->params.rread.count - m, &st, clnt->dotu);
-
-       if (!n) {
-               err = -EIO;
-               goto error;
-       }
-
-       fid->rdir_pos += n;
-       st.size = n;
-       ret = p9_clone_stat(&st, clnt->dotu);
-       if (IS_ERR(ret)) {
-               err = PTR_ERR(ret);
-               ret = NULL;
-               goto error;
-       }
-
-done:
-       kfree(tc);
-       kfree(rc);
-       return ret;
-
-error:
-       kfree(tc);
-       kfree(rc);
-       kfree(ret);
-       return ERR_PTR(err);
-}
-EXPORT_SYMBOL(p9_client_dirread);