aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miklos Szeredi <miklos@szeredi.hu>2005-07-21 07:59:37 +0000
committerGravatar Miklos Szeredi <miklos@szeredi.hu>2005-07-21 07:59:37 +0000
commit9b813af8631729cf7f626f0cbac08863bb315863 (patch)
tree1ccd7493b978e83e85f27063d88045dbdddec7bb
parente2aa2e243d729e29ad67f1b30aa3392ca9a9cdb2 (diff)
fixes
-rw-r--r--ChangeLog13
-rw-r--r--example/hello_ll.c9
-rw-r--r--include/Makefile.am2
-rw-r--r--include/fuse.h14
-rw-r--r--kernel/file.c13
-rw-r--r--kernel/inode.c3
-rw-r--r--lib/fuse.c6
-rw-r--r--lib/fuse_lowlevel.c12
-rw-r--r--lib/fuse_mt.c2
-rw-r--r--lib/helper.c1
-rw-r--r--lib/mount.c17
-rw-r--r--test/test.c16
-rw-r--r--util/fusermount.c55
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 <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
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 <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);