merge to 2_0_merge4
diff --git a/ChangeLog b/ChangeLog
index 0173f98..c9a090d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,15 @@
 
 	* kernel: make readpage() uninterruptible
 
+	* kernel: check readonly filesystem flag in fuse_permission
+
+	* lib: don't die if version file not found and new style device
+	exists
+
+	* lib: add '-r' option, which is short for '-o ro'
+
+	* fusermount: simplify device opening
+
 	* kernel: when direct_io is turend on, copy data directly to
 	destination without itermediate buffer.  More efficient and safer,
 	since no allocation is done.
diff --git a/kernel/dir.c b/kernel/dir.c
index fe8e803..19834b4 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -633,8 +633,15 @@
 		   keeping it open... */
 
 		return err;
-	} else
+	} else {
+		int mode = inode->i_mode;
+		if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
+                    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
+                        return -EROFS;
+		if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
+			return -EACCES;
 		return 0;
+	}
 }
 
 static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
diff --git a/lib/helper.c b/lib/helper.c
index b8c73be..b4d437f 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -25,6 +25,7 @@
             "    -d                  enable debug output (implies -f)\n"
             "    -f                  foreground operation\n"
             "    -s                  disable multithreaded operation\n"
+            "    -r                  mount read only (equivalent to '-o ro')\n"
             "    -o opt,[opt...]     mount options\n"
             "    -h                  print help\n"
             "\n"
@@ -187,6 +188,12 @@
                     *background = 0;
                     break;
                     
+                case 'r':
+                    res = add_options(lib_opts, kernel_opts, "ro");
+                    if (res == -1)
+                        goto err;
+                    break;
+
                 case 'f':
                     *background = 0;
                     break;
diff --git a/util/fusermount.c b/util/fusermount.c
index d8490db..ddf8603 100644
--- a/util/fusermount.c
+++ b/util/fusermount.c
@@ -39,9 +39,10 @@
 
 #define FUSE_DEV_OLD "/proc/fs/fuse/dev"
 #define FUSE_DEV_NEW "/dev/fuse"
-#define FUSE_SYS_DEV "/sys/class/misc/fuse/dev"
 #define FUSE_VERSION_FILE_OLD "/proc/fs/fuse/version"
 #define FUSE_VERSION_FILE_NEW "/sys/fs/fuse/version"
+#define FUSE_MAJOR 10
+#define FUSE_MINOR 229
 
 const char *progname;
 
@@ -520,20 +521,18 @@
     if (strcmp(dev, FUSE_DEV_OLD) == 0)
         isold = 1;
 
-    if (isold)
-        version_file = FUSE_VERSION_FILE_OLD;
-    else
-        version_file = FUSE_VERSION_FILE_NEW;
-
+    version_file = FUSE_VERSION_FILE_NEW;
     vf = fopen(version_file, "r");
     if (vf == NULL) {
-        if (isold) {
-            fprintf(stderr, "%s: kernel interface too old\n", progname);
-            return -1;
-        } else
-            /* If /sys/fs/fuse/version doesn't exist, just skip
-               version checking */
-            return 0;
+        version_file = FUSE_VERSION_FILE_OLD;
+        vf = fopen(version_file, "r");
+        if (vf == NULL) {
+            if (isold) {
+                fprintf(stderr, "%s: kernel interface too old\n", progname);
+                return -1;
+            } else
+                return 0;
+        }
     }
     res = fscanf(vf, "%i.%i", &majorver, &minorver);
     fclose(vf);
@@ -628,7 +627,7 @@
 #define FUSE_TMP_DIRNAME "/tmp/.fuse_devXXXXXX"
 #define FUSE_TMP_DEVNAME "/fuse"
 
-static int try_open_new_temp(unsigned devnum, char **devp, int silent)
+static int try_open_new_temp(unsigned devnum, char **devp)
 {
     int res;
     int fd;
@@ -647,68 +646,29 @@
         rmdir(dirname);
         return -1;
     }
-    fd = try_open(filename, devp, silent);
+    fd = try_open(filename, devp, 0);
     unlink(filename);
     rmdir(dirname);
     return fd;
 }
 
-static int try_open_new(char **devp, int final)
+static int try_open_fuse_device(char **devp)
 {
-    const char *dev;
-    unsigned minor;
-    unsigned major;
-    int res;
-    struct stat stbuf;
-    unsigned devnum;
-    char buf[256];
-    int fd = open(FUSE_SYS_DEV, O_RDONLY);
+    int fd = try_open(FUSE_DEV_NEW, devp, 1);
+    if (fd >= 0)
+        return fd;
+    
     if (fd == -1) {
-        if (!final)
-            return -2;
-        fd = try_open(FUSE_DEV_NEW, devp, 1);
-        if (fd == -2)
-            return -2;
-        fd = try_open_new_temp(FUSE_MAJOR << 8 | FUSE_MINOR, devp, 1);
-        if (fd == -2)
-            return -2;
-        return try_open(FUSE_DEV_NEW, devp, 0);
-    }
-
-    res = read(fd, buf, sizeof(buf)-1);
-    close(fd);
-    if (res == -1) {
-        fprintf(stderr, "%s: failed to read from %s: %s\n", progname,
-                FUSE_SYS_DEV, strerror(errno));
-        return -1;
+        fd = try_open_new_temp(FUSE_MAJOR << 8 | FUSE_MINOR, devp);
+        if (fd != -2)
+            return fd;
     }
     
-    buf[res] = '\0';
-    if (sscanf(buf, "%u:%u", &major, &minor) != 2) {
-        fprintf(stderr, "%s: parse error reading from %s\n", progname,
-                FUSE_SYS_DEV);
-        return -1;
-    }
+    fd = try_open(FUSE_DEV_OLD, devp, 1);
+    if (fd >= 0)
+        return fd;
 
-    devnum = (major << 8) + (minor & 0xff) + ((minor & 0xff00) << 12);
-    dev = FUSE_DEV_NEW;
-    res = stat(dev, &stbuf);
-    if (res == -1) {
-        if (major == FUSE_MAJOR && minor == FUSE_MINOR)
-            return try_open_new_temp(devnum, devp, 0);
-        else {
-            fprintf(stderr, "%s: failed to open %s: %s\n", progname,
-                    dev, strerror(errno));
-            return -1;
-        }
-    }
-    
-    if ((stbuf.st_mode & S_IFMT) != S_IFCHR || stbuf.st_rdev != devnum) {
-        fprintf(stderr, "%s: %s exists but has wrong attributes\n", progname,
-                dev);
-        return -1;
-    }
-    return try_open(dev, devp, 0);
+    return -1;
 }
 
 static int open_fuse_device(char **devp)
@@ -723,14 +683,10 @@
         int status;
         pid_t pid;
 
-        fd = try_open(FUSE_DEV_OLD, devp, 1);
-        if (fd != -1)
+        fd = try_open_fuse_device(devp);
+        if (fd >= 0)
             return fd;
-
-        fd = try_open_new(devp, 0);
-        if (fd != -2)
-            return fd;
-
+        
 #ifndef USE_UCLIBC
         pid = fork();
 #else
@@ -745,14 +701,10 @@
             waitpid(pid, &status, 0);
     }
 
-    fd = try_open(FUSE_DEV_OLD, devp, 1);
-    if (fd != -1)
+    fd = try_open_fuse_device(devp);
+    if (fd >= 0)
         return fd;
-
-    fd = try_open_new(devp, 1);
-    if (fd != -2)
-        return fd;        
-
+    
     fprintf(stderr, "fuse device not found, try 'modprobe fuse' first\n");
     return -1;
 }