From 9b813af8631729cf7f626f0cbac08863bb315863 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 21 Jul 2005 07:59:37 +0000 Subject: [PATCH] fixes --- ChangeLog | 13 +++++++++++ example/hello_ll.c | 9 ++++---- include/Makefile.am | 2 +- include/fuse.h | 14 ++++++------ kernel/file.c | 13 +++++++---- kernel/inode.c | 3 ++- lib/fuse.c | 6 ++--- lib/fuse_lowlevel.c | 12 +++++----- lib/fuse_mt.c | 2 +- lib/helper.c | 1 - lib/mount.c | 17 ++++++++++---- test/test.c | 16 ++++++------- util/fusermount.c | 55 +++++++++++++++++++++------------------------ 13 files changed, 92 insertions(+), 71 deletions(-) diff --git a/ChangeLog b/ChangeLog index 96b1cad..1ff388f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2005-07-21 Miklos Szeredi + + * 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 * fusermount: add '-v', '--version' and '--help' options diff --git a/example/hello_ll.c b/example/hello_ll.c index 2589836..9f70865 100644 --- a/example/hello_ll.c +++ b/example/hello_ll.c @@ -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); diff --git a/include/Makefile.am b/include/Makefile.am index 269e0e1..ee8a83c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -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 diff --git a/include/fuse.h b/include/fuse.h index 6c6cf09..e285c07 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -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); diff --git a/kernel/file.c b/kernel/file.c index 63e4380..f5e2c87 100644 --- a/kernel/file.c +++ b/kernel/file.c @@ -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 diff --git a/kernel/inode.c b/kernel/inode.c index 5dacb22..7717ef1 100644 --- a/kernel/inode.c +++ b/kernel/inode.c @@ -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; diff --git a/lib/fuse.c b/lib/fuse.c index 79ce5e7..0ee4ab4 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -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++ = ','; diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index b89ad93..4635e32 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -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; diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c index c9fe63c..c9d85a8 100644 --- a/lib/fuse_mt.c +++ b/lib/fuse_mt.c @@ -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)); diff --git a/lib/helper.c b/lib/helper.c index d8e694f..681197d 100644 --- a/lib/helper.c +++ b/lib/helper.c @@ -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, diff --git a/lib/mount.c b/lib/mount.c index 86ad2be..01081bb 100644 --- a/lib/mount.c +++ b/lib/mount.c @@ -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); diff --git a/test/test.c b/test/test.c index 4e7711c..dfc9fea 100644 --- a/test/test.c +++ b/test/test.c @@ -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) { diff --git a/util/fusermount.c b/util/fusermount.c index 8702ffb..1fe3127 100644 --- a/util/fusermount.c +++ b/util/fusermount.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -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); -- 2.30.2