aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <miklos@szeredi.hu>2005-03-31 19:59:12 +0000
committerGravatar Miklos Szeredi <miklos@szeredi.hu>2005-03-31 19:59:12 +0000
commiteab72ef27a0ff2376a409ce40390b5c8c1e8727a (patch)
treee187c04157a6c8d6106bd48ff7c36cae7a94e163 /kernel
parent407e6a7297a7e126182934c53946eac44fe6b54b (diff)
fix
Diffstat (limited to 'kernel')
-rw-r--r--kernel/dev.c22
-rw-r--r--kernel/dir.c2
-rw-r--r--kernel/file.c6
-rw-r--r--kernel/fuse_i.h5
-rw-r--r--kernel/fuse_kernel.h18
5 files changed, 45 insertions, 8 deletions
diff --git a/kernel/dev.c b/kernel/dev.c
index b17296a..29a9b63 100644
--- a/kernel/dev.c
+++ b/kernel/dev.c
@@ -221,6 +221,10 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
wake_up(&req->waitq);
if (req->in.h.opcode == FUSE_INIT) {
int i;
+
+ if (req->misc.init_in_out.major != FUSE_KERNEL_VERSION)
+ fc->conn_error = 1;
+
/* After INIT reply is received other requests can go
out. So do (FUSE_MAX_OUTSTANDING - 1) number of
up()s on outstanding_sem. The last up() is done in
@@ -367,8 +371,11 @@ static void request_send_wait(struct fuse_conn *fc, struct fuse_req *req,
{
req->isreply = 1;
spin_lock(&fuse_lock);
- req->out.h.error = -ENOTCONN;
- if (fc->file) {
+ if (!fc->file)
+ req->out.h.error = -ENOTCONN;
+ else if (fc->conn_error)
+ req->out.h.error = -ECONNREFUSED;
+ else {
queue_request(fc, req);
/* acquire extra reference, since request is still needed
after request_end() */
@@ -665,6 +672,17 @@ static void request_wait(struct fuse_conn *fc)
remove_wait_queue(&fc->waitq, &wait);
}
+#ifndef KERNEL_2_6
+static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs)
+{
+ unsigned long seg;
+ size_t ret = 0;
+
+ for (seg = 0; seg < nr_segs; seg++)
+ ret += iov[seg].iov_len;
+ return ret;
+}
+#endif
/*
* Read a single request into the userspace filesystem's buffer. This
* function waits until a request is available, then removes it from
diff --git a/kernel/dir.c b/kernel/dir.c
index a7507fe..ecd6108 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -512,7 +512,7 @@ static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
break;
over = filldir(dstbuf, dirent->name, dirent->namelen,
- file->f_pos, dirent->ino, dirent->type);
+ dirent->off, dirent->ino, dirent->type);
if (over)
break;
diff --git a/kernel/file.c b/kernel/file.c
index 0865ab0..a886546 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -528,7 +528,7 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
{
struct inode *inode = file->f_dentry->d_inode;
struct fuse_conn *fc = get_fuse_conn(inode);
- unsigned nmax = write ? fc->max_write : fc->max_read;
+ size_t nmax = write ? fc->max_write : fc->max_read;
loff_t pos = *ppos;
ssize_t res = 0;
struct fuse_req *req = fuse_get_request(fc);
@@ -536,8 +536,8 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
return -ERESTARTSYS;
while (count) {
- unsigned tmp;
- unsigned nres;
+ size_t tmp;
+ size_t nres;
size_t nbytes = min(count, nmax);
int err = fuse_get_user_pages(req, buf, nbytes, !write);
if (err) {
diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h
index fb94ebb..1dd0d10 100644
--- a/kernel/fuse_i.h
+++ b/kernel/fuse_i.h
@@ -328,6 +328,9 @@ struct fuse_conn {
/** Is removexattr not implemented by fs? */
unsigned no_removexattr : 1;
+ /** Connection failed (version mismatch) */
+ unsigned conn_error : 1;
+
#ifdef KERNEL_2_6
/** Backing dev info */
struct backing_dev_info bdi;
@@ -410,7 +413,7 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir);
*/
int fuse_release_common(struct inode *inode, struct file *file, int isdir);
-/**
+/**
* Send FSYNC or FSYNCDIR request
*/
int fuse_fsync_common(struct file *file, struct dentry *de, int datasync,
diff --git a/kernel/fuse_kernel.h b/kernel/fuse_kernel.h
index 2f313eb..3c06967 100644
--- a/kernel/fuse_kernel.h
+++ b/kernel/fuse_kernel.h
@@ -11,7 +11,7 @@
#include <asm/types.h>
/** Version number of this interface */
-#define FUSE_KERNEL_VERSION 5
+#define FUSE_KERNEL_VERSION 6
/** Minor version number of this interface */
#define FUSE_KERNEL_MINOR_VERSION 1
@@ -25,6 +25,9 @@
/** The minor number of the fuse character device */
#define FUSE_MINOR 229
+/* Make sure all structures are padded to 64bit boundary, so 32bit
+ userspace works under 64bit kernels */
+
struct fuse_attr {
__u64 ino;
__u64 size;
@@ -127,6 +130,7 @@ struct fuse_mknod_in {
struct fuse_mkdir_in {
__u32 mode;
+ __u32 padding;
};
struct fuse_rename_in {
@@ -139,32 +143,38 @@ struct fuse_link_in {
struct fuse_setattr_in {
__u32 valid;
+ __u32 padding;
struct fuse_attr attr;
};
struct fuse_open_in {
__u32 flags;
+ __u32 padding;
};
struct fuse_open_out {
__u64 fh;
__u32 open_flags;
+ __u32 padding;
};
struct fuse_release_in {
__u64 fh;
__u32 flags;
+ __u32 padding;
};
struct fuse_flush_in {
__u64 fh;
__u32 flush_flags;
+ __u32 padding;
};
struct fuse_read_in {
__u64 fh;
__u64 offset;
__u32 size;
+ __u32 padding;
};
struct fuse_write_in {
@@ -176,6 +186,7 @@ struct fuse_write_in {
struct fuse_write_out {
__u32 size;
+ __u32 padding;
};
struct fuse_statfs_out {
@@ -185,6 +196,7 @@ struct fuse_statfs_out {
struct fuse_fsync_in {
__u64 fh;
__u32 fsync_flags;
+ __u32 padding;
};
struct fuse_setxattr_in {
@@ -194,10 +206,12 @@ struct fuse_setxattr_in {
struct fuse_getxattr_in {
__u32 size;
+ __u32 padding;
};
struct fuse_getxattr_out {
__u32 size;
+ __u32 padding;
};
struct fuse_init_in_out {
@@ -213,6 +227,7 @@ struct fuse_in_header {
__u32 uid;
__u32 gid;
__u32 pid;
+ __u32 padding;
};
struct fuse_out_header {
@@ -223,6 +238,7 @@ struct fuse_out_header {
struct fuse_dirent {
__u64 ino;
+ __u64 off;
__u32 namelen;
__u32 type;
char name[0];