fixes
authorMiklos Szeredi <miklos@szeredi.hu>
Thu, 21 Jul 2005 07:59:37 +0000 (07:59 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Thu, 21 Jul 2005 07:59:37 +0000 (07:59 +0000)
13 files changed:
ChangeLog
example/hello_ll.c
include/Makefile.am
include/fuse.h
kernel/file.c
kernel/inode.c
lib/fuse.c
lib/fuse_lowlevel.c
lib/fuse_mt.c
lib/helper.c
lib/mount.c
test/test.c
util/fusermount.c

index 96b1cadda0d939b707363d67bc9be6c9576172e5..1ff388f904236df51df359bf895d4734412dc7b1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2005-07-21  Miklos Szeredi <miklos@szeredi.hu>
+
+       * Don't change mtime/ctime/atime to local time on read/write.
+       Bug reported by Ben Grimm
+
+       * Install fuse_common.h and fuse_lowlevel.h.  Report by Christian
+       Magnusson
+
+       * fusermount: use getopt_long() for option parsing.  It allows the
+       use of '--' to stop argument scanning, so fusermount can now
+       operate on directories whose names begin with a '-'.  Patch by
+       Adam Connell
+
 2005-07-15  Miklos Szeredi <miklos@szeredi.hu>
 
        * fusermount: add '-v', '--version' and '--help' options
index 258983681efeea464697aa5b74d084e0c611caf1..9f7086560bee76a3fdfb3dceb22ca4d25663d543 100644 (file)
@@ -27,13 +27,13 @@ static int hello_stat(fuse_ino_t ino, struct stat *stbuf)
         stbuf->st_mode = S_IFDIR | 0755;
         stbuf->st_nlink = 2;
         break;
-        
+
     case 2:
         stbuf->st_mode = S_IFREG | 0444;
         stbuf->st_nlink = 1;
         stbuf->st_size = strlen(hello_str);
         break;
-        
+
     default:
         return -1;
     }
@@ -63,7 +63,7 @@ static void hello_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
         e.attr_timeout = 1.0;
         e.entry_timeout = 1.0;
         hello_stat(e.ino, &e.attr);
-        
+
         fuse_reply_entry(req, &e);
     }
 }
