Commit 8d3af7f3 authored by Al Viro's avatar Al Viro

[readdir] convert fuse

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 568f8f5e
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/slab.h> #include <linux/slab.h>
static bool fuse_use_readdirplus(struct inode *dir, struct file *filp) static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx)
{ {
struct fuse_conn *fc = get_fuse_conn(dir); struct fuse_conn *fc = get_fuse_conn(dir);
struct fuse_inode *fi = get_fuse_inode(dir); struct fuse_inode *fi = get_fuse_inode(dir);
...@@ -25,7 +25,7 @@ static bool fuse_use_readdirplus(struct inode *dir, struct file *filp) ...@@ -25,7 +25,7 @@ static bool fuse_use_readdirplus(struct inode *dir, struct file *filp)
return true; return true;
if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state)) if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state))
return true; return true;
if (filp->f_pos == 0) if (ctx->pos == 0)
return true; return true;
return false; return false;
} }
...@@ -1165,25 +1165,23 @@ static int fuse_permission(struct inode *inode, int mask) ...@@ -1165,25 +1165,23 @@ static int fuse_permission(struct inode *inode, int mask)
} }
static int parse_dirfile(char *buf, size_t nbytes, struct file *file, static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
void *dstbuf, filldir_t filldir) struct dir_context *ctx)
{ {
while (nbytes >= FUSE_NAME_OFFSET) { while (nbytes >= FUSE_NAME_OFFSET) {
struct fuse_dirent *dirent = (struct fuse_dirent *) buf; struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
size_t reclen = FUSE_DIRENT_SIZE(dirent); size_t reclen = FUSE_DIRENT_SIZE(dirent);
int over;
if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX) if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
return -EIO; return -EIO;
if (reclen > nbytes) if (reclen > nbytes)
break; break;
over = filldir(dstbuf, dirent->name, dirent->namelen, if (!dir_emit(ctx, dirent->name, dirent->namelen,
file->f_pos, dirent->ino, dirent->type); dirent->ino, dirent->type))
if (over)
break; break;
buf += reclen; buf += reclen;
nbytes -= reclen; nbytes -= reclen;
file->f_pos = dirent->off; ctx->pos = dirent->off;
} }
return 0; return 0;
...@@ -1284,7 +1282,7 @@ static int fuse_direntplus_link(struct file *file, ...@@ -1284,7 +1282,7 @@ static int fuse_direntplus_link(struct file *file,
} }
static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
void *dstbuf, filldir_t filldir, u64 attr_version) struct dir_context *ctx, u64 attr_version)
{ {
struct fuse_direntplus *direntplus; struct fuse_direntplus *direntplus;
struct fuse_dirent *dirent; struct fuse_dirent *dirent;
...@@ -1309,10 +1307,9 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, ...@@ -1309,10 +1307,9 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
we need to send a FORGET for each of those we need to send a FORGET for each of those
which we did not link. which we did not link.
*/ */
over = filldir(dstbuf, dirent->name, dirent->namelen, over = !dir_emit(ctx, dirent->name, dirent->namelen,
file->f_pos, dirent->ino, dirent->ino, dirent->type);
dirent->type); ctx->pos = dirent->off;
file->f_pos = dirent->off;
} }
buf += reclen; buf += reclen;
...@@ -1326,7 +1323,7 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, ...@@ -1326,7 +1323,7 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
return 0; return 0;
} }
static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) static int fuse_readdir(struct file *file, struct dir_context *ctx)
{ {
int plus, err; int plus, err;
size_t nbytes; size_t nbytes;
...@@ -1349,17 +1346,17 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) ...@@ -1349,17 +1346,17 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
return -ENOMEM; return -ENOMEM;
} }
plus = fuse_use_readdirplus(inode, file); plus = fuse_use_readdirplus(inode, ctx);
req->out.argpages = 1; req->out.argpages = 1;
req->num_pages = 1; req->num_pages = 1;
req->pages[0] = page; req->pages[0] = page;
req->page_descs[0].length = PAGE_SIZE; req->page_descs[0].length = PAGE_SIZE;
if (plus) { if (plus) {
attr_version = fuse_get_attr_version(fc); attr_version = fuse_get_attr_version(fc);
fuse_read_fill(req, file, file->f_pos, PAGE_SIZE, fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
FUSE_READDIRPLUS); FUSE_READDIRPLUS);
} else { } else {
fuse_read_fill(req, file, file->f_pos, PAGE_SIZE, fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
FUSE_READDIR); FUSE_READDIR);
} }
fuse_request_send(fc, req); fuse_request_send(fc, req);
...@@ -1369,11 +1366,11 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir) ...@@ -1369,11 +1366,11 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
if (!err) { if (!err) {
if (plus) { if (plus) {
err = parse_dirplusfile(page_address(page), nbytes, err = parse_dirplusfile(page_address(page), nbytes,
file, dstbuf, filldir, file, ctx,
attr_version); attr_version);
} else { } else {
err = parse_dirfile(page_address(page), nbytes, file, err = parse_dirfile(page_address(page), nbytes, file,
dstbuf, filldir); ctx);
} }
} }
...@@ -1886,7 +1883,7 @@ static const struct inode_operations fuse_dir_inode_operations = { ...@@ -1886,7 +1883,7 @@ static const struct inode_operations fuse_dir_inode_operations = {
static const struct file_operations fuse_dir_operations = { static const struct file_operations fuse_dir_operations = {
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
.read = generic_read_dir, .read = generic_read_dir,
.readdir = fuse_readdir, .iterate = fuse_readdir,
.open = fuse_dir_open, .open = fuse_dir_open,
.release = fuse_dir_release, .release = fuse_dir_release,
.fsync = fuse_dir_fsync, .fsync = fuse_dir_fsync,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment