|
@@ -12,7 +12,7 @@
|
|
#include <linux/slab.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/kernel.h>
|
|
|
|
|
|
-static int fuse_open(struct inode *inode, struct file *file)
|
|
|
|
|
|
+int fuse_open_common(struct inode *inode, struct file *file, int isdir)
|
|
{
|
|
{
|
|
struct fuse_conn *fc = get_fuse_conn(inode);
|
|
struct fuse_conn *fc = get_fuse_conn(inode);
|
|
struct fuse_req *req;
|
|
struct fuse_req *req;
|
|
@@ -56,7 +56,7 @@ static int fuse_open(struct inode *inode, struct file *file)
|
|
|
|
|
|
memset(&inarg, 0, sizeof(inarg));
|
|
memset(&inarg, 0, sizeof(inarg));
|
|
inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
|
|
inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
|
|
- req->in.h.opcode = FUSE_OPEN;
|
|
|
|
|
|
+ req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
|
|
req->in.h.nodeid = get_node_id(inode);
|
|
req->in.h.nodeid = get_node_id(inode);
|
|
req->inode = inode;
|
|
req->inode = inode;
|
|
req->in.numargs = 1;
|
|
req->in.numargs = 1;
|
|
@@ -85,7 +85,7 @@ static int fuse_open(struct inode *inode, struct file *file)
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
-static int fuse_release(struct inode *inode, struct file *file)
|
|
|
|
|
|
+int fuse_release_common(struct inode *inode, struct file *file, int isdir)
|
|
{
|
|
{
|
|
struct fuse_conn *fc = get_fuse_conn(inode);
|
|
struct fuse_conn *fc = get_fuse_conn(inode);
|
|
struct fuse_file *ff = file->private_data;
|
|
struct fuse_file *ff = file->private_data;
|
|
@@ -94,7 +94,7 @@ static int fuse_release(struct inode *inode, struct file *file)
|
|
|
|
|
|
inarg->fh = ff->fh;
|
|
inarg->fh = ff->fh;
|
|
inarg->flags = file->f_flags & ~O_EXCL;
|
|
inarg->flags = file->f_flags & ~O_EXCL;
|
|
- req->in.h.opcode = FUSE_RELEASE;
|
|
|
|
|
|
+ req->in.h.opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE;
|
|
req->in.h.nodeid = get_node_id(inode);
|
|
req->in.h.nodeid = get_node_id(inode);
|
|
req->inode = inode;
|
|
req->inode = inode;
|
|
req->in.numargs = 1;
|
|
req->in.numargs = 1;
|
|
@@ -107,6 +107,16 @@ static int fuse_release(struct inode *inode, struct file *file)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int fuse_open(struct inode *inode, struct file *file)
|
|
|
|
+{
|
|
|
|
+ return fuse_open_common(inode, file, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int fuse_release(struct inode *inode, struct file *file)
|
|
|
|
+{
|
|
|
|
+ return fuse_release_common(inode, file, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
static int fuse_flush(struct file *file)
|
|
static int fuse_flush(struct file *file)
|
|
{
|
|
{
|
|
struct inode *inode = file->f_dentry->d_inode;
|
|
struct inode *inode = file->f_dentry->d_inode;
|
|
@@ -178,8 +188,9 @@ static int fuse_fsync(struct file *file, struct dentry *de, int datasync)
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
-static ssize_t fuse_send_read(struct fuse_req *req, struct file *file,
|
|
|
|
- struct inode *inode, loff_t pos, size_t count)
|
|
|
|
|
|
+size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
|
|
|
|
+ struct inode *inode, loff_t pos, size_t count,
|
|
|
|
+ int isdir)
|
|
{
|
|
{
|
|
struct fuse_conn *fc = get_fuse_conn(inode);
|
|
struct fuse_conn *fc = get_fuse_conn(inode);
|
|
struct fuse_file *ff = file->private_data;
|
|
struct fuse_file *ff = file->private_data;
|
|
@@ -189,7 +200,7 @@ static ssize_t fuse_send_read(struct fuse_req *req, struct file *file,
|
|
inarg.fh = ff->fh;
|
|
inarg.fh = ff->fh;
|
|
inarg.offset = pos;
|
|
inarg.offset = pos;
|
|
inarg.size = count;
|
|
inarg.size = count;
|
|
- req->in.h.opcode = FUSE_READ;
|
|
|
|
|
|
+ req->in.h.opcode = isdir ? FUSE_READDIR : FUSE_READ;
|
|
req->in.h.nodeid = get_node_id(inode);
|
|
req->in.h.nodeid = get_node_id(inode);
|
|
req->inode = inode;
|
|
req->inode = inode;
|
|
req->file = file;
|
|
req->file = file;
|
|
@@ -204,6 +215,13 @@ static ssize_t fuse_send_read(struct fuse_req *req, struct file *file,
|
|
return req->out.args[0].size;
|
|
return req->out.args[0].size;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline size_t fuse_send_read(struct fuse_req *req, struct file *file,
|
|
|
|
+ struct inode *inode, loff_t pos,
|
|
|
|
+ size_t count)
|
|
|
|
+{
|
|
|
|
+ return fuse_send_read_common(req, file, inode, pos, count, 0);
|
|
|
|
+}
|
|
|
|
+
|
|
static int fuse_readpage(struct file *file, struct page *page)
|
|
static int fuse_readpage(struct file *file, struct page *page)
|
|
{
|
|
{
|
|
struct inode *inode = page->mapping->host;
|
|
struct inode *inode = page->mapping->host;
|
|
@@ -293,8 +311,8 @@ static int fuse_readpages(struct file *file, struct address_space *mapping,
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
-static ssize_t fuse_send_write(struct fuse_req *req, struct file *file,
|
|
|
|
- struct inode *inode, loff_t pos, size_t count)
|
|
|
|
|
|
+static size_t fuse_send_write(struct fuse_req *req, struct file *file,
|
|
|
|
+ struct inode *inode, loff_t pos, size_t count)
|
|
{
|
|
{
|
|
struct fuse_conn *fc = get_fuse_conn(inode);
|
|
struct fuse_conn *fc = get_fuse_conn(inode);
|
|
struct fuse_file *ff = file->private_data;
|
|
struct fuse_file *ff = file->private_data;
|
|
@@ -332,7 +350,7 @@ static int fuse_commit_write(struct file *file, struct page *page,
|
|
unsigned offset, unsigned to)
|
|
unsigned offset, unsigned to)
|
|
{
|
|
{
|
|
int err;
|
|
int err;
|
|
- ssize_t nres;
|
|
|
|
|
|
+ size_t nres;
|
|
unsigned count = to - offset;
|
|
unsigned count = to - offset;
|
|
struct inode *inode = page->mapping->host;
|
|
struct inode *inode = page->mapping->host;
|
|
struct fuse_conn *fc = get_fuse_conn(inode);
|
|
struct fuse_conn *fc = get_fuse_conn(inode);
|