@@ -89,7 +89,6 @@ static void dirbuf_add(struct dirbuf *b, const char *name, fuse_ino_t ino)
 static int reply_buf_limited(fuse_req_t req, const char *buf, size_t bufsize,
                              off_t off, size_t maxsize)
 {
-        
     if (off < bufsize)
         return fuse_reply_buf(req, buf + off, min(bufsize - off, maxsize));
     else
@@ -105,7 +104,7 @@ static void hello_ll_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
         fuse_reply_err(req, ENOTDIR);
     else {
         struct dirbuf b;
-    
+
         memset(&b, 0, sizeof(b));
         dirbuf_add(&b, ".", 1);
         dirbuf_add(&b, "..", 1);
index 269e0e1701c27a4761f83dd1d218d55c1fc82470..ee8a83ccd9d27e4f515df099e200ef67aac51ccc 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
 fuseincludedir=$(includedir)/fuse
-fuseinclude_HEADERS = fuse.h fuse_compat.h
+fuseinclude_HEADERS = fuse.h fuse_compat.h fuse_common.h fuse_lowlevel.h
 include_HEADERS = old/fuse.h
 noinst_HEADERS = fuse_kernel.h
index 6c6cf097dbf381519a6658d208a98b84cee35467..e285c07191c63cd07752fa242b2a3b7ed2f7c53d 100644 (file)
@@ -145,7 +145,7 @@ struct fuse_operations {
      * is permitted for the given flags.  Optionally open may also
      * return an arbitary filehandle in the fuse_file_info structure,
      * which will be passed to all file operations.
-     * 
+     *
      * Changed in version 2.2
      */
     int (*open) (const char *, struct fuse_file_info *);
@@ -197,7 +197,7 @@ struct fuse_operations {
      * not possible to determine if a flush is final, so each flush
      * should be treated equally.  Multiple write-flush sequences are
      * relatively rare, so this shouldn't be a problem.
-     * 
+     *
      * Changed in version 2.2
      */
     int (*flush) (const char *, struct fuse_file_info *);
@@ -266,13 +266,13 @@ struct fuse_operations {
      * passes non-zero offset to the filler function.  When the buffer
      * is full (or an error happens) the filler function will return
      * '1'.
-     * 
+     *
      * Introduced in version 2.3
      */
     int (*readdir) (const char *, void *, fuse_fill_dir_t, off_t,
                     struct fuse_file_info *);
 
-    /** Release directory 
+    /** Release directory
      *
      * Introduced in version 2.3
      */
@@ -293,7 +293,7 @@ struct fuse_operations {
      * The return value will passed in the private_data field of
      * fuse_context to all file operations and as a parameter to the
      * destroy() method.
-     * 
+     *
      * Introduced in version 2.3
      */
     void *(*init) (void);
@@ -302,7 +302,7 @@ struct fuse_operations {
      * Clean up filesystem
      *
      * Called on filesystem exit.
-     * 
+     *
      * Introduced in version 2.3
      */
     void (*destroy) (void *);
@@ -448,7 +448,7 @@ struct fuse_context *fuse_get_context(void);
 
 /**
  * Obsolete, doesn't do anything
- * 
+ *
  * @return -EINVAL
  */
 int fuse_invalidate(struct fuse *f, const char *path);
index 63e43809a22845c6c16dfd4a3fef0a68e99c3fad..f5e2c8745274cdb981736d9cc941d631a1508efe 100644 (file)
@@ -248,6 +248,8 @@ static int fuse_readpage(struct file *file, struct page *page)
        fuse_put_request(fc, req);
        if (!err)
                SetPageUptodate(page);
+       if (!(inode->i_sb->s_flags & MS_NOATIME))
+               fuse_invalidate_attr(inode);
  out:
        unlock_page(page);
        return err;
@@ -268,6 +270,8 @@ static int fuse_send_readpages(struct fuse_req *req, struct file *file,
                        SetPageUptodate(page);
                unlock_page(page);
        }
+       if (!(inode->i_sb->s_flags & MS_NOATIME))
+               fuse_invalidate_attr(inode);
        return req->out.h.error;
 }
 
@@ -484,8 +488,8 @@ static int fuse_commit_write(struct file *file, struct page *page,
                        clear_page_dirty(page);
                        SetPageUptodate(page);
                }
-       } else if (err == -EINTR || err == -EIO)
-               fuse_invalidate_attr(inode);
+       }
+       fuse_invalidate_attr(inode);
        return err;
 }
 
@@ -577,7 +581,8 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf,
                if (write && pos > i_size_read(inode))
                        i_size_write(inode, pos);
                *ppos = pos;
-       } else if (write && (res == -EINTR || res == -EIO))
+       }
+       if (write || !(inode->i_sb->s_flags & MS_NOATIME))
                fuse_invalidate_attr(inode);
 
        return res;
@@ -642,7 +647,7 @@ static int fuse_set_page_dirty(struct page *page)
 static struct file_operations fuse_file_operations = {
        .llseek         = generic_file_llseek,
 #ifdef KERNEL_2_6
-       .read           = generic_file_read,    
+       .read           = generic_file_read,
 #else
        .read           = fuse_file_read,
 #endif
index 5dacb220f18d8bfd547eed525d39f09d57bdd03e..7717ef18c5bc0a974803295291001106cd4f19fd 100644 (file)
@@ -199,6 +199,7 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid,
                return NULL;
 
        if ((inode->i_state & I_NEW)) {
+               inode->i_flags |= S_NOATIME|S_NOCMTIME;
                inode->i_generation = generation;
                inode->i_data.backing_dev_info = &fc->bdi;
                fuse_init_inode(inode, attr);
@@ -424,7 +425,7 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d)
                        return 0;
                }
        }
