From 06b55b464ee5b305aca75cb7d9424b184bf07f68 Mon Sep 17 00:00:00 2001 From: Eric Van Hensbergen Date: Mon, 13 Oct 2008 20:36:15 -0500 Subject: 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 --- fs/9p/vfs_dir.c | 54 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 16 deletions(-) (limited to 'fs/9p/vfs_dir.c') 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) 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; } -- cgit From 51a87c552dfd428e304c865e24ecbe091556f226 Mon Sep 17 00:00:00 2001 From: Eric Van Hensbergen Date: Thu, 16 Oct 2008 08:30:07 -0500 Subject: 9p: rework client code to use new protocol support functions Now that the new protocol functions are in place, this patch switches the client code to using the new support code. Signed-off-by: Eric Van Hensbergen --- fs/9p/vfs_dir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'fs/9p/vfs_dir.c') diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index d7d0ac5a2ca..276aed62592 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c @@ -85,8 +85,8 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) return -ENOMEM; while (1) { - err = v9fs_file_readn(filp, statbuf, NULL, fid->rdir_fpos, - buflen); + err = v9fs_file_readn(filp, statbuf, NULL, buflen, + fid->rdir_fpos); if (err <= 0) break; -- cgit From 02da398b950c5d079c20afaa23f322383e96070a Mon Sep 17 00:00:00 2001 From: Eric Van Hensbergen Date: Thu, 16 Oct 2008 08:29:30 -0500 Subject: 9p: eliminate depricated conv functions Remove depricated conv functions which have been replaced with new protocol routines. This patch also reworks the one instance of the file-system code which directly calls conversion routines (to accomplish unpacking dirreads). Signed-off-by: Eric Van Hensbergen --- fs/9p/vfs_dir.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'fs/9p/vfs_dir.c') diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index 276aed62592..873cd31baa4 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c @@ -45,7 +45,7 @@ * */ -static inline int dt_type(struct p9_stat *mistat) +static inline int dt_type(struct p9_wstat *mistat) { unsigned long perm = mistat->mode; int rettype = DT_REG; @@ -69,7 +69,7 @@ static inline int dt_type(struct p9_stat *mistat) static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) { int over; - struct p9_stat st; + struct p9_wstat st; int err; struct p9_fid *fid; int buflen; @@ -92,20 +92,24 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) n = err; while (i < n) { - err = p9_deserialize_stat(statbuf + i, buflen-i, &st, + err = p9stat_read(statbuf + i, buflen-i, &st, fid->clnt->dotu); - if (!err) { + if (err) { + P9_DPRINTK(P9_DEBUG_VFS, "returned %d\n", err); err = -EIO; + p9stat_free(&st); goto free_and_exit; } - i += err; - fid->rdir_fpos += err; + i += st.size+2; + fid->rdir_fpos += st.size+2; - over = filldir(dirent, st.name.str, st.name.len, + over = filldir(dirent, st.name, strlen(st.name), filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st)); - filp->f_pos += st.size; + filp->f_pos += st.size+2; + + p9stat_free(&st); if (over) { err = 0; -- cgit