[readdir] convert 9p

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2013-05-17 17:51:41 -04:00
parent 0edf977d2a
commit 8f29843a51

View file

@ -101,16 +101,15 @@ static struct p9_rdir *v9fs_alloc_rdir_buf(struct file *filp, int buflen)
} }
/** /**
* v9fs_dir_readdir - read a directory * v9fs_dir_readdir - iterate through a directory
* @filp: opened file structure * @file: opened file structure
* @dirent: directory structure ??? * @ctx: actor we feed the entries to
* @filldir: function to populate directory structure ???
* *
*/ */
static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir) static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
{ {
int over; bool over;
struct p9_wstat st; struct p9_wstat st;
int err = 0; int err = 0;
struct p9_fid *fid; struct p9_fid *fid;
@ -118,19 +117,19 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
int reclen = 0; int reclen = 0;
struct p9_rdir *rdir; struct p9_rdir *rdir;
p9_debug(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); p9_debug(P9_DEBUG_VFS, "name %s\n", file->f_path.dentry->d_name.name);
fid = filp->private_data; fid = file->private_data;
buflen = fid->clnt->msize - P9_IOHDRSZ; buflen = fid->clnt->msize - P9_IOHDRSZ;
rdir = v9fs_alloc_rdir_buf(filp, buflen); rdir = v9fs_alloc_rdir_buf(file, buflen);
if (!rdir) if (!rdir)
return -ENOMEM; return -ENOMEM;
while (1) { while (1) {
if (rdir->tail == rdir->head) { if (rdir->tail == rdir->head) {
err = v9fs_file_readn(filp, rdir->buf, NULL, err = v9fs_file_readn(file, rdir->buf, NULL,
buflen, filp->f_pos); buflen, ctx->pos);
if (err <= 0) if (err <= 0)
return err; return err;
@ -148,51 +147,45 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
} }
reclen = st.size+2; reclen = st.size+2;
over = filldir(dirent, st.name, strlen(st.name), over = !dir_emit(ctx, st.name, strlen(st.name),
filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st)); v9fs_qid2ino(&st.qid), dt_type(&st));
p9stat_free(&st); p9stat_free(&st);
if (over) if (over)
return 0; return 0;
rdir->head += reclen; rdir->head += reclen;
filp->f_pos += reclen; ctx->pos += reclen;
} }
} }
} }
/** /**
* v9fs_dir_readdir_dotl - read a directory * v9fs_dir_readdir_dotl - iterate through a directory
* @filp: opened file structure * @file: opened file structure
* @dirent: buffer to fill dirent structures * @ctx: actor we feed the entries to
* @filldir: function to populate dirent structures
* *
*/ */
static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent, static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx)
filldir_t filldir)
{ {
int over;
int err = 0; int err = 0;
struct p9_fid *fid; struct p9_fid *fid;
int buflen; int buflen;
struct p9_rdir *rdir; struct p9_rdir *rdir;
struct p9_dirent curdirent; struct p9_dirent curdirent;
u64 oldoffset = 0;
p9_debug(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name); p9_debug(P9_DEBUG_VFS, "name %s\n", file->f_path.dentry->d_name.name);
fid = filp->private_data; fid = file->private_data;
buflen = fid->clnt->msize - P9_READDIRHDRSZ; buflen = fid->clnt->msize - P9_READDIRHDRSZ;
rdir = v9fs_alloc_rdir_buf(filp, buflen); rdir = v9fs_alloc_rdir_buf(file, buflen);
if (!rdir) if (!rdir)
return -ENOMEM; return -ENOMEM;
while (1) { while (1) {
if (rdir->tail == rdir->head) { if (rdir->tail == rdir->head) {
err = p9_client_readdir(fid, rdir->buf, buflen, err = p9_client_readdir(fid, rdir->buf, buflen,
filp->f_pos); ctx->pos);
if (err <= 0) if (err <= 0)
return err; return err;
@ -210,22 +203,13 @@ static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent,
return -EIO; return -EIO;
} }
/* d_off in dirent structure tracks the offset into if (!dir_emit(ctx, curdirent.d_name,
* the next dirent in the dir. However, filldir() strlen(curdirent.d_name),
* expects offset into the current dirent. Hence v9fs_qid2ino(&curdirent.qid),
* while calling filldir send the offset from the curdirent.d_type))
* previous dirent structure.
*/
over = filldir(dirent, curdirent.d_name,
strlen(curdirent.d_name),
oldoffset, v9fs_qid2ino(&curdirent.qid),
curdirent.d_type);
oldoffset = curdirent.d_off;
if (over)
return 0; return 0;
filp->f_pos = curdirent.d_off; ctx->pos = curdirent.d_off;
rdir->head += err; rdir->head += err;
} }
} }
@ -254,7 +238,7 @@ int v9fs_dir_release(struct inode *inode, struct file *filp)
const struct file_operations v9fs_dir_operations = { const struct file_operations v9fs_dir_operations = {
.read = generic_read_dir, .read = generic_read_dir,
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
.readdir = v9fs_dir_readdir, .iterate = v9fs_dir_readdir,
.open = v9fs_file_open, .open = v9fs_file_open,
.release = v9fs_dir_release, .release = v9fs_dir_release,
}; };
@ -262,7 +246,7 @@ const struct file_operations v9fs_dir_operations = {
const struct file_operations v9fs_dir_operations_dotl = { const struct file_operations v9fs_dir_operations_dotl = {
.read = generic_read_dir, .read = generic_read_dir,
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
.readdir = v9fs_dir_readdir_dotl, .iterate = v9fs_dir_readdir_dotl,
.open = v9fs_file_open, .open = v9fs_file_open,
.release = v9fs_dir_release, .release = v9fs_dir_release,
.fsync = v9fs_file_fsync_dotl, .fsync = v9fs_file_fsync_dotl,