-       
+
        if (!d->fd_present || !d->rootmode_present ||
            !d->user_id_present || !d->group_id_present)
                return 0;
index 79ce5e79260932fcb041abfa9f262cae9e32c041..0ee4ab40ede143d2dd4c62c43800315bbb2c610a 100644 (file)
@@ -550,7 +550,7 @@ static void reply_entry(fuse_req_t req, const struct fuse_entry_param *e,
                         int err)
 {
     if (!err) {
-        if (fuse_reply_entry(req, e) == -ENOENT) 
+        if (fuse_reply_entry(req, e) == -ENOENT)
             forget_node(req_fuse(req), e->ino, 1);
     } else
         reply_err(req, err);
@@ -1353,7 +1353,7 @@ static void fuse_releasedir(fuse_req_t req, fuse_ino_t ino,
                             struct fuse_file_info *llfi)
 {
     struct fuse *f = req_fuse_prepare(req);
-    struct fuse_file_info fi;    
+    struct fuse_file_info fi;
     struct fuse_dirhandle *dh = get_dirhandle(llfi, &fi);
     if (f->op.releasedir) {
         char *path;
@@ -1698,7 +1698,7 @@ static int parse_lib_opts(struct fuse *f, const char *opts, char **llopts)
             if (fuse_ll_is_lib_option(opt)) {
                 size_t optlen = strlen(opt);
                 if (strcmp(opt, "debug") == 0)
-                    f->flags |= FUSE_DEBUG;                
+                    f->flags |= FUSE_DEBUG;
                 memmove(d, opt, optlen);
                 d += optlen;
                 *d++ = ',';
index b89ad93d287a8441c69fc1744cd4f22222bc2be0..4635e326fac768911c2e6a4a2103d9e0abfadd5d 100644 (file)
@@ -319,7 +319,7 @@ int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *f)
 
     memset(&arg, 0, sizeof(arg));
     arg.fh = f->fh;
-    
+
     return send_reply_req(req, &arg, sizeof(arg));
 }
 
@@ -329,7 +329,7 @@ int fuse_reply_write(fuse_req_t req, size_t count)
 
     memset(&arg, 0, sizeof(arg));
     arg.size = count;
-    
+
     return send_reply_req(req, &arg, sizeof(arg));
 }
 
@@ -344,7 +344,7 @@ int fuse_reply_statfs(fuse_req_t req, const struct statfs *statfs)
 
     memset(&arg, 0, sizeof(arg));
     convert_statfs(statfs, &arg.st);
-    
+
     return send_reply_req(req, &arg, sizeof(arg));
 }
 
@@ -354,7 +354,7 @@ int fuse_reply_xattr(fuse_req_t req, size_t count)
 
     memset(&arg, 0, sizeof(arg));
     arg.size = count;
-    
+
     return send_reply_req(req, &arg, sizeof(arg));
 }
 
@@ -468,7 +468,7 @@ static void do_open(fuse_req_t req, fuse_ino_t nodeid,
                     struct fuse_open_in *arg)
 {
     struct fuse_file_info fi;
-    
+
     memset(&fi, 0, sizeof(fi));
     fi.flags = arg->flags;
 
@@ -735,7 +735,7 @@ void fuse_ll_process_cmd(struct fuse_ll *f, struct fuse_cmd *cmd)
         fprintf(stderr, "fuse: failed to allocate request\n");
         goto out;
     }
-    
+
     req->f = f;
     req->unique = in->unique;
     req->ctx.uid = in->uid;
