From eab72ef27a0ff2376a409ce40390b5c8c1e8727a Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 31 Mar 2005 19:59:12 +0000 Subject: [PATCH] fix --- ChangeLog | 14 ++++++++++++++ kernel/dev.c | 22 ++++++++++++++++++++-- kernel/dir.c | 2 +- kernel/file.c | 6 +++--- kernel/fuse_i.h | 5 ++++- kernel/fuse_kernel.h | 18 +++++++++++++++++- lib/fuse.c | 1 + 7 files changed, 60 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index ba85a21..bf89ea5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2005-03-31 Miklos Szeredi + + * kernel API: add padding to structures, so 64bit and 32bit + compiler will return the same size + + * kernel API: add offset field to fuse_dirent. This will allow + more sophisticated readdir interface for userspace + + * kernel API: change major number to 6 + + * kernel: fix warnings on 64bit archs + + * kernel: in case of API version mismatch, return ECONNREFUSED + 2005-03-24 Miklos Szeredi * kernel: trivial cleanups 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 /** 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]; diff --git a/lib/fuse.c b/lib/fuse.c index 9694239..9a31b15 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -459,6 +459,7 @@ static int fill_dir(struct fuse_dirhandle *dh, const char *name, int type, dirent->namelen = namelen; strncpy(dirent->name, name, namelen); dirent->type = type; + dirent->off = dh->len; dh->len += FUSE_DIRENT_SIZE(dirent); return 0; } -- 2.30.2