aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/file.c
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2005-09-09 16:10:36 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 17:03:47 -0400
commit04730fef1f9c7277e5c730b193e681ac095b0507 (patch)
tree3694ea435eb38f10dadc5c8b6abd603a7e10f52e /fs/fuse/file.c
parent413ef8cb302511d8e995e2b0e5517ee1a65b9c77 (diff)
[PATCH] fuse: transfer readdir data through device
This patch removes a long lasting "hack" in FUSE, which used a separate channel (a file descriptor refering to a disk-file) to transfer directory contents from userspace to the kernel. The patch adds three new operations (OPENDIR, READDIR, RELEASEDIR), which have semantics and implementation exactly maching the respective file operations (OPEN, READ, RELEASE). This simplifies the directory reading code. Also disk space is not necessary, which can be important in embedded systems. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/fuse/file.c')
-rw-r--r--fs/fuse/file.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 6bc3fb26de39..224453557cf6 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -12,7 +12,7 @@
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14 14
15static int fuse_open(struct inode *inode, struct file *file) 15int fuse_open_common(struct inode *inode, struct file *file, int isdir)
16{ 16{
17 struct fuse_conn *fc = get_fuse_conn(inode); 17 struct fuse_conn *fc = get_fuse_conn(inode);
18 struct fuse_req *req; 18 struct fuse_req *req;
@@ -56,7 +56,7 @@ static int fuse_open(struct inode *inode, struct file *file)
56 56
57 memset(&inarg, 0, sizeof(inarg)); 57 memset(&inarg, 0, sizeof(inarg));
58 inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); 58 inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
59 req->in.h.opcode = FUSE_OPEN; 59 req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
60 req->in.h.nodeid = get_node_id(inode); 60 req->in.h.nodeid = get_node_id(inode);
61 req->inode = inode; 61 req->inode = inode;
62 req->in.numargs = 1; 62 req->in.numargs = 1;
@@ -85,7 +85,7 @@ static int fuse_open(struct inode *inode, struct file *file)
85 return err; 85 return err;
86} 86}
87 87
88static int fuse_release(struct inode *inode, struct file *file) 88int fuse_release_common(struct inode *inode, struct file *file, int isdir)
89{ 89{
90 struct fuse_conn *fc = get_fuse_conn(inode); 90 struct fuse_conn *fc = get_fuse_conn(inode);
91 struct fuse_file *ff = file->private_data; 91 struct fuse_file *ff = file->private_data;
@@ -94,7 +94,7 @@ static int fuse_release(struct inode *inode, struct file *file)
94 94
95 inarg->fh = ff->fh; 95 inarg->fh = ff->fh;
96 inarg->flags = file->f_flags & ~O_EXCL; 96 inarg->flags = file->f_flags & ~O_EXCL;
97 req->in.h.opcode = FUSE_RELEASE; 97 req->in.h.opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE;
98 req->in.h.nodeid = get_node_id(inode); 98 req->in.h.nodeid = get_node_id(inode);
99 req->inode = inode; 99 req->inode = inode;
100 req->in.numargs = 1; 100 req->in.numargs = 1;
@@ -107,6 +107,16 @@ static int fuse_release(struct inode *inode, struct file *file)
107 return 0; 107 return 0;
108} 108}
109 109
110static int fuse_open(struct inode *inode, struct file *file)
111{
112 return fuse_open_common(inode, file, 0);
113}
114
115static int fuse_release(struct inode *inode, struct file *file)
116{
117 return fuse_release_common(inode, file, 0);
118}
119
110static int fuse_flush(struct file *file) 120static int fuse_flush(struct file *file)
111{ 121{
112 struct inode *inode = file->f_dentry->d_inode; 122 struct inode *inode = file->f_dentry->d_inode;
@@ -178,8 +188,9 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
178 return err; 188 return err;
179} 189}
180 190
181static ssize_t fuse_send_read(struct fuse_req *req, struct file *file, 191size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
182 struct inode *inode, loff_t pos, size_t count) 192 struct inode *inode, loff_t pos, size_t count,
193 int isdir)
183{ 194{
184 struct fuse_conn *fc = get_fuse_conn(inode); 195 struct fuse_conn *fc = get_fuse_conn(inode);
185 struct fuse_file *ff = file->private_data; 196 struct fuse_file *ff = file->private_data;
@@ -189,7 +200,7 @@ static ssize_t fuse_send_read(struct fuse_req *req, struct file *file,
189 inarg.fh = ff->fh; 200 inarg.fh = ff->fh;
190 inarg.offset = pos; 201 inarg.offset = pos;
191 inarg.size = count; 202 inarg.size = count;
192 req->in.h.opcode = FUSE_READ; 203 req->in.h.opcode = isdir ? FUSE_READDIR : FUSE_READ;
193 req->in.h.nodeid = get_node_id(inode); 204 req->in.h.nodeid = get_node_id(inode);
194 req->inode = inode; 205 req->inode = inode;
195 req->file = file; 206 req->file = file;
@@ -204,6 +215,13 @@ static ssize_t fuse_send_read(struct fuse_req *req, struct file *file,
204 return req->out.args[0].size; 215 return req->out.args[0].size;
205} 216}
206 217
218static inline size_t fuse_send_read(struct fuse_req *req, struct file *file,
219 struct inode *inode, loff_t pos,
220 size_t count)
221{
222 return fuse_send_read_common(req, file, inode, pos, count, 0);
223}
224
207static int fuse_readpage(struct file *file, struct page *page) 225static int fuse_readpage(struct file *file, struct page *page)
208{ 226{
209 struct inode *inode = page->mapping->host; 227 struct inode *inode = page->mapping->host;
@@ -293,8 +311,8 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
293 return err; 311 return err;
294} 312}
295 313
296static ssize_t fuse_send_write(struct fuse_req *req, struct file *file, 314static size_t fuse_send_write(struct fuse_req *req, struct file *file,
297 struct inode *inode, loff_t pos, size_t count) 315 struct inode *inode, loff_t pos, size_t count)
298{ 316{
299 struct fuse_conn *fc = get_fuse_conn(inode); 317 struct fuse_conn *fc = get_fuse_conn(inode);
300 struct fuse_file *ff = file->private_data; 318 struct fuse_file *ff = file->private_data;
@@ -332,7 +350,7 @@ static int fuse_commit_write(struct file *file, struct page *page,
332 unsigned offset, unsigned to) 350 unsigned offset, unsigned to)
333{ 351{
334 int err; 352 int err;
335 ssize_t nres; 353 size_t nres;
336 unsigned count = to - offset; 354 unsigned count = to - offset;
337 struct inode *inode = page->mapping->host; 355 struct inode *inode = page->mapping->host;
338 struct fuse_conn *fc = get_fuse_conn(inode); 356 struct fuse_conn *fc = get_fuse_conn(inode);