fix
authorMiklos Szeredi <miklos@szeredi.hu>
Thu, 31 Mar 2005 19:59:12 +0000 (19:59 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Thu, 31 Mar 2005 19:59:12 +0000 (19:59 +0000)
ChangeLog
kernel/dev.c
kernel/dir.c
kernel/file.c
kernel/fuse_i.h
kernel/fuse_kernel.h
lib/fuse.c

index ba85a21db8f4ab61fb7bd7ce73cc304e500c3b90..bf89ea54e3aad916763ef76b18a1b62dbbc709c7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2005-03-31  Miklos Szeredi <miklos@szeredi.hu>
+
+       * 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 <miklos@szeredi.hu>
 
        * kernel: trivial cleanups
index b17296a49355130a3ecf2f8257d6817304195c1d..29a9b6366139295df36c648a9eb9c84c570e5e90 100644 (file)
@@ -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
index a7507fec834d7a1be2f91d9c1b0dd65d140260d2..ecd610882938875a9ffb937681b70c26731e61d3 100644 (file)
@@ -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;
 
index 0865ab0aed6e4a3864a8cb08837e132eb2f9b2a2..a88654637668db69f1293cdd7ab105dfbb635a49 100644 (file)
@@ -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) {
index fb94ebbc36e07ad9b1aae567ba417fe5bda7a27f..1dd0d10983ddd468128ad1be480c4f31bea36313 100644 (file)
@@ -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,
index 2f313eb872c8abda7cacba4ed2622463567f6fc0..3c0696796ca6fef0999c0f765b0c60a4400fe1b2 100644 (file)
@@ -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];
index 9694239fd41f5ebc1d76a7ca26dc48362d0c49e9..9a31b15c4003dd7cc0121d32b2fd5adceeb821f0 100644 (file)
@@ -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;
 }