index c9fe63cbe6011d5d9771b78ac5b4b3dde0e24751..c9d85a8a0d88c55986e55c572f21878ebc390447 100644 (file)
@@ -22,7 +22,7 @@ static int context_ref;
 static struct fuse_context *mt_getcontext(void)
 {
     struct fuse_context *ctx;
-        
+
     ctx = (struct fuse_context *) pthread_getspecific(context_key);
     if (ctx == NULL) {
         ctx = (struct fuse_context *) malloc(sizeof(struct fuse_context));
index d8e694fe86d51c502d9197186cef9c0ef884a159..681197d613cf054fc1fc6e1ee3f2be0efc98d963 100644 (file)
@@ -293,7 +293,6 @@ static int fuse_parse_cmdline(int argc, const char *argv[], char **kernel_opts,
 }
 
 static struct fuse *fuse_setup_common(int argc, char *argv[],
-                                      
                                       const struct fuse_operations *op,
                                       size_t op_size,
                                       char **mountpoint,
index 86ad2beb449f62b19794726719e411786e2498d0..01081bb814aea3446a395a2f87b9fd699126659c 100644 (file)
@@ -72,8 +72,8 @@ void fuse_unmount(const char *mountpoint)
     const char *mountprog = FUSERMOUNT_PROG;
     char umount_cmd[1024];
 
-    snprintf(umount_cmd, sizeof(umount_cmd) - 1, "%s -u -q -z %s", mountprog,
-             mountpoint);
+    snprintf(umount_cmd, sizeof(umount_cmd) - 1, "%s -u -q -z -- %s",
+             mountprog, mountpoint);
 
     umount_cmd[sizeof(umount_cmd) - 1] = '\0';
     system(umount_cmd);
@@ -106,8 +106,17 @@ int fuse_mount(const char *mountpoint, const char *opts)
 
     if(pid == 0) {
         char env[10];
-        const char *argv[] = {mountprog, opts ? "-o" : mountpoint, opts,
-                              mountpoint, NULL};
+        const char *argv[32];
+        int a = 0;
+        
+        argv[a++] = mountprog;
+        if (opts) {
+            argv[a++] = "-o";
+            argv[a++] = opts;
+        }
+        argv[a++] = "--";
+        argv[a++] = mountpoint;
+        argv[a++] = NULL;
 
         close(fds[1]);
         fcntl(fds[0], F_SETFD, 0);
index 4e7711ce90715fdcbed2d02c9dbee90847eea16a..dfc9feaeb533501fdba6e7d530440a74e2606b15 100644 (file)
@@ -33,7 +33,7 @@ static void test_error(const char *func, const char *msg, ...)
 
 static void start_test(const char *fmt, ...)
      __attribute__ ((format (printf, 1, 2)));
-     
+
 static void test_error(const char *func, const char *msg, ...)
 {
     va_list ap;
@@ -254,7 +254,7 @@ static int create_file(const char *path, const char *data, int len)
 {
     int res;
     int fd;
-    
+
     unlink(path);
     fd = creat(path, 0644);
     if (fd == -1) {
@@ -335,7 +335,7 @@ static int create_dir(const char *path, const char **dir_files)
     res = check_mode(path, 0755);
     if (res == -1)
         return -1;
-    
+
     for (i = 0; dir_files[i]; i++) {
         char fpath[1024];
         sprintf(fpath, "%s/%s", path, dir_files[i]);
@@ -365,7 +365,7 @@ int test_truncate(int len)
     res = create_file(testfile, data, datalen);
     if (res == -1)
         return -1;
-    
+
     res = truncate(testfile, len);
     if (res == -1) {
         PERROR("truncate");
@@ -374,7 +374,7 @@ int test_truncate(int len)
     res = check_size(testfile, len);
     if (res == -1)
         return -1;
-    
+
     if (len > 0) {
         if (len <= datalen) {
             res = check_data(testfile, data, 0, len);
@@ -468,7 +468,7 @@ static int test_symlink(void)
     res = create_file(testfile, data, datalen);
     if (res == -1)
         return -1;
-    
+
     unlink(testfile2);
     res = symlink(testfile, testfile2);
     if (res == -1) {
@@ -521,7 +521,7 @@ static int test_rename_file(void)
     res = create_file(testfile, data, datalen);
     if (res == -1)
         return -1;
-    
+
     unlink(testfile2);
     res = rename(testfile, testfile2);
     if (res == -1) {
@@ -562,7 +562,7 @@ static int test_rename_dir(void)
     res = create_dir(testdir, testdir_files);
     if (res == -1)
         return -1;
-    
+
     rmdir(testdir2);
     res = rename(testdir, testdir2);
     if (res == -1) {
index 8702ffbbc10a71532c4339d10496945090859109..1fe312736ab16e4a2864537e911d5de198110df7 100644 (file)
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
+#include <getopt.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <pwd.h>
@@ -694,13 +695,13 @@ static int check_perm(const char **mntp, struct stat *stbuf, int *currdir_fd,
                     progname, origmnt, strerror(errno));
             return -1;
         }
-        
+
         if ((stbuf->st_mode & S_ISVTX) && stbuf->st_uid != getuid()) {
             fprintf(stderr, "%s: mountpoint %s not owned by user\n",
                     progname, origmnt);
             return -1;
         }
-        
+
         res = access(mnt, W_OK);
         if (res == -1) {
             fprintf(stderr, "%s: user has no write access to mountpoint %s\n",
@@ -1014,25 +1015,34 @@ static void show_version(void)
 
 int main(int argc, char *argv[])
 {
-    int a;
+    int ch;
     int fd;
     int res;
     char *origmnt;
     char *mnt;
-    int unmount = 0;
-    int lazy = 0;
+    static int unmount = 0;
+    static int lazy = 0;
+    static int quiet = 0;
     char *commfd;
-    int quiet = 0;
     int cfd;
     const char *opts = "";
 
-    progname = argv[0];
-
-    for (a = 1; a < argc; a++) {
-        if (argv[a][0] != '-')
-            break;
+    static const struct option long_opts[] = {
+        {"unmount", no_argument, NULL, 'u'},
+        {"lazy",    no_argument, NULL, 'z'},
+        {"quiet",   no_argument, NULL, 'q'},
+        {"help",    no_argument, NULL, 'h'},
+        {"version", no_argument, NULL, 'v'},
+        {0, 0, 0, 0}};
+
+    progname = strdup(argv[0]);
+    if (progname == NULL) {
+        fprintf(stderr, "%s: failed to allocate memory\n", argv[0]);
+        exit(1);
+    }
 
-        switch (argv[a][1]) {
+    while ((ch = getopt_long(argc, argv, "hvo:uzq", long_opts, NULL)) != -1) {
+        switch (ch) {
         case 'h':
             usage();
             break;
@@ -1042,12 +1052,7 @@ int main(int argc, char *argv[])
             break;
 
         case 'o':
-            a++;
-            if (a == argc) {
-                fprintf(stderr, "%s: missing argument to -o\n", progname);
-                exit(1);
-            }
-            opts = argv[a];
+            opts = optarg;
             break;
 
         case 'u':
@@ -1062,17 +1067,7 @@ int main(int argc, char *argv[])
             quiet = 1;
             break;
 
-        case '-':
-            if (strcmp(&argv[a][2], "help") == 0)
-                usage();
-            else if (strcmp(&argv[a][2], "version") == 0)
-                show_version();
-
-            /* fall through */
-
         default:
-            fprintf(stderr, "%s: unknown option '%s'\n", progname, argv[a]);
-            fprintf(stderr, "Try `%s -h' for more information\n", progname);
             exit(1);
         }
     }
@@ -1082,12 +1077,12 @@ int main(int argc, char *argv[])
         exit(1);
     }
 
-    if (a == argc) {
+    if (optind >= argc) {
         fprintf(stderr, "%s: missing mountpoint argument\n", progname);
         exit(1);
     }
 
-    origmnt = argv[a++];
+    origmnt = argv[optind];
 
     drop_privs();
     mnt = resolve_path(origmnt);