aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/fuse.c4987
-rw-r--r--lib/fuse_i.h22
-rw-r--r--lib/fuse_kern_chan.c118
-rw-r--r--lib/fuse_loop.c48
-rw-r--r--lib/fuse_loop_mt.c347
-rw-r--r--lib/fuse_lowlevel.c1791
-rw-r--r--lib/fuse_misc.h18
-rw-r--r--lib/fuse_mt.c136
-rw-r--r--lib/fuse_opt.c528
-rw-r--r--lib/fuse_session.c185
-rw-r--r--lib/fuse_signals.c78
-rw-r--r--lib/helper.c568
-rw-r--r--lib/modules/iconv.c1021
-rw-r--r--lib/modules/subdir.c913
-rw-r--r--lib/mount.c966
-rw-r--r--lib/mount_bsd.c560
-rw-r--r--lib/mount_util.c397
-rw-r--r--lib/mount_util.h12
-rw-r--r--lib/ulockmgr.c702
19 files changed, 6737 insertions, 6660 deletions
diff --git a/lib/fuse.c b/lib/fuse.c
index d22e200..7bcbe76 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
@@ -40,109 +40,109 @@
#define OFFSET_MAX 0x7fffffffffffffffLL
struct fuse_config {
- unsigned int uid;
- unsigned int gid;
- unsigned int umask;
- double entry_timeout;
- double negative_timeout;
- double attr_timeout;
- double ac_attr_timeout;
- int ac_attr_timeout_set;
- int debug;
- int hard_remove;
- int use_ino;
- int readdir_ino;
- int set_mode;
- int set_uid;
- int set_gid;
- int direct_io;
- int kernel_cache;
- int auto_cache;
- int intr;
- int intr_signal;
- int help;
- char *modules;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int umask;
+ double entry_timeout;
+ double negative_timeout;
+ double attr_timeout;
+ double ac_attr_timeout;
+ int ac_attr_timeout_set;
+ int debug;
+ int hard_remove;
+ int use_ino;
+ int readdir_ino;
+ int set_mode;
+ int set_uid;
+ int set_gid;
+ int direct_io;
+ int kernel_cache;
+ int auto_cache;
+ int intr;
+ int intr_signal;
+ int help;
+ char *modules;
};
struct fuse_fs {
- struct fuse_operations op;
- struct fuse_module *m;
- void *user_data;
- int compat;
+ struct fuse_operations op;
+ struct fuse_module *m;
+ void *user_data;
+ int compat;
};
struct fusemod_so {
- void *handle;
- int ctr;
+ void *handle;
+ int ctr;
};
struct fuse {
- struct fuse_session *se;
- struct node **name_table;
- size_t name_table_size;
- struct node **id_table;
- size_t id_table_size;
- fuse_ino_t ctr;
- unsigned int generation;
- unsigned int hidectr;
- pthread_mutex_t lock;
- pthread_rwlock_t tree_lock;
- struct fuse_config conf;
- int intr_installed;
- struct fuse_fs *fs;
+ struct fuse_session *se;
+ struct node **name_table;
+ size_t name_table_size;
+ struct node **id_table;
+ size_t id_table_size;
+ fuse_ino_t ctr;
+ unsigned int generation;
+ unsigned int hidectr;
+ pthread_mutex_t lock;
+ pthread_rwlock_t tree_lock;
+ struct fuse_config conf;
+ int intr_installed;
+ struct fuse_fs *fs;
};
struct lock {
- int type;
- off_t start;
- off_t end;
- pid_t pid;
- uint64_t owner;
- struct lock *next;
+ int type;
+ off_t start;
+ off_t end;
+ pid_t pid;
+ uint64_t owner;
+ struct lock *next;
};
struct node {
- struct node *name_next;
- struct node *id_next;
- fuse_ino_t nodeid;
- unsigned int generation;
- int refctr;
- struct node *parent;
- char *name;
- uint64_t nlookup;
- int open_count;
- int is_hidden;
- struct timespec stat_updated;
- struct timespec mtime;
- off_t size;
- int cache_valid;
- struct lock *locks;
+ struct node *name_next;
+ struct node *id_next;
+ fuse_ino_t nodeid;
+ unsigned int generation;
+ int refctr;
+ struct node *parent;
+ char *name;
+ uint64_t nlookup;
+ int open_count;
+ int is_hidden;
+ struct timespec stat_updated;
+ struct timespec mtime;
+ off_t size;
+ int cache_valid;
+ struct lock *locks;
};
struct fuse_dh {
- pthread_mutex_t lock;
- struct fuse *fuse;
- fuse_req_t req;
- char *contents;
- int allocated;
- unsigned len;
- unsigned size;
- unsigned needlen;
- int filled;
- uint64_t fh;
- int error;
- fuse_ino_t nodeid;
+ pthread_mutex_t lock;
+ struct fuse *fuse;
+ fuse_req_t req;
+ char *contents;
+ int allocated;
+ unsigned len;
+ unsigned size;
+ unsigned needlen;
+ int filled;
+ uint64_t fh;
+ int error;
+ fuse_ino_t nodeid;
};
/* old dir handle */
struct fuse_dirhandle {
- fuse_fill_dir_t filler;
- void *buf;
+ fuse_fill_dir_t filler;
+ void *buf;
};
struct fuse_context_i {
- struct fuse_context ctx;
- fuse_req_t req;
+ struct fuse_context ctx;
+ fuse_req_t req;
};
static pthread_key_t fuse_context_key;
@@ -153,1017 +153,1025 @@ static struct fuse_module *fuse_modules;
static int fuse_load_so_name(const char *soname)
{
- struct fusemod_so *so;
-
- so = calloc(1, sizeof(struct fusemod_so));
- if (!so) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- return -1;
- }
-
- fuse_current_so = so;
- so->handle = dlopen(soname, RTLD_NOW);
- fuse_current_so = NULL;
- if (!so->handle) {
- fprintf(stderr, "fuse: %s\n", dlerror());
- goto err;
- }
- if (!so->ctr) {
- fprintf(stderr, "fuse: %s did not register any modules", soname);
- goto err;
- }
- return 0;
-
- err:
- if (so->handle)
- dlclose(so->handle);
- free(so);
- return -1;
+ struct fusemod_so *so;
+
+ so = calloc(1, sizeof(struct fusemod_so));
+ if (!so) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ return -1;
+ }
+
+ fuse_current_so = so;
+ so->handle = dlopen(soname, RTLD_NOW);
+ fuse_current_so = NULL;
+ if (!so->handle) {
+ fprintf(stderr, "fuse: %s\n", dlerror());
+ goto err;
+ }
+ if (!so->ctr) {
+ fprintf(stderr, "fuse: %s did not register any modules",
+ soname);
+ goto err;
+ }
+ return 0;
+
+err:
+ if (so->handle)
+ dlclose(so->handle);
+ free(so);
+ return -1;
}
static int fuse_load_so_module(const char *module)
{
- int res;
- char *soname = malloc(strlen(module) + 64);
- if (!soname) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- return -1;
- }
- sprintf(soname, "libfusemod_%s.so", module);
- res = fuse_load_so_name(soname);
- free(soname);
- return res;
+ int res;
+ char *soname = malloc(strlen(module) + 64);
+ if (!soname) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ return -1;
+ }
+ sprintf(soname, "libfusemod_%s.so", module);
+ res = fuse_load_so_name(soname);
+ free(soname);
+ return res;
}
static struct fuse_module *fuse_find_module(const char *module)
{
- struct fuse_module *m;
- for (m = fuse_modules; m; m = m->next) {
- if (strcmp(module, m->name) == 0) {
- m->ctr++;
- break;
- }
- }
- return m;
+ struct fuse_module *m;
+ for (m = fuse_modules; m; m = m->next) {
+ if (strcmp(module, m->name) == 0) {
+ m->ctr++;
+ break;
+ }
+ }
+ return m;
}
static struct fuse_module *fuse_get_module(const char *module)
{
- struct fuse_module *m;
+ struct fuse_module *m;
- pthread_mutex_lock(&fuse_context_lock);
- m = fuse_find_module(module);
- if (!m) {
- int err = fuse_load_so_module(module);
- if (!err)
- m = fuse_find_module(module);
- }
- pthread_mutex_unlock(&fuse_context_lock);
- return m;
+ pthread_mutex_lock(&fuse_context_lock);
+ m = fuse_find_module(module);
+ if (!m) {
+ int err = fuse_load_so_module(module);
+ if (!err)
+ m = fuse_find_module(module);
+ }
+ pthread_mutex_unlock(&fuse_context_lock);
+ return m;
}
static void fuse_put_module(struct fuse_module *m)
{
- pthread_mutex_lock(&fuse_context_lock);
- assert(m->ctr > 0);
- m->ctr--;
- if (!m->ctr && m->so) {
- struct fusemod_so *so = m->so;
- assert(so->ctr > 0);
- so->ctr--;
- if (!so->ctr) {
- struct fuse_module **mp;
- for (mp = &fuse_modules; *mp;) {
- if ((*mp)->so == so)
- *mp = (*mp)->next;
- else
- mp = &(*mp)->next;
- }
- dlclose(so->handle);
- free(so);
- }
- }
- pthread_mutex_unlock(&fuse_context_lock);
+ pthread_mutex_lock(&fuse_context_lock);
+ assert(m->ctr > 0);
+ m->ctr--;
+ if (!m->ctr && m->so) {
+ struct fusemod_so *so = m->so;
+ assert(so->ctr > 0);
+ so->ctr--;
+ if (!so->ctr) {
+ struct fuse_module **mp;
+ for (mp = &fuse_modules; *mp;) {
+ if ((*mp)->so == so)
+ *mp = (*mp)->next;
+ else
+ mp = &(*mp)->next;
+ }
+ dlclose(so->handle);
+ free(so);
+ }
+ }
+ pthread_mutex_unlock(&fuse_context_lock);
}
static struct node *get_node_nocheck(struct fuse *f, fuse_ino_t nodeid)
{
- size_t hash = nodeid % f->id_table_size;
- struct node *node;
+ size_t hash = nodeid % f->id_table_size;
+ struct node *node;
- for (node = f->id_table[hash]; node != NULL; node = node->id_next)
- if (node->nodeid == nodeid)
- return node;
+ for (node = f->id_table[hash]; node != NULL; node = node->id_next)
+ if (node->nodeid == nodeid)
+ return node;
- return NULL;
+ return NULL;
}
static struct node *get_node(struct fuse *f, fuse_ino_t nodeid)
{
- struct node *node = get_node_nocheck(f, nodeid);
- if (!node) {
- fprintf(stderr, "fuse internal error: node %llu not found\n",
- (unsigned long long) nodeid);
- abort();
- }
- return node;
+ struct node *node = get_node_nocheck(f, nodeid);
+ if (!node) {
+ fprintf(stderr, "fuse internal error: node %llu not found\n",
+ (unsigned long long) nodeid);
+ abort();
+ }
+ return node;
}
static void free_node(struct node *node)
{
- free(node->name);
- free(node);
+ free(node->name);
+ free(node);
}
static void unhash_id(struct fuse *f, struct node *node)
{
- size_t hash = node->nodeid % f->id_table_size;
- struct node **nodep = &f->id_table[hash];
+ size_t hash = node->nodeid % f->id_table_size;
+ struct node **nodep = &f->id_table[hash];
- for (; *nodep != NULL; nodep = &(*nodep)->id_next)
- if (*nodep == node) {
- *nodep = node->id_next;
- return;
- }
+ for (; *nodep != NULL; nodep = &(*nodep)->id_next)
+ if (*nodep == node) {
+ *nodep = node->id_next;
+ return;
+ }
}
static void hash_id(struct fuse *f, struct node *node)
{
- size_t hash = node->nodeid % f->id_table_size;
- node->id_next = f->id_table[hash];
- f->id_table[hash] = node;
+ size_t hash = node->nodeid % f->id_table_size;
+ node->id_next = f->id_table[hash];
+ f->id_table[hash] = node;
}
static unsigned int name_hash(struct fuse *f, fuse_ino_t parent,
- const char *name)
+ const char *name)
{
- unsigned int hash = *name;
+ unsigned int hash = *name;
- if (hash)
- for (name += 1; *name != '\0'; name++)
- hash = (hash << 5) - hash + *name;
+ if (hash)
+ for (name += 1; *name != '\0'; name++)
+ hash = (hash << 5) - hash + *name;
- return (hash + parent) % f->name_table_size;
+ return (hash + parent) % f->name_table_size;
}
static void unref_node(struct fuse *f, struct node *node);
static void unhash_name(struct fuse *f, struct node *node)
{
- if (node->name) {
- size_t hash = name_hash(f, node->parent->nodeid, node->name);
- struct node **nodep = &f->name_table[hash];
-
- for (; *nodep != NULL; nodep = &(*nodep)->name_next)
- if (*nodep == node) {
- *nodep = node->name_next;
- node->name_next = NULL;
- unref_node(f, node->parent);
- free(node->name);
- node->name = NULL;
- node->parent = NULL;
- return;
- }
- fprintf(stderr, "fuse internal error: unable to unhash node: %llu\n",
- (unsigned long long) node->nodeid);
- abort();
- }
+ if (node->name) {
+ size_t hash = name_hash(f, node->parent->nodeid, node->name);
+ struct node **nodep = &f->name_table[hash];
+
+ for (; *nodep != NULL; nodep = &(*nodep)->name_next)
+ if (*nodep == node) {
+ *nodep = node->name_next;
+ node->name_next = NULL;
+ unref_node(f, node->parent);
+ free(node->name);
+ node->name = NULL;
+ node->parent = NULL;
+ return;
+ }
+ fprintf(stderr,
+ "fuse internal error: unable to unhash node: %llu\n",
+ (unsigned long long) node->nodeid);
+ abort();
+ }
}
static int hash_name(struct fuse *f, struct node *node, fuse_ino_t parentid,
- const char *name)
+ const char *name)
{
- size_t hash = name_hash(f, parentid, name);
- struct node *parent = get_node(f, parentid);
- node->name = strdup(name);
- if (node->name == NULL)
- return -1;
+ size_t hash = name_hash(f, parentid, name);
+ struct node *parent = get_node(f, parentid);
+ node->name = strdup(name);
+ if (node->name == NULL)
+ return -1;
- parent->refctr ++;
- node->parent = parent;
- node->name_next = f->name_table[hash];
- f->name_table[hash] = node;
- return 0;
+ parent->refctr ++;
+ node->parent = parent;
+ node->name_next = f->name_table[hash];
+ f->name_table[hash] = node;
+ return 0;
}
static void delete_node(struct fuse *f, struct node *node)
{
- if (f->conf.debug)
- fprintf(stderr, "delete: %llu\n", (unsigned long long) node->nodeid);
+ if (f->conf.debug)
+ fprintf(stderr, "delete: %llu\n",
+ (unsigned long long) node->nodeid);
- assert(!node->name);
- unhash_id(f, node);
- free_node(node);
+ assert(!node->name);
+ unhash_id(f, node);
+ free_node(node);
}
static void unref_node(struct fuse *f, struct node *node)
{
- assert(node->refctr > 0);
- node->refctr --;
- if (!node->refctr)
- delete_node(f, node);
+ assert(node->refctr > 0);
+ node->refctr --;
+ if (!node->refctr)
+ delete_node(f, node);
}
static fuse_ino_t next_id(struct fuse *f)
{
- do {
- f->ctr = (f->ctr + 1) & 0xffffffff;
- if (!f->ctr)
- f->generation ++;
- } while (f->ctr == 0 || f->ctr == FUSE_UNKNOWN_INO ||
- get_node_nocheck(f, f->ctr) != NULL);
- return f->ctr;
+ do {
+ f->ctr = (f->ctr + 1) & 0xffffffff;
+ if (!f->ctr)
+ f->generation ++;
+ } while (f->ctr == 0 || f->ctr == FUSE_UNKNOWN_INO ||
+ get_node_nocheck(f, f->ctr) != NULL);
+ return f->ctr;
}
static struct node *lookup_node(struct fuse *f, fuse_ino_t parent,
- const char *name)
+ const char *name)
{
- size_t hash = name_hash(f, parent, name);
- struct node *node;
+ size_t hash = name_hash(f, parent, name);
+ struct node *node;
- for (node = f->name_table[hash]; node != NULL; node = node->name_next)
- if (node->parent->nodeid == parent && strcmp(node->name, name) == 0)
- return node;
+ for (node = f->name_table[hash]; node != NULL; node = node->name_next)
+ if (node->parent->nodeid == parent &&
+ strcmp(node->name, name) == 0)
+ return node;
- return NULL;
+ return NULL;
}
static struct node *find_node(struct fuse *f, fuse_ino_t parent,
- const char *name)
-{
- struct node *node;
-
- pthread_mutex_lock(&f->lock);
- node = lookup_node(f, parent, name);
- if (node == NULL) {
- node = (struct node *) calloc(1, sizeof(struct node));
- if (node == NULL)
- goto out_err;
-
- node->refctr = 1;
- node->nodeid = next_id(f);
- node->open_count = 0;
- node->is_hidden = 0;
- node->generation = f->generation;
- if (hash_name(f, node, parent, name) == -1) {
- free(node);
- node = NULL;
- goto out_err;
- }
- hash_id(f, node);
- }
- node->nlookup ++;
- out_err:
- pthread_mutex_unlock(&f->lock);
- return node;
+ const char *name)
+{
+ struct node *node;
+
+ pthread_mutex_lock(&f->lock);
+ node = lookup_node(f, parent, name);
+ if (node == NULL) {
+ node = (struct node *) calloc(1, sizeof(struct node));
+ if (node == NULL)
+ goto out_err;
+
+ node->refctr = 1;
+ node->nodeid = next_id(f);
+ node->open_count = 0;
+ node->is_hidden = 0;
+ node->generation = f->generation;
+ if (hash_name(f, node, parent, name) == -1) {
+ free(node);
+ node = NULL;
+ goto out_err;
+ }
+ hash_id(f, node);
+ }
+ node->nlookup ++;
+out_err:
+ pthread_mutex_unlock(&f->lock);
+ return node;
}
static char *add_name(char *buf, char *s, const char *name)
{
- size_t len = strlen(name);
- s -= len;
- if (s <= buf) {
- fprintf(stderr, "fuse: path too long: ...%s\n", s + len);
- return NULL;
- }
- strncpy(s, name, len);
- s--;
- *s = '/';
+ size_t len = strlen(name);
+ s -= len;
+ if (s <= buf) {
+ fprintf(stderr, "fuse: path too long: ...%s\n", s + len);
+ return NULL;
+ }
+ strncpy(s, name, len);
+ s--;
+ *s = '/';
- return s;
+ return s;
}
static char *get_path_name(struct fuse *f, fuse_ino_t nodeid, const char *name)
{
- char buf[FUSE_MAX_PATH];
- char *s = buf + FUSE_MAX_PATH - 1;
- struct node *node;
+ char buf[FUSE_MAX_PATH];
+ char *s = buf + FUSE_MAX_PATH - 1;
+ struct node *node;
- *s = '\0';
+ *s = '\0';
- if (name != NULL) {
- s = add_name(buf, s, name);
- if (s == NULL)
- return NULL;
- }
+ if (name != NULL) {
+ s = add_name(buf, s, name);
+ if (s == NULL)
+ return NULL;
+ }
- pthread_mutex_lock(&f->lock);
- for (node = get_node(f, nodeid); node && node->nodeid != FUSE_ROOT_ID;
- node = node->parent) {
- if (node->name == NULL) {
- s = NULL;
- break;
- }
+ pthread_mutex_lock(&f->lock);
+ for (node = get_node(f, nodeid); node && node->nodeid != FUSE_ROOT_ID;
+ node = node->parent) {
+ if (node->name == NULL) {
+ s = NULL;
+ break;
+ }
- s = add_name(buf, s, node->name);
- if (s == NULL)
- break;
- }
- pthread_mutex_unlock(&f->lock);
+ s = add_name(buf, s, node->name);
+ if (s == NULL)
+ break;
+ }
+ pthread_mutex_unlock(&f->lock);
- if (node == NULL || s == NULL)
- return NULL;
- else if (*s == '\0')
- return strdup("/");
- else
- return strdup(s);
+ if (node == NULL || s == NULL)
+ return NULL;
+ else if (*s == '\0')
+ return strdup("/");
+ else
+ return strdup(s);
}
static char *get_path(struct fuse *f, fuse_ino_t nodeid)
{
- return get_path_name(f, nodeid, NULL);
+ return get_path_name(f, nodeid, NULL);
}
static void forget_node(struct fuse *f, fuse_ino_t nodeid, uint64_t nlookup)
{
- struct node *node;
- if (nodeid == FUSE_ROOT_ID)
- return;
- pthread_mutex_lock(&f->lock);
- node = get_node(f, nodeid);
- assert(node->nlookup >= nlookup);
- node->nlookup -= nlookup;
- if (!node->nlookup) {
- unhash_name(f, node);
- unref_node(f, node);
- }
- pthread_mutex_unlock(&f->lock);
+ struct node *node;
+ if (nodeid == FUSE_ROOT_ID)
+ return;
+ pthread_mutex_lock(&f->lock);
+ node = get_node(f, nodeid);
+ assert(node->nlookup >= nlookup);
+ node->nlookup -= nlookup;
+ if (!node->nlookup) {
+ unhash_name(f, node);
+ unref_node(f, node);
+ }
+ pthread_mutex_unlock(&f->lock);
}
static void remove_node(struct fuse *f, fuse_ino_t dir, const char *name)
{
- struct node *node;
+ struct node *node;
- pthread_mutex_lock(&f->lock);
- node = lookup_node(f, dir, name);
- if (node != NULL)
- unhash_name(f, node);
- pthread_mutex_unlock(&f->lock);
+ pthread_mutex_lock(&f->lock);
+ node = lookup_node(f, dir, name);
+ if (node != NULL)
+ unhash_name(f, node);
+ pthread_mutex_unlock(&f->lock);
}
static int rename_node(struct fuse *f, fuse_ino_t olddir, const char *oldname,
- fuse_ino_t newdir, const char *newname, int hide)
-{
- struct node *node;
- struct node *newnode;
- int err = 0;
-
- pthread_mutex_lock(&f->lock);
- node = lookup_node(f, olddir, oldname);
- newnode = lookup_node(f, newdir, newname);
- if (node == NULL)
- goto out;
-
- if (newnode != NULL) {
- if (hide) {
- fprintf(stderr, "fuse: hidden file got created during hiding\n");
- err = -EBUSY;
- goto out;
- }
- unhash_name(f, newnode);
- }
-
- unhash_name(f, node);
- if (hash_name(f, node, newdir, newname) == -1) {
- err = -ENOMEM;
- goto out;
- }
-
- if (hide)
- node->is_hidden = 1;
+ fuse_ino_t newdir, const char *newname, int hide)
+{
+ struct node *node;
+ struct node *newnode;
+ int err = 0;
+
+ pthread_mutex_lock(&f->lock);
+ node = lookup_node(f, olddir, oldname);
+ newnode = lookup_node(f, newdir, newname);
+ if (node == NULL)
+ goto out;
+
+ if (newnode != NULL) {
+ if (hide) {
+ fprintf(stderr, "fuse: hidden file got created during hiding\n");
+ err = -EBUSY;
+ goto out;
+ }
+ unhash_name(f, newnode);
+ }
+
+ unhash_name(f, node);
+ if (hash_name(f, node, newdir, newname) == -1) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ if (hide)
+ node->is_hidden = 1;
- out:
- pthread_mutex_unlock(&f->lock);
- return err;
+out:
+ pthread_mutex_unlock(&f->lock);
+ return err;
}
static void set_stat(struct fuse *f, fuse_ino_t nodeid, struct stat *stbuf)
{
- if (!f->conf.use_ino)
- stbuf->st_ino = nodeid;
- if (f->conf.set_mode)
- stbuf->st_mode = (stbuf->st_mode & S_IFMT) | (0777 & ~f->conf.umask);
- if (f->conf.set_uid)
- stbuf->st_uid = f->conf.uid;
- if (f->conf.set_gid)
- stbuf->st_gid = f->conf.gid;
+ if (!f->conf.use_ino)
+ stbuf->st_ino = nodeid;
+ if (f->conf.set_mode)
+ stbuf->st_mode = (stbuf->st_mode & S_IFMT) |
+ (0777 & ~f->conf.umask);
+ if (f->conf.set_uid)
+ stbuf->st_uid = f->conf.uid;
+ if (f->conf.set_gid)
+ stbuf->st_gid = f->conf.gid;
}
static struct fuse *req_fuse(fuse_req_t req)
{
- return (struct fuse *) fuse_req_userdata(req);
+ return (struct fuse *) fuse_req_userdata(req);
}
static void fuse_intr_sighandler(int sig)
{
- (void) sig;
- /* Nothing to do */
+ (void) sig;
+ /* Nothing to do */
}
struct fuse_intr_data {
- pthread_t id;
- pthread_cond_t cond;
- int finished;
+ pthread_t id;
+ pthread_cond_t cond;
+ int finished;
};
static void fuse_interrupt(fuse_req_t req, void *d_)
{
- struct fuse_intr_data *d = d_;
- struct fuse *f = req_fuse(req);
+ struct fuse_intr_data *d = d_;
+ struct fuse *f = req_fuse(req);
- if (d->id == pthread_self())
- return;
+ if (d->id == pthread_self())
+ return;
- pthread_mutex_lock(&f->lock);
- while (!d->finished) {
- struct timeval now;
- struct timespec timeout;
+ pthread_mutex_lock(&f->lock);
+ while (!d->finished) {
+ struct timeval now;
+ struct timespec timeout;
- pthread_kill(d->id, f->conf.intr_signal);
- gettimeofday(&now, NULL);
- timeout.tv_sec = now.tv_sec + 1;
- timeout.tv_nsec = now.tv_usec * 1000;
- pthread_cond_timedwait(&d->cond, &f->lock, &timeout);
- }
- pthread_mutex_unlock(&f->lock);
+ pthread_kill(d->id, f->conf.intr_signal);
+ gettimeofday(&now, NULL);
+ timeout.tv_sec = now.tv_sec + 1;
+ timeout.tv_nsec = now.tv_usec * 1000;
+ pthread_cond_timedwait(&d->cond, &f->lock, &timeout);
+ }
+ pthread_mutex_unlock(&f->lock);
}
static void fuse_do_finish_interrupt(struct fuse *f, fuse_req_t req,
- struct fuse_intr_data *d)
+ struct fuse_intr_data *d)
{
- pthread_mutex_lock(&f->lock);
- d->finished = 1;
- pthread_cond_broadcast(&d->cond);
- pthread_mutex_unlock(&f->lock);
- fuse_req_interrupt_func(req, NULL, NULL);
- pthread_cond_destroy(&d->cond);
+ pthread_mutex_lock(&f->lock);
+ d->finished = 1;
+ pthread_cond_broadcast(&d->cond);
+ pthread_mutex_unlock(&f->lock);
+ fuse_req_interrupt_func(req, NULL, NULL);
+ pthread_cond_destroy(&d->cond);
}
static void fuse_do_prepare_interrupt(fuse_req_t req, struct fuse_intr_data *d)
{
- d->id = pthread_self();
- pthread_cond_init(&d->cond, NULL);
- d->finished = 0;
- fuse_req_interrupt_func(req, fuse_interrupt, d);
+ d->id = pthread_self();
+ pthread_cond_init(&d->cond, NULL);
+ d->finished = 0;
+ fuse_req_interrupt_func(req, fuse_interrupt, d);
}
static inline void fuse_finish_interrupt(struct fuse *f, fuse_req_t req,
- struct fuse_intr_data *d)
+ struct fuse_intr_data *d)
{
- if (f->conf.intr)
- fuse_do_finish_interrupt(f, req, d);
+ if (f->conf.intr)
+ fuse_do_finish_interrupt(f, req, d);
}
static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req,
- struct fuse_intr_data *d)
+ struct fuse_intr_data *d)
{
- if (f->conf.intr)
- fuse_do_prepare_interrupt(req, d);
+ if (f->conf.intr)
+ fuse_do_prepare_interrupt(req, d);
}
#ifndef __FreeBSD__
static int fuse_compat_open(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
-{
- int err;
- if (!fs->compat || fs->compat >= 25)
- err = fs->op.open(path, fi);
- else if (fs->compat == 22) {
- struct fuse_file_info_compat tmp;
- memcpy(&tmp, fi, sizeof(tmp));
- err = ((struct fuse_operations_compat22 *) &fs->op)->open(path, &tmp);
- memcpy(fi, &tmp, sizeof(tmp));
- fi->fh = tmp.fh;
- } else
- err = ((struct fuse_operations_compat2 *) &fs->op)
- ->open(path, fi->flags);
- return err;
+ struct fuse_file_info *fi)
+{
+ int err;
+ if (!fs->compat || fs->compat >= 25)
+ err = fs->op.open(path, fi);
+ else if (fs->compat == 22) {
+ struct fuse_file_info_compat tmp;
+ memcpy(&tmp, fi, sizeof(tmp));
+ err = ((struct fuse_operations_compat22 *) &fs->op)->open(path,
+ &tmp);
+ memcpy(fi, &tmp, sizeof(tmp));
+ fi->fh = tmp.fh;
+ } else
+ err = ((struct fuse_operations_compat2 *) &fs->op)
+ ->open(path, fi->flags);
+ return err;
}
static int fuse_compat_release(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- if (!fs->compat || fs->compat >= 22)
- return fs->op.release(path, fi);
- else
- return ((struct fuse_operations_compat2 *) &fs->op)
- ->release(path, fi->flags);
+ if (!fs->compat || fs->compat >= 22)
+ return fs->op.release(path, fi);
+ else
+ return ((struct fuse_operations_compat2 *) &fs->op)
+ ->release(path, fi->flags);
}
static int fuse_compat_opendir(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
-{
- if (!fs->compat || fs->compat >= 25)
- return fs->op.opendir(path, fi);
- else {
- int err;
- struct fuse_file_info_compat tmp;
- memcpy(&tmp, fi, sizeof(tmp));
- err = ((struct fuse_operations_compat22 *) &fs->op)
- ->opendir(path, &tmp);
- memcpy(fi, &tmp, sizeof(tmp));
- fi->fh = tmp.fh;
- return err;
- }
+ struct fuse_file_info *fi)
+{
+ if (!fs->compat || fs->compat >= 25)
+ return fs->op.opendir(path, fi);
+ else {
+ int err;
+ struct fuse_file_info_compat tmp;
+ memcpy(&tmp, fi, sizeof(tmp));
+ err = ((struct fuse_operations_compat22 *) &fs->op)
+ ->opendir(path, &tmp);
+ memcpy(fi, &tmp, sizeof(tmp));
+ fi->fh = tmp.fh;
+ return err;
+ }
}
static void convert_statfs_compat(struct fuse_statfs_compat1 *compatbuf,
- struct statvfs *stbuf)
+ struct statvfs *stbuf)
{
- stbuf->f_bsize = compatbuf->block_size;
- stbuf->f_blocks = compatbuf->blocks;
- stbuf->f_bfree = compatbuf->blocks_free;
- stbuf->f_bavail = compatbuf->blocks_free;
- stbuf->f_files = compatbuf->files;
- stbuf->f_ffree = compatbuf->files_free;
- stbuf->f_namemax = compatbuf->namelen;
+ stbuf->f_bsize = compatbuf->block_size;
+ stbuf->f_blocks = compatbuf->blocks;
+ stbuf->f_bfree = compatbuf->blocks_free;
+ stbuf->f_bavail = compatbuf->blocks_free;
+ stbuf->f_files = compatbuf->files;
+ stbuf->f_ffree = compatbuf->files_free;
+ stbuf->f_namemax = compatbuf->namelen;
}
static void convert_statfs_old(struct statfs *oldbuf, struct statvfs *stbuf)
{
- stbuf->f_bsize = oldbuf->f_bsize;
- stbuf->f_blocks = oldbuf->f_blocks;
- stbuf->f_bfree = oldbuf->f_bfree;
- stbuf->f_bavail = oldbuf->f_bavail;
- stbuf->f_files = oldbuf->f_files;
- stbuf->f_ffree = oldbuf->f_ffree;
- stbuf->f_namemax = oldbuf->f_namelen;
+ stbuf->f_bsize = oldbuf->f_bsize;
+ stbuf->f_blocks = oldbuf->f_blocks;
+ stbuf->f_bfree = oldbuf->f_bfree;
+ stbuf->f_bavail = oldbuf->f_bavail;
+ stbuf->f_files = oldbuf->f_files;
+ stbuf->f_ffree = oldbuf->f_ffree;
+ stbuf->f_namemax = oldbuf->f_namelen;
}
static int fuse_compat_statfs(struct fuse_fs *fs, const char *path,
- struct statvfs *buf)
-{
- int err;
-
- if (!fs->compat || fs->compat >= 25) {
- err = fs->op.statfs(fs->compat == 25 ? "/" : path, buf);
- } else if (fs->compat > 11) {
- struct statfs oldbuf;
- err = ((struct fuse_operations_compat22 *) &fs->op)
- ->statfs("/", &oldbuf);
- if (!err)
- convert_statfs_old(&oldbuf, buf);
- } else {
- struct fuse_statfs_compat1 compatbuf;
- memset(&compatbuf, 0, sizeof(struct fuse_statfs_compat1));
- err = ((struct fuse_operations_compat1 *) &fs->op)->statfs(&compatbuf);
- if (!err)
- convert_statfs_compat(&compatbuf, buf);
- }
- return err;
+ struct statvfs *buf)
+{
+ int err;
+
+ if (!fs->compat || fs->compat >= 25) {
+ err = fs->op.statfs(fs->compat == 25 ? "/" : path, buf);
+ } else if (fs->compat > 11) {
+ struct statfs oldbuf;
+ err = ((struct fuse_operations_compat22 *) &fs->op)
+ ->statfs("/", &oldbuf);
+ if (!err)
+ convert_statfs_old(&oldbuf, buf);
+ } else {
+ struct fuse_statfs_compat1 compatbuf;
+ memset(&compatbuf, 0, sizeof(struct fuse_statfs_compat1));
+ err = ((struct fuse_operations_compat1 *) &fs->op)
+ ->statfs(&compatbuf);
+ if (!err)
+ convert_statfs_compat(&compatbuf, buf);
+ }
+ return err;
}
#else /* __FreeBSD__ */
static inline int fuse_compat_open(struct fuse_fs *fs, char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- return fs->op.open(path, fi);
+ return fs->op.open(path, fi);
}
static inline int fuse_compat_release(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- return fs->op.release(path, fi);
+ return fs->op.release(path, fi);
}
static inline int fuse_compat_opendir(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- return fs->op.opendir(path, fi);
+ return fs->op.opendir(path, fi);
}
static inline int fuse_compat_statfs(struct fuse_fs *fs, const char *path,
- struct statvfs *buf)
+ struct statvfs *buf)
{
- return fs->op.statfs(fs->compat == 25 ? "/" : path, buf);
+ return fs->op.statfs(fs->compat == 25 ? "/" : path, buf);
}
#endif /* __FreeBSD__ */
int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.getattr)
- return fs->op.getattr(path, buf);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.getattr)
+ return fs->op.getattr(path, buf);
+ else
+ return -ENOSYS;
}
int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct stat *buf,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.fgetattr)
- return fs->op.fgetattr(path, buf, fi);
- else if (fs->op.getattr)
- return fs->op.getattr(path, buf);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.fgetattr)
+ return fs->op.fgetattr(path, buf, fi);
+ else if (fs->op.getattr)
+ return fs->op.getattr(path, buf);
+ else
+ return -ENOSYS;
}
int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
- const char *newpath)
+ const char *newpath)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.rename)
- return fs->op.rename(oldpath, newpath);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.rename)
+ return fs->op.rename(oldpath, newpath);
+ else
+ return -ENOSYS;
}
int fuse_fs_unlink(struct fuse_fs *fs, const char *path)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.unlink)
- return fs->op.unlink(path);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.unlink)
+ return fs->op.unlink(path);
+ else
+ return -ENOSYS;
}
int fuse_fs_rmdir(struct fuse_fs *fs, const char *path)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.rmdir)
- return fs->op.rmdir(path);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.rmdir)
+ return fs->op.rmdir(path);
+ else
+ return -ENOSYS;
}
int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname, const char *path)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.symlink)
- return fs->op.symlink(linkname, path);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.symlink)
+ return fs->op.symlink(linkname, path);
+ else
+ return -ENOSYS;
}
int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.link)
- return fs->op.link(oldpath, newpath);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.link)
+ return fs->op.link(oldpath, newpath);
+ else
+ return -ENOSYS;
}
-int fuse_fs_release(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+int fuse_fs_release(struct fuse_fs *fs, const char *path,
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.release)
- return fuse_compat_release(fs, path, fi);
- else
- return 0;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.release)
+ return fuse_compat_release(fs, path, fi);
+ else
+ return 0;
}
int fuse_fs_opendir(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.opendir)
- return fuse_compat_opendir(fs, path, fi);
- else
- return 0;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.opendir)
+ return fuse_compat_opendir(fs, path, fi);
+ else
+ return 0;
}
int fuse_fs_open(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.open)
- return fuse_compat_open(fs, path, fi);
- else
- return 0;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.open)
+ return fuse_compat_open(fs, path, fi);
+ else
+ return 0;
}
int fuse_fs_read(struct fuse_fs *fs, const char *path, char *buf, size_t size,
- off_t off, struct fuse_file_info *fi)
+ off_t off, struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.read)
- return fs->op.read(path, buf, size, off, fi);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.read)
+ return fs->op.read(path, buf, size, off, fi);
+ else
+ return -ENOSYS;
}
int fuse_fs_write(struct fuse_fs *fs, const char *path, const char *buf,
- size_t size, off_t off, struct fuse_file_info *fi)
+ size_t size, off_t off, struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.write)
- return fs->op.write(path, buf, size, off, fi);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.write)
+ return fs->op.write(path, buf, size, off, fi);
+ else
+ return -ENOSYS;
}
int fuse_fs_fsync(struct fuse_fs *fs, const char *path, int datasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.fsync)
- return fs->op.fsync(path, datasync, fi);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.fsync)
+ return fs->op.fsync(path, datasync, fi);
+ else
+ return -ENOSYS;
}
int fuse_fs_fsyncdir(struct fuse_fs *fs, const char *path, int datasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.fsyncdir)
- return fs->op.fsyncdir(path, datasync, fi);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.fsyncdir)
+ return fs->op.fsyncdir(path, datasync, fi);
+ else
+ return -ENOSYS;
}
int fuse_fs_flush(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.flush)
- return fs->op.flush(path, fi);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.flush)
+ return fs->op.flush(path, fi);
+ else
+ return -ENOSYS;
}
int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.statfs)
- return fuse_compat_statfs(fs, path, buf);
- else {
- buf->f_namemax = 255;
- buf->f_bsize = 512;
- return 0;
- }
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.statfs)
+ return fuse_compat_statfs(fs, path, buf);
+ else {
+ buf->f_namemax = 255;
+ buf->f_bsize = 512;
+ return 0;
+ }
}
int fuse_fs_releasedir(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.releasedir)
- return fs->op.releasedir(path, fi);
- else
- return 0;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.releasedir)
+ return fs->op.releasedir(path, fi);
+ else
+ return 0;
}
static int fill_dir_old(struct fuse_dirhandle *dh, const char *name, int type,
- ino_t ino)
+ ino_t ino)
{
- int res;
- struct stat stbuf;
+ int res;
+ struct stat stbuf;
- memset(&stbuf, 0, sizeof(stbuf));
- stbuf.st_mode = type << 12;
- stbuf.st_ino = ino;
+ memset(&stbuf, 0, sizeof(stbuf));
+ stbuf.st_mode = type << 12;
+ stbuf.st_ino = ino;
- res = dh->filler(dh->buf, name, &stbuf, 0);
- return res ? -ENOMEM : 0;
+ res = dh->filler(dh->buf, name, &stbuf, 0);
+ return res ? -ENOMEM : 0;
}
int fuse_fs_readdir(struct fuse_fs *fs, const char *path, void *buf,
- fuse_fill_dir_t filler, off_t off,
- struct fuse_file_info *fi)
+ fuse_fill_dir_t filler, off_t off,
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.readdir)
- return fs->op.readdir(path, buf, filler, off, fi);
- else if (fs->op.getdir) {
- struct fuse_dirhandle dh;
- dh.filler = filler;
- dh.buf = buf;
- return fs->op.getdir(path, &dh, fill_dir_old);
- } else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.readdir)
+ return fs->op.readdir(path, buf, filler, off, fi);
+ else if (fs->op.getdir) {
+ struct fuse_dirhandle dh;
+ dh.filler = filler;
+ dh.buf = buf;
+ return fs->op.getdir(path, &dh, fill_dir_old);
+ } else
+ return -ENOSYS;
}
int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.create)
- return fs->op.create(path, mode, fi);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.create)
+ return fs->op.create(path, mode, fi);
+ else
+ return -ENOSYS;
}
int fuse_fs_lock(struct fuse_fs *fs, const char *path,
- struct fuse_file_info *fi, int cmd, struct flock *lock)
+ struct fuse_file_info *fi, int cmd, struct flock *lock)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.lock)
- return fs->op.lock(path, fi, cmd, lock);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.lock)
+ return fs->op.lock(path, fi, cmd, lock);
+ else
+ return -ENOSYS;
}
int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.chown)
- return fs->op.chown(path, uid, gid);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.chown)
+ return fs->op.chown(path, uid, gid);
+ else
+ return -ENOSYS;
}
int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.truncate)
- return fs->op.truncate(path, size);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.truncate)
+ return fs->op.truncate(path, size);
+ else
+ return -ENOSYS;
}
int fuse_fs_ftruncate(struct fuse_fs *fs, const char *path, off_t size,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.ftruncate)
- return fs->op.ftruncate(path, size, fi);
- else if (fs->op.truncate)
- return fs->op.truncate(path, size);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.ftruncate)
+ return fs->op.ftruncate(path, size, fi);
+ else if (fs->op.truncate)
+ return fs->op.truncate(path, size);
+ else
+ return -ENOSYS;
}
int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
- const struct timespec tv[2])
+ const struct timespec tv[2])
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.utimens)
- return fs->op.utimens(path, tv);
- else if(fs->op.utime) {
- struct utimbuf buf;
- buf.actime = tv[0].tv_sec;
- buf.modtime = tv[1].tv_sec;
- return fs->op.utime(path, &buf);
- } else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.utimens)
+ return fs->op.utimens(path, tv);
+ else if(fs->op.utime) {
+ struct utimbuf buf;
+ buf.actime = tv[0].tv_sec;
+ buf.modtime = tv[1].tv_sec;
+ return fs->op.utime(path, &buf);
+ } else
+ return -ENOSYS;
}
int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.access)
- return fs->op.access(path, mask);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.access)
+ return fs->op.access(path, mask);
+ else
+ return -ENOSYS;
}
int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,
- size_t len)
+ size_t len)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.readlink)
- return fs->op.readlink(path, buf, len);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.readlink)
+ return fs->op.readlink(path, buf, len);
+ else
+ return -ENOSYS;
}
int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode,
- dev_t rdev)
+ dev_t rdev)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.mknod)
- return fs->op.mknod(path, mode, rdev);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.mknod)
+ return fs->op.mknod(path, mode, rdev);
+ else
+ return -ENOSYS;
}
int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.mkdir)
- return fs->op.mkdir(path, mode);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.mkdir)
+ return fs->op.mkdir(path, mode);
+ else
+ return -ENOSYS;
}
int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name,
- const char *value, size_t size, int flags)
+ const char *value, size_t size, int flags)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.setxattr)
- return fs->op.setxattr(path, name, value, size, flags);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.setxattr)
+ return fs->op.setxattr(path, name, value, size, flags);
+ else
+ return -ENOSYS;
}
int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name,
- char *value, size_t size)
+ char *value, size_t size)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.getxattr)
- return fs->op.getxattr(path, name, value, size);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.getxattr)
+ return fs->op.getxattr(path, name, value, size);
+ else
+ return -ENOSYS;
}
int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list,
- size_t size)
+ size_t size)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.listxattr)
- return fs->op.listxattr(path, list, size);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.listxattr)
+ return fs->op.listxattr(path, list, size);
+ else
+ return -ENOSYS;
}
int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
- uint64_t *idx)
+ uint64_t *idx)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.bmap)
- return fs->op.bmap(path, blocksize, idx);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.bmap)
+ return fs->op.bmap(path, blocksize, idx);
+ else
+ return -ENOSYS;
}
int fuse_fs_removexattr(struct fuse_fs *fs, const char *path, const char *name)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.removexattr)
- return fs->op.removexattr(path, name);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.removexattr)
+ return fs->op.removexattr(path, name);
+ else
+ return -ENOSYS;
}
static int is_open(struct fuse *f, fuse_ino_t dir, const char *name)
{
- struct node *node;
- int isopen = 0;
- pthread_mutex_lock(&f->lock);
- node = lookup_node(f, dir, name);
- if (node && node->open_count > 0)
- isopen = 1;
- pthread_mutex_unlock(&f->lock);
- return isopen;
+ struct node *node;
+ int isopen = 0;
+ pthread_mutex_lock(&f->lock);
+ node = lookup_node(f, dir, name);
+ if (node && node->open_count > 0)
+ isopen = 1;
+ pthread_mutex_unlock(&f->lock);
+ return isopen;
}
static char *hidden_name(struct fuse *f, fuse_ino_t dir, const char *oldname,
- char *newname, size_t bufsize)
-{
- struct stat buf;
- struct node *node;
- struct node *newnode;
- char *newpath;
- int res;
- int failctr = 10;
-
- do {
- pthread_mutex_lock(&f->lock);
- node = lookup_node(f, dir, oldname);
- if (node == NULL) {
- pthread_mutex_unlock(&f->lock);
- return NULL;
- }
- do {
- f->hidectr ++;
- snprintf(newname, bufsize, ".fuse_hidden%08x%08x",
- (unsigned int) node->nodeid, f->hidectr);
- newnode = lookup_node(f, dir, newname);
- } while(newnode);
- pthread_mutex_unlock(&f->lock);
-
- newpath = get_path_name(f, dir, newname);
- if (!newpath)
- break;
-
- res = fuse_fs_getattr(f->fs, newpath, &buf);
- if (res == -ENOENT)
- break;
- free(newpath);
- newpath = NULL;
- } while(res == 0 && --failctr);
-
- return newpath;
+ char *newname, size_t bufsize)
+{
+ struct stat buf;
+ struct node *node;
+ struct node *newnode;
+ char *newpath;
+ int res;
+ int failctr = 10;
+
+ do {
+ pthread_mutex_lock(&f->lock);
+ node = lookup_node(f, dir, oldname);
+ if (node == NULL) {
+ pthread_mutex_unlock(&f->lock);
+ return NULL;
+ }
+ do {
+ f->hidectr ++;
+ snprintf(newname, bufsize, ".fuse_hidden%08x%08x",
+ (unsigned int) node->nodeid, f->hidectr);
+ newnode = lookup_node(f, dir, newname);
+ } while(newnode);
+ pthread_mutex_unlock(&f->lock);
+
+ newpath = get_path_name(f, dir, newname);
+ if (!newpath)
+ break;
+
+ res = fuse_fs_getattr(f->fs, newpath, &buf);
+ if (res == -ENOENT)
+ break;
+ free(newpath);
+ newpath = NULL;
+ } while(res == 0 && --failctr);
+
+ return newpath;
}
static int hide_node(struct fuse *f, const char *oldpath,
- fuse_ino_t dir, const char *oldname)
+ fuse_ino_t dir, const char *oldname)
{
- char newname[64];
- char *newpath;
- int err = -EBUSY;
+ char newname[64];
+ char *newpath;
+ int err = -EBUSY;
- newpath = hidden_name(f, dir, oldname, newname, sizeof(newname));
- if (newpath) {
- err = fuse_fs_rename(f->fs, oldpath, newpath);
- if (!err)
- err = rename_node(f, dir, oldname, dir, newname, 1);
- free(newpath);
- }
- return err;
+ newpath = hidden_name(f, dir, oldname, newname, sizeof(newname));
+ if (newpath) {
+ err = fuse_fs_rename(f->fs, oldpath, newpath);
+ if (!err)
+ err = rename_node(f, dir, oldname, dir, newname, 1);
+ free(newpath);
+ }
+ return err;
}
static int mtime_eq(const struct stat *stbuf, const struct timespec *ts)
{
- return stbuf->st_mtime == ts->tv_sec && ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
+ return stbuf->st_mtime == ts->tv_sec &&
+ ST_MTIM_NSEC(stbuf) == ts->tv_nsec;
}
#ifndef CLOCK_MONOTONIC
@@ -1172,2122 +1180,2153 @@ static int mtime_eq(const struct stat *stbuf, const struct timespec *ts)
static void curr_time(struct timespec *now)
{
- static clockid_t clockid = CLOCK_MONOTONIC;
- int res = clock_gettime(clockid, now);
- if (res == -1 && errno == EINVAL) {
- clockid = CLOCK_REALTIME;
- res = clock_gettime(clockid, now);
- }
- if (res == -1) {
- perror("fuse: clock_gettime");
- abort();
- }
+ static clockid_t clockid = CLOCK_MONOTONIC;
+ int res = clock_gettime(clockid, now);
+ if (res == -1 && errno == EINVAL) {
+ clockid = CLOCK_REALTIME;
+ res = clock_gettime(clockid, now);
+ }
+ if (res == -1) {
+ perror("fuse: clock_gettime");
+ abort();
+ }
}
static void update_stat(struct node *node, const struct stat *stbuf)
{
- if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
- stbuf->st_size != node->size))
- node->cache_valid = 0;
- node->mtime.tv_sec = stbuf->st_mtime;
- node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
- node->size = stbuf->st_size;
- curr_time(&node->stat_updated);
+ if (node->cache_valid && (!mtime_eq(stbuf, &node->mtime) ||
+ stbuf->st_size != node->size))
+ node->cache_valid = 0;
+ node->mtime.tv_sec = stbuf->st_mtime;
+ node->mtime.tv_nsec = ST_MTIM_NSEC(stbuf);
+ node->size = stbuf->st_size;
+ curr_time(&node->stat_updated);
}
static int lookup_path(struct fuse *f, fuse_ino_t nodeid,
- const char *name, const char *path,
- struct fuse_entry_param *e, struct fuse_file_info *fi)
-{
- int res;
-
- memset(e, 0, sizeof(struct fuse_entry_param));
- if (fi)
- res = fuse_fs_fgetattr(f->fs, path, &e->attr, fi);
- else
- res = fuse_fs_getattr(f->fs, path, &e->attr);
- if (res == 0) {
- struct node *node;
-
- node = find_node(f, nodeid, name);
- if (node == NULL)
- res = -ENOMEM;
- else {
- e->ino = node->nodeid;
- e->generation = node->generation;
- e->entry_timeout = f->conf.entry_timeout;
- e->attr_timeout = f->conf.attr_timeout;
- if (f->conf.auto_cache) {
- pthread_mutex_lock(&f->lock);
- update_stat(node, &e->attr);
- pthread_mutex_unlock(&f->lock);
- }
- set_stat(f, e->ino, &e->attr);
- if (f->conf.debug)
- fprintf(stderr, " NODEID: %lu\n", (unsigned long) e->ino);
- }
- }
- return res;
+ const char *name, const char *path,
+ struct fuse_entry_param *e, struct fuse_file_info *fi)
+{
+ int res;
+
+ memset(e, 0, sizeof(struct fuse_entry_param));
+ if (fi)
+ res = fuse_fs_fgetattr(f->fs, path, &e->attr, fi);
+ else
+ res = fuse_fs_getattr(f->fs, path, &e->attr);
+ if (res == 0) {
+ struct node *node;
+
+ node = find_node(f, nodeid, name);
+ if (node == NULL)
+ res = -ENOMEM;
+ else {
+ e->ino = node->nodeid;
+ e->generation = node->generation;
+ e->entry_timeout = f->conf.entry_timeout;
+ e->attr_timeout = f->conf.attr_timeout;
+ if (f->conf.auto_cache) {
+ pthread_mutex_lock(&f->lock);
+ update_stat(node, &e->attr);
+ pthread_mutex_unlock(&f->lock);
+ }
+ set_stat(f, e->ino, &e->attr);
+ if (f->conf.debug)
+ fprintf(stderr, " NODEID: %lu\n",
+ (unsigned long) e->ino);
+ }
+ }
+ return res;
}
static struct fuse_context_i *fuse_get_context_internal(void)
{
- struct fuse_context_i *c;
-
- c = (struct fuse_context_i *) pthread_getspecific(fuse_context_key);
- if (c == NULL) {
- c = (struct fuse_context_i *) malloc(sizeof(struct fuse_context_i));
- if (c == NULL) {
- /* This is hard to deal with properly, so just abort. If
- memory is so low that the context cannot be allocated,
- there's not much hope for the filesystem anyway */
- fprintf(stderr, "fuse: failed to allocate thread specific data\n");
- abort();
- }
- pthread_setspecific(fuse_context_key, c);
- }
- return c;
+ struct fuse_context_i *c;
+
+ c = (struct fuse_context_i *) pthread_getspecific(fuse_context_key);
+ if (c == NULL) {
+ c = (struct fuse_context_i *)
+ malloc(sizeof(struct fuse_context_i));
+ if (c == NULL) {
+ /* This is hard to deal with properly, so just
+ abort. If memory is so low that the
+ context cannot be allocated, there's not
+ much hope for the filesystem anyway */
+ fprintf(stderr, "fuse: failed to allocate thread specific data\n");
+ abort();
+ }
+ pthread_setspecific(fuse_context_key, c);
+ }
+ return c;
}
static void fuse_freecontext(void *data)
{
- free(data);
+ free(data);
}
static int fuse_create_context_key(void)
{
- int err = 0;
- pthread_mutex_lock(&fuse_context_lock);
- if (!fuse_context_ref) {
- err = pthread_key_create(&fuse_context_key, fuse_freecontext);
- if (err) {
- fprintf(stderr, "fuse: failed to create thread specific key: %s\n",
- strerror(err));
- pthread_mutex_unlock(&fuse_context_lock);
- return -1;
- }
- }
- fuse_context_ref++;
- pthread_mutex_unlock(&fuse_context_lock);
- return 0;
+ int err = 0;
+ pthread_mutex_lock(&fuse_context_lock);
+ if (!fuse_context_ref) {
+ err = pthread_key_create(&fuse_context_key, fuse_freecontext);
+ if (err) {
+ fprintf(stderr, "fuse: failed to create thread specific key: %s\n",
+ strerror(err));
+ pthread_mutex_unlock(&fuse_context_lock);
+ return -1;
+ }
+ }
+ fuse_context_ref++;
+ pthread_mutex_unlock(&fuse_context_lock);
+ return 0;
}
static void fuse_delete_context_key(void)
{
- pthread_mutex_lock(&fuse_context_lock);
- fuse_context_ref--;
- if (!fuse_context_ref) {
- free(pthread_getspecific(fuse_context_key));
- pthread_key_delete(fuse_context_key);
- }
- pthread_mutex_unlock(&fuse_context_lock);
+ pthread_mutex_lock(&fuse_context_lock);
+ fuse_context_ref--;
+ if (!fuse_context_ref) {
+ free(pthread_getspecific(fuse_context_key));
+ pthread_key_delete(fuse_context_key);
+ }
+ pthread_mutex_unlock(&fuse_context_lock);
}
static struct fuse *req_fuse_prepare(fuse_req_t req)
{
- struct fuse_context_i *c = fuse_get_context_internal();
- const struct fuse_ctx *ctx = fuse_req_ctx(req);
- c->req = req;
- c->ctx.fuse = req_fuse(req);
- c->ctx.uid = ctx->uid;
- c->ctx.gid = ctx->gid;
- c->ctx.pid = ctx->pid;
- return c->ctx.fuse;
+ struct fuse_context_i *c = fuse_get_context_internal();
+ const struct fuse_ctx *ctx = fuse_req_ctx(req);
+ c->req = req;
+ c->ctx.fuse = req_fuse(req);
+ c->ctx.uid = ctx->uid;
+ c->ctx.gid = ctx->gid;
+ c->ctx.pid = ctx->pid;
+ return c->ctx.fuse;
}
static inline void reply_err(fuse_req_t req, int err)
{
- /* fuse_reply_err() uses non-negated errno values */
- fuse_reply_err(req, -err);
+ /* fuse_reply_err() uses non-negated errno values */
+ fuse_reply_err(req, -err);
}
static void reply_entry(fuse_req_t req, const struct fuse_entry_param *e,
- int err)
+ int err)
{
- if (!err) {
- struct fuse *f = req_fuse(req);
- if (fuse_reply_entry(req, e) == -ENOENT)
- forget_node(f, e->ino, 1);
- } else
- reply_err(req, err);
+ if (!err) {
+ struct fuse *f = req_fuse(req);
+ if (fuse_reply_entry(req, e) == -ENOENT)
+ forget_node(f, e->ino, 1);
+ } else
+ reply_err(req, err);
}
void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.init)
- fs->user_data = fs->op.init(conn);
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.init)
+ fs->user_data = fs->op.init(conn);
}
static void fuse_lib_init(void *data, struct fuse_conn_info *conn)
{
- struct fuse *f = (struct fuse *) data;
- struct fuse_context_i *c = fuse_get_context_internal();
+ struct fuse *f = (struct fuse *) data;
+ struct fuse_context_i *c = fuse_get_context_internal();
- memset(c, 0, sizeof(*c));
- c->ctx.fuse = f;
- fuse_fs_init(f->fs, conn);
+ memset(c, 0, sizeof(*c));
+ c->ctx.fuse = f;
+ fuse_fs_init(f->fs, conn);
}
void fuse_fs_destroy(struct fuse_fs *fs)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.destroy)
- fs->op.destroy(fs->user_data);
- if (fs->m)
- fuse_put_module(fs->m);
- free(fs);
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.destroy)
+ fs->op.destroy(fs->user_data);
+ if (fs->m)
+ fuse_put_module(fs->m);
+ free(fs);
}
static void fuse_lib_destroy(void *data)
{
- struct fuse *f = (struct fuse *) data;
- struct fuse_context_i *c = fuse_get_context_internal();
+ struct fuse *f = (struct fuse *) data;
+ struct fuse_context_i *c = fuse_get_context_internal();
- memset(c, 0, sizeof(*c));
- c->ctx.fuse = f;
- fuse_fs_destroy(f->fs);
- f->fs = NULL;
+ memset(c, 0, sizeof(*c));
+ c->ctx.fuse = f;
+ fuse_fs_destroy(f->fs);
+ f->fs = NULL;
}
static void fuse_lib_lookup(fuse_req_t req, fuse_ino_t parent,
- const char *name)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_entry_param e;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "LOOKUP %s\n", path);
- fuse_prepare_interrupt(f, req, &d);
- err = lookup_path(f, parent, name, path, &e, NULL);
- if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
- e.ino = 0;
- e.entry_timeout = f->conf.negative_timeout;
- err = 0;
- }
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_entry(req, &e, err);
+ const char *name)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_entry_param e;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "LOOKUP %s\n", path);
+ fuse_prepare_interrupt(f, req, &d);
+ err = lookup_path(f, parent, name, path, &e, NULL);
+ if (err == -ENOENT && f->conf.negative_timeout != 0.0) {
+ e.ino = 0;
+ e.entry_timeout = f->conf.negative_timeout;
+ err = 0;
+ }
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_entry(req, &e, err);
}
static void fuse_lib_forget(fuse_req_t req, fuse_ino_t ino,
- unsigned long nlookup)
+ unsigned long nlookup)
{
- struct fuse *f = req_fuse(req);
- if (f->conf.debug)
- fprintf(stderr, "FORGET %llu/%lu\n", (unsigned long long)ino, nlookup);
- forget_node(f, ino, nlookup);
- fuse_reply_none(req);
+ struct fuse *f = req_fuse(req);
+ if (f->conf.debug)
+ fprintf(stderr, "FORGET %llu/%lu\n", (unsigned long long)ino,
+ nlookup);
+ forget_node(f, ino, nlookup);
+ fuse_reply_none(req);
}
static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct stat buf;
- char *path;
- int err;
-
- (void) fi;
- memset(&buf, 0, sizeof(buf));
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_getattr(f->fs, path, &buf);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- if (!err) {
- if (f->conf.auto_cache) {
- pthread_mutex_lock(&f->lock);
- update_stat(get_node(f, ino), &buf);
- pthread_mutex_unlock(&f->lock);
- }
- set_stat(f, ino, &buf);
- fuse_reply_attr(req, &buf, f->conf.attr_timeout);
- } else
- reply_err(req, err);
+ struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct stat buf;
+ char *path;
+ int err;
+
+ (void) fi;
+ memset(&buf, 0, sizeof(buf));
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_getattr(f->fs, path, &buf);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ if (!err) {
+ if (f->conf.auto_cache) {
+ pthread_mutex_lock(&f->lock);
+ update_stat(get_node(f, ino), &buf);
+ pthread_mutex_unlock(&f->lock);
+ }
+ set_stat(f, ino, &buf);
+ fuse_reply_attr(req, &buf, f->conf.attr_timeout);
+ } else
+ reply_err(req, err);
}
int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode)
{
- fuse_get_context()->private_data = fs->user_data;
- if (fs->op.chmod)
- return fs->op.chmod(path, mode);
- else
- return -ENOSYS;
+ fuse_get_context()->private_data = fs->user_data;
+ if (fs->op.chmod)
+ return fs->op.chmod(path, mode);
+ else
+ return -ENOSYS;
}
static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
- int valid, struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct stat buf;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = 0;
- if (!err && (valid & FUSE_SET_ATTR_MODE))
- err = fuse_fs_chmod(f->fs, path, attr->st_mode);
- if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
- uid_t uid =
- (valid & FUSE_SET_ATTR_UID) ? attr->st_uid : (uid_t) -1;
- gid_t gid =
- (valid & FUSE_SET_ATTR_GID) ? attr->st_gid : (gid_t) -1;
- err = fuse_fs_chown(f->fs, path, uid, gid);
- }
- if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
- if (fi)
- err = fuse_fs_ftruncate(f->fs, path, attr->st_size, fi);
- else
- err = fuse_fs_truncate(f->fs, path, attr->st_size);
- }
- if (!err && (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
- (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
- struct timespec tv[2];
- tv[0].tv_sec = attr->st_atime;
- tv[0].tv_nsec = ST_ATIM_NSEC(attr);
- tv[1].tv_sec = attr->st_mtime;
- tv[1].tv_nsec = ST_MTIM_NSEC(attr);
- err = fuse_fs_utimens(f->fs, path, tv);
- }
- if (!err)
- err = fuse_fs_getattr(f->fs, path, &buf);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- if (!err) {
- if (f->conf.auto_cache) {
- pthread_mutex_lock(&f->lock);
- update_stat(get_node(f, ino), &buf);
- pthread_mutex_unlock(&f->lock);
- }
- set_stat(f, ino, &buf);
- fuse_reply_attr(req, &buf, f->conf.attr_timeout);
- } else
- reply_err(req, err);
+ int valid, struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct stat buf;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = 0;
+ if (!err && (valid & FUSE_SET_ATTR_MODE))
+ err = fuse_fs_chmod(f->fs, path, attr->st_mode);
+ if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) {
+ uid_t uid = (valid & FUSE_SET_ATTR_UID) ?
+ attr->st_uid : (uid_t) -1;
+ gid_t gid = (valid & FUSE_SET_ATTR_GID) ?
+ attr->st_gid : (gid_t) -1;
+ err = fuse_fs_chown(f->fs, path, uid, gid);
+ }
+ if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
+ if (fi)
+ err = fuse_fs_ftruncate(f->fs, path,
+ attr->st_size, fi);
+ else
+ err = fuse_fs_truncate(f->fs, path,
+ attr->st_size);
+ }
+ if (!err &&
+ (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) ==
+ (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) {
+ struct timespec tv[2];
+ tv[0].tv_sec = attr->st_atime;
+ tv[0].tv_nsec = ST_ATIM_NSEC(attr);
+ tv[1].tv_sec = attr->st_mtime;
+ tv[1].tv_nsec = ST_MTIM_NSEC(attr);
+ err = fuse_fs_utimens(f->fs, path, tv);
+ }
+ if (!err)
+ err = fuse_fs_getattr(f->fs, path, &buf);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ if (!err) {
+ if (f->conf.auto_cache) {
+ pthread_mutex_lock(&f->lock);
+ update_stat(get_node(f, ino), &buf);
+ pthread_mutex_unlock(&f->lock);
+ }
+ set_stat(f, ino, &buf);
+ fuse_reply_attr(req, &buf, f->conf.attr_timeout);
+ } else
+ reply_err(req, err);
}
static void fuse_lib_access(fuse_req_t req, fuse_ino_t ino, int mask)
{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "ACCESS %s 0%o\n", path, mask);
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_access(f->fs, path, mask);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "ACCESS %s 0%o\n", path, mask);
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_access(f->fs, path, mask);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static void fuse_lib_readlink(fuse_req_t req, fuse_ino_t ino)
{
- struct fuse *f = req_fuse_prepare(req);
- char linkname[PATH_MAX + 1];
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_readlink(f->fs, path, linkname, sizeof(linkname));
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- if (!err) {
- linkname[PATH_MAX] = '\0';
- fuse_reply_readlink(req, linkname);
- } else
- reply_err(req, err);
+ struct fuse *f = req_fuse_prepare(req);
+ char linkname[PATH_MAX + 1];
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_readlink(f->fs, path, linkname, sizeof(linkname));
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ if (!err) {
+ linkname[PATH_MAX] = '\0';
+ fuse_reply_readlink(req, linkname);
+ } else
+ reply_err(req, err);
}
static void fuse_lib_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode, dev_t rdev)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_entry_param e;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "MKNOD %s\n", path);
- fuse_prepare_interrupt(f, req, &d);
- err = -ENOSYS;
- if (S_ISREG(mode)) {
- struct fuse_file_info fi;
-
- memset(&fi, 0, sizeof(fi));
- fi.flags = O_CREAT | O_EXCL | O_WRONLY;
- err = fuse_fs_create(f->fs, path, mode, &fi);
- if (!err) {
- err = lookup_path(f, parent, name, path, &e, &fi);
- fuse_fs_release(f->fs, path, &fi);
- }
- }
- if (err == -ENOSYS) {
- err = fuse_fs_mknod(f->fs, path, mode, rdev);
- if (!err)
- err = lookup_path(f, parent, name, path, &e, NULL);
- }
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_entry(req, &e, err);
+ mode_t mode, dev_t rdev)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_entry_param e;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "MKNOD %s\n", path);
+ fuse_prepare_interrupt(f, req, &d);
+ err = -ENOSYS;
+ if (S_ISREG(mode)) {
+ struct fuse_file_info fi;
+
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = O_CREAT | O_EXCL | O_WRONLY;
+ err = fuse_fs_create(f->fs, path, mode, &fi);
+ if (!err) {
+ err = lookup_path(f, parent, name, path, &e,
+ &fi);
+ fuse_fs_release(f->fs, path, &fi);
+ }
+ }
+ if (err == -ENOSYS) {
+ err = fuse_fs_mknod(f->fs, path, mode, rdev);
+ if (!err)
+ err = lookup_path(f, parent, name, path, &e,
+ NULL);
+ }
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_entry(req, &e, err);
}
static void fuse_lib_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
- mode_t mode)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_entry_param e;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "MKDIR %s\n", path);
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_mkdir(f->fs, path, mode);
- if (!err)
- err = lookup_path(f, parent, name, path, &e, NULL);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_entry(req, &e, err);
+ mode_t mode)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_entry_param e;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "MKDIR %s\n", path);
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_mkdir(f->fs, path, mode);
+ if (!err)
+ err = lookup_path(f, parent, name, path, &e, NULL);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_entry(req, &e, err);
}
static void fuse_lib_unlink(fuse_req_t req, fuse_ino_t parent,
- const char *name)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_wrlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "UNLINK %s\n", path);
- fuse_prepare_interrupt(f, req, &d);
- if (!f->conf.hard_remove && is_open(f, parent, name))
- err = hide_node(f, path, parent, name);
- else {
- err = fuse_fs_unlink(f->fs, path);
- if (!err)
- remove_node(f, parent, name);
- }
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ const char *name)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_wrlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "UNLINK %s\n", path);
+ fuse_prepare_interrupt(f, req, &d);
+ if (!f->conf.hard_remove && is_open(f, parent, name))
+ err = hide_node(f, path, parent, name);
+ else {
+ err = fuse_fs_unlink(f->fs, path);
+ if (!err)
+ remove_node(f, parent, name);
+ }
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static void fuse_lib_rmdir(fuse_req_t req, fuse_ino_t parent, const char *name)
{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_wrlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "RMDIR %s\n", path);
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_rmdir(f->fs, path);
- fuse_finish_interrupt(f, req, &d);
- if (!err)
- remove_node(f, parent, name);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_wrlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "RMDIR %s\n", path);
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_rmdir(f->fs, path);
+ fuse_finish_interrupt(f, req, &d);
+ if (!err)
+ remove_node(f, parent, name);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static void fuse_lib_symlink(fuse_req_t req, const char *linkname,
- fuse_ino_t parent, const char *name)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_entry_param e;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "SYMLINK %s\n", path);
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_symlink(f->fs, linkname, path);
- if (!err)
- err = lookup_path(f, parent, name, path, &e, NULL);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_entry(req, &e, err);
+ fuse_ino_t parent, const char *name)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_entry_param e;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "SYMLINK %s\n", path);
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_symlink(f->fs, linkname, path);
+ if (!err)
+ err = lookup_path(f, parent, name, path, &e, NULL);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_entry(req, &e, err);
}
static void fuse_lib_rename(fuse_req_t req, fuse_ino_t olddir,
- const char *oldname, fuse_ino_t newdir,
- const char *newname)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *oldpath;
- char *newpath;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_wrlock(&f->tree_lock);
- oldpath = get_path_name(f, olddir, oldname);
- if (oldpath != NULL) {
- newpath = get_path_name(f, newdir, newname);
- if (newpath != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "RENAME %s -> %s\n", oldpath, newpath);
- err = 0;
- fuse_prepare_interrupt(f, req, &d);
- if (!f->conf.hard_remove && is_open(f, newdir, newname))
- err = hide_node(f, newpath, newdir, newname);
- if (!err) {
- err = fuse_fs_rename(f->fs, oldpath, newpath);
- if (!err)
- err = rename_node(f, olddir, oldname, newdir, newname, 0);
- }
- fuse_finish_interrupt(f, req, &d);
- free(newpath);
- }
- free(oldpath);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ const char *oldname, fuse_ino_t newdir,
+ const char *newname)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *oldpath;
+ char *newpath;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_wrlock(&f->tree_lock);
+ oldpath = get_path_name(f, olddir, oldname);
+ if (oldpath != NULL) {
+ newpath = get_path_name(f, newdir, newname);
+ if (newpath != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "RENAME %s -> %s\n", oldpath,
+ newpath);
+ err = 0;
+ fuse_prepare_interrupt(f, req, &d);
+ if (!f->conf.hard_remove && is_open(f, newdir, newname))
+ err = hide_node(f, newpath, newdir, newname);
+ if (!err) {
+ err = fuse_fs_rename(f->fs, oldpath, newpath);
+ if (!err)
+ err = rename_node(f, olddir, oldname,
+ newdir, newname, 0);
+ }
+ fuse_finish_interrupt(f, req, &d);
+ free(newpath);
+ }
+ free(oldpath);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static void fuse_lib_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
- const char *newname)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_entry_param e;
- char *oldpath;
- char *newpath;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- oldpath = get_path(f, ino);
- if (oldpath != NULL) {
- newpath = get_path_name(f, newparent, newname);
- if (newpath != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "LINK %s\n", newpath);
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_link(f->fs, oldpath, newpath);
- if (!err)
- err = lookup_path(f, newparent, newname, newpath, &e, NULL);
- fuse_finish_interrupt(f, req, &d);
- free(newpath);
- }
- free(oldpath);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_entry(req, &e, err);
+ const char *newname)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_entry_param e;
+ char *oldpath;
+ char *newpath;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ oldpath = get_path(f, ino);
+ if (oldpath != NULL) {
+ newpath = get_path_name(f, newparent, newname);
+ if (newpath != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "LINK %s\n", newpath);
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_link(f->fs, oldpath, newpath);
+ if (!err)
+ err = lookup_path(f, newparent, newname,
+ newpath, &e, NULL);
+ fuse_finish_interrupt(f, req, &d);
+ free(newpath);
+ }
+ free(oldpath);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_entry(req, &e, err);
}
static void fuse_do_release(struct fuse *f, fuse_ino_t ino, const char *path,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct node *node;
- int unlink_hidden = 0;
+ struct node *node;
+ int unlink_hidden = 0;
- fuse_fs_release(f->fs, path ? path : "-", fi);
+ fuse_fs_release(f->fs, path ? path : "-", fi);
- pthread_mutex_lock(&f->lock);
- node = get_node(f, ino);
- assert(node->open_count > 0);
- --node->open_count;
- if (node->is_hidden && !node->open_count) {
- unlink_hidden = 1;
- node->is_hidden = 0;
- }
- pthread_mutex_unlock(&f->lock);
+ pthread_mutex_lock(&f->lock);
+ node = get_node(f, ino);
+ assert(node->open_count > 0);
+ --node->open_count;
+ if (node->is_hidden && !node->open_count) {
+ unlink_hidden = 1;
+ node->is_hidden = 0;
+ }
+ pthread_mutex_unlock(&f->lock);
- if(unlink_hidden && path)
- fuse_fs_unlink(f->fs, path);
+ if(unlink_hidden && path)
+ fuse_fs_unlink(f->fs, path);
}
static void fuse_lib_create(fuse_req_t req, fuse_ino_t parent,
- const char *name, mode_t mode,
- struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_intr_data d;
- struct fuse_entry_param e;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path_name(f, parent, name);
- if (path) {
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_create(f->fs, path, mode, fi);
- if (!err) {
- err = lookup_path(f, parent, name, path, &e, fi);
- if (err)
- fuse_fs_release(f->fs, path, fi);
- else if (!S_ISREG(e.attr.st_mode)) {
- err = -EIO;
- fuse_fs_release(f->fs, path, fi);
- forget_node(f, e.ino, 1);
- } else {
- if (f->conf.direct_io)
- fi->direct_io = 1;
- if (f->conf.kernel_cache)
- fi->keep_cache = 1;
-
- }
- }
- fuse_finish_interrupt(f, req, &d);
- }
- if (!err) {
- pthread_mutex_lock(&f->lock);
- get_node(f, e.ino)->open_count++;
- pthread_mutex_unlock(&f->lock);
- if (fuse_reply_create(req, &e, fi) == -ENOENT) {
- /* The open syscall was interrupted, so it must be cancelled */
- fuse_prepare_interrupt(f, req, &d);
- fuse_do_release(f, e.ino, path, fi);
- fuse_finish_interrupt(f, req, &d);
- forget_node(f, e.ino, 1);
- } else if (f->conf.debug) {
- fprintf(stderr, " CREATE[%llu] flags: 0x%x %s\n",
- (unsigned long long) fi->fh, fi->flags, path);
- }
- } else
- reply_err(req, err);
-
- if (path)
- free(path);
-
- pthread_rwlock_unlock(&f->tree_lock);
+ const char *name, mode_t mode,
+ struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_intr_data d;
+ struct fuse_entry_param e;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path_name(f, parent, name);
+ if (path) {
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_create(f->fs, path, mode, fi);
+ if (!err) {
+ err = lookup_path(f, parent, name, path, &e, fi);
+ if (err)
+ fuse_fs_release(f->fs, path, fi);
+ else if (!S_ISREG(e.attr.st_mode)) {
+ err = -EIO;
+ fuse_fs_release(f->fs, path, fi);
+ forget_node(f, e.ino, 1);
+ } else {
+ if (f->conf.direct_io)
+ fi->direct_io = 1;
+ if (f->conf.kernel_cache)
+ fi->keep_cache = 1;
+
+ }
+ }
+ fuse_finish_interrupt(f, req, &d);
+ }
+ if (!err) {
+ pthread_mutex_lock(&f->lock);
+ get_node(f, e.ino)->open_count++;
+ pthread_mutex_unlock(&f->lock);
+ if (fuse_reply_create(req, &e, fi) == -ENOENT) {
+ /* The open syscall was interrupted, so it
+ must be cancelled */
+ fuse_prepare_interrupt(f, req, &d);
+ fuse_do_release(f, e.ino, path, fi);
+ fuse_finish_interrupt(f, req, &d);
+ forget_node(f, e.ino, 1);
+ } else if (f->conf.debug) {
+ fprintf(stderr, " CREATE[%llu] flags: 0x%x %s\n",
+ (unsigned long long) fi->fh, fi->flags, path);
+ }
+ } else
+ reply_err(req, err);
+
+ if (path)
+ free(path);
+
+ pthread_rwlock_unlock(&f->tree_lock);
}
static double diff_timespec(const struct timespec *t1,
- const struct timespec *t2)
+ const struct timespec *t2)
{
- return (t1->tv_sec - t2->tv_sec) +
- ((double) t1->tv_nsec - (double) t2->tv_nsec) / 1000000000.0;
+ return (t1->tv_sec - t2->tv_sec) +
+ ((double) t1->tv_nsec - (double) t2->tv_nsec) / 1000000000.0;
}
static void open_auto_cache(struct fuse *f, fuse_ino_t ino, const char *path,
- struct fuse_file_info *fi)
-{
- struct node *node;
-
- pthread_mutex_lock(&f->lock);
- node = get_node(f, ino);
- if (node->cache_valid) {
- struct timespec now;
-
- curr_time(&now);
- if (diff_timespec(&now, &node->stat_updated) > f->conf.ac_attr_timeout) {
- struct stat stbuf;
- int err;
- pthread_mutex_unlock(&f->lock);
- err = fuse_fs_fgetattr(f->fs, path, &stbuf, fi);
- pthread_mutex_lock(&f->lock);
- if (!err)
- update_stat(node, &stbuf);
- else
- node->cache_valid = 0;
- }
- }
- if (node->cache_valid)
- fi->keep_cache = 1;
-
- node->cache_valid = 1;
- pthread_mutex_unlock(&f->lock);
+ struct fuse_file_info *fi)
+{
+ struct node *node;
+
+ pthread_mutex_lock(&f->lock);
+ node = get_node(f, ino);
+ if (node->cache_valid) {
+ struct timespec now;
+
+ curr_time(&now);
+ if (diff_timespec(&now, &node->stat_updated) >
+ f->conf.ac_attr_timeout) {
+ struct stat stbuf;
+ int err;
+ pthread_mutex_unlock(&f->lock);
+ err = fuse_fs_fgetattr(f->fs, path, &stbuf, fi);
+ pthread_mutex_lock(&f->lock);
+ if (!err)
+ update_stat(node, &stbuf);
+ else
+ node->cache_valid = 0;
+ }
+ }
+ if (node->cache_valid)
+ fi->keep_cache = 1;
+
+ node->cache_valid = 1;
+ pthread_mutex_unlock(&f->lock);
}
static void fuse_lib_open(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_intr_data d;
- char *path = NULL;
- int err = 0;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path) {
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_open(f->fs, path, fi);
- if (!err) {
- if (f->conf.direct_io)
- fi->direct_io = 1;
- if (f->conf.kernel_cache)
- fi->keep_cache = 1;
-
- if (f->conf.auto_cache)
- open_auto_cache(f, ino, path, fi);
- }
- fuse_finish_interrupt(f, req, &d);
- }
- if (!err) {
- pthread_mutex_lock(&f->lock);
- get_node(f, ino)->open_count++;
- pthread_mutex_unlock(&f->lock);
- if (fuse_reply_open(req, fi) == -ENOENT) {
- /* The open syscall was interrupted, so it must be cancelled */
- fuse_prepare_interrupt(f, req, &d);
- fuse_do_release(f, ino, path, fi);
- fuse_finish_interrupt(f, req, &d);
- } else if (f->conf.debug) {
- fprintf(stderr, "OPEN[%llu] flags: 0x%x %s\n",
- (unsigned long long) fi->fh, fi->flags, path);
- }
- } else
- reply_err(req, err);
-
- if (path)
- free(path);
- pthread_rwlock_unlock(&f->tree_lock);
+ struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_intr_data d;
+ char *path = NULL;
+ int err = 0;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path) {
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_open(f->fs, path, fi);
+ if (!err) {
+ if (f->conf.direct_io)
+ fi->direct_io = 1;
+ if (f->conf.kernel_cache)
+ fi->keep_cache = 1;
+
+ if (f->conf.auto_cache)
+ open_auto_cache(f, ino, path, fi);
+ }
+ fuse_finish_interrupt(f, req, &d);
+ }
+ if (!err) {
+ pthread_mutex_lock(&f->lock);
+ get_node(f, ino)->open_count++;
+ pthread_mutex_unlock(&f->lock);
+ if (fuse_reply_open(req, fi) == -ENOENT) {
+ /* The open syscall was interrupted, so it
+ must be cancelled */
+ fuse_prepare_interrupt(f, req, &d);
+ fuse_do_release(f, ino, path, fi);
+ fuse_finish_interrupt(f, req, &d);
+ } else if (f->conf.debug) {
+ fprintf(stderr, "OPEN[%llu] flags: 0x%x %s\n",
+ (unsigned long long) fi->fh, fi->flags, path);
+ }
+ } else
+ reply_err(req, err);
+
+ if (path)
+ free(path);
+ pthread_rwlock_unlock(&f->tree_lock);
}
static void fuse_lib_read(fuse_req_t req, fuse_ino_t ino, size_t size,
- off_t off, struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- char *buf;
- int res;
-
- buf = (char *) malloc(size);
- if (buf == NULL) {
- reply_err(req, -ENOMEM);
- return;
- }
-
- res = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "READ[%llu] %lu bytes from %llu\n",
- (unsigned long long) fi->fh, (unsigned long) size,
- (unsigned long long) off);
-
- fuse_prepare_interrupt(f, req, &d);
- res = fuse_fs_read(f->fs, path, buf, size, off, fi);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
-
- if (res >= 0) {
- if (f->conf.debug)
- fprintf(stderr, " READ[%llu] %u bytes\n",
- (unsigned long long)fi->fh, res);
- if ((size_t) res > size)
- fprintf(stderr, "fuse: read too many bytes");
- fuse_reply_buf(req, buf, res);
- } else
- reply_err(req, res);
-
- free(buf);
+ off_t off, struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ char *buf;
+ int res;
+
+ buf = (char *) malloc(size);
+ if (buf == NULL) {
+ reply_err(req, -ENOMEM);
+ return;
+ }
+
+ res = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "READ[%llu] %lu bytes from %llu\n",
+ (unsigned long long) fi->fh,
+ (unsigned long) size, (unsigned long long) off);
+
+ fuse_prepare_interrupt(f, req, &d);
+ res = fuse_fs_read(f->fs, path, buf, size, off, fi);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+
+ if (res >= 0) {
+ if (f->conf.debug)
+ fprintf(stderr, " READ[%llu] %u bytes\n",
+ (unsigned long long)fi->fh, res);
+ if ((size_t) res > size)
+ fprintf(stderr, "fuse: read too many bytes");
+ fuse_reply_buf(req, buf, res);
+ } else
+ reply_err(req, res);
+
+ free(buf);
}
static void fuse_lib_write(fuse_req_t req, fuse_ino_t ino, const char *buf,
- size_t size, off_t off, struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int res;
-
- res = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "WRITE%s[%llu] %lu bytes to %llu\n",
- fi->writepage ? "PAGE" : "", (unsigned long long) fi->fh,
- (unsigned long) size, (unsigned long long) off);
-
- fuse_prepare_interrupt(f, req, &d);
- res = fuse_fs_write(f->fs, path, buf, size, off, fi);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
-
- if (res >= 0) {
- if (f->conf.debug)
- fprintf(stderr, " WRITE%s[%llu] %u bytes\n",
- fi->writepage ? "PAGE" : "", (unsigned long long) fi->fh,
- res);
- if ((size_t) res > size)
- fprintf(stderr, "fuse: wrote too many bytes");
- fuse_reply_write(req, res);
- } else
- reply_err(req, res);
+ size_t size, off_t off, struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int res;
+
+ res = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "WRITE%s[%llu] %lu bytes to %llu\n",
+ fi->writepage ? "PAGE" : "",
+ (unsigned long long) fi->fh,
+ (unsigned long) size, (unsigned long long) off);
+
+ fuse_prepare_interrupt(f, req, &d);
+ res = fuse_fs_write(f->fs, path, buf, size, off, fi);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+
+ if (res >= 0) {
+ if (f->conf.debug)
+ fprintf(stderr, " WRITE%s[%llu] %u bytes\n",
+ fi->writepage ? "PAGE" : "",
+ (unsigned long long) fi->fh, res);
+ if ((size_t) res > size)
+ fprintf(stderr, "fuse: wrote too many bytes");
+ fuse_reply_write(req, res);
+ } else
+ reply_err(req, res);
}
static void fuse_lib_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *fi)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- if (f->conf.debug)
- fprintf(stderr, "FSYNC[%llu]\n", (unsigned long long) fi->fh);
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_fsync(f->fs, path, datasync, fi);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ struct fuse_file_info *fi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ if (f->conf.debug)
+ fprintf(stderr, "FSYNC[%llu]\n",
+ (unsigned long long) fi->fh);
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_fsync(f->fs, path, datasync, fi);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static struct fuse_dh *get_dirhandle(const struct fuse_file_info *llfi,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct fuse_dh *dh = (struct fuse_dh *) (uintptr_t) llfi->fh;
- memset(fi, 0, sizeof(struct fuse_file_info));
- fi->fh = dh->fh;
- fi->fh_old = dh->fh;
- return dh;
+ struct fuse_dh *dh = (struct fuse_dh *) (uintptr_t) llfi->fh;
+ memset(fi, 0, sizeof(struct fuse_file_info));
+ fi->fh = dh->fh;
+ fi->fh_old = dh->fh;
+ return dh;
}
static void fuse_lib_opendir(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *llfi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_intr_data d;
- struct fuse_dh *dh;
- struct fuse_file_info fi;
- char *path;
- int err;
-
- dh = (struct fuse_dh *) malloc(sizeof(struct fuse_dh));
- if (dh == NULL) {
- reply_err(req, -ENOMEM);
- return;
- }
- memset(dh, 0, sizeof(struct fuse_dh));
- dh->fuse = f;
- dh->contents = NULL;
- dh->len = 0;
- dh->filled = 0;
- dh->nodeid = ino;
- fuse_mutex_init(&dh->lock);
-
- llfi->fh = (uintptr_t) dh;
-
- memset(&fi, 0, sizeof(fi));
- fi.flags = llfi->flags;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_opendir(f->fs, path, &fi);
- fuse_finish_interrupt(f, req, &d);
- dh->fh = fi.fh;
- }
- if (!err) {
- if (fuse_reply_open(req, llfi) == -ENOENT) {
- /* The opendir syscall was interrupted, so it must be cancelled */
- fuse_prepare_interrupt(f, req, &d);
- fuse_fs_releasedir(f->fs, path, &fi);
- fuse_finish_interrupt(f, req, &d);
- pthread_mutex_destroy(&dh->lock);
- free(dh);
- }
- } else {
- reply_err(req, err);
- free(dh);
- }
- free(path);
- pthread_rwlock_unlock(&f->tree_lock);
+ struct fuse_file_info *llfi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_intr_data d;
+ struct fuse_dh *dh;
+ struct fuse_file_info fi;
+ char *path;
+ int err;
+
+ dh = (struct fuse_dh *) malloc(sizeof(struct fuse_dh));
+ if (dh == NULL) {
+ reply_err(req, -ENOMEM);
+ return;
+ }
+ memset(dh, 0, sizeof(struct fuse_dh));
+ dh->fuse = f;
+ dh->contents = NULL;
+ dh->len = 0;
+ dh->filled = 0;
+ dh->nodeid = ino;
+ fuse_mutex_init(&dh->lock);
+
+ llfi->fh = (uintptr_t) dh;
+
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = llfi->flags;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_opendir(f->fs, path, &fi);
+ fuse_finish_interrupt(f, req, &d);
+ dh->fh = fi.fh;
+ }
+ if (!err) {
+ if (fuse_reply_open(req, llfi) == -ENOENT) {
+ /* The opendir syscall was interrupted, so it
+ must be cancelled */
+ fuse_prepare_interrupt(f, req, &d);
+ fuse_fs_releasedir(f->fs, path, &fi);
+ fuse_finish_interrupt(f, req, &d);
+ pthread_mutex_destroy(&dh->lock);
+ free(dh);
+ }
+ } else {
+ reply_err(req, err);
+ free(dh);
+ }
+ free(path);
+ pthread_rwlock_unlock(&f->tree_lock);
}
static int extend_contents(struct fuse_dh *dh, unsigned minsize)
{
- if (minsize > dh->size) {
- char *newptr;
- unsigned newsize = dh->size;
- if (!newsize)
- newsize = 1024;
- while (newsize < minsize)
- newsize *= 2;
-
- newptr = (char *) realloc(dh->contents, newsize);
- if (!newptr) {
- dh->error = -ENOMEM;
- return -1;
- }
- dh->contents = newptr;
- dh->size = newsize;
- }
- return 0;
+ if (minsize > dh->size) {
+ char *newptr;
+ unsigned newsize = dh->size;
+ if (!newsize)
+ newsize = 1024;
+ while (newsize < minsize)
+ newsize *= 2;
+
+ newptr = (char *) realloc(dh->contents, newsize);
+ if (!newptr) {
+ dh->error = -ENOMEM;
+ return -1;
+ }
+ dh->contents = newptr;
+ dh->size = newsize;
+ }
+ return 0;
}
static int fill_dir(void *dh_, const char *name, const struct stat *statp,
- off_t off)
-{
- struct fuse_dh *dh = (struct fuse_dh *) dh_;
- struct stat stbuf;
- size_t newlen;
-
- if (statp)
- stbuf = *statp;
- else {
- memset(&stbuf, 0, sizeof(stbuf));
- stbuf.st_ino = FUSE_UNKNOWN_INO;
- }
-
- if (!dh->fuse->conf.use_ino) {
- stbuf.st_ino = FUSE_UNKNOWN_INO;
- if (dh->fuse->conf.readdir_ino) {
- struct node *node;
- pthread_mutex_lock(&dh->fuse->lock);
- node = lookup_node(dh->fuse, dh->nodeid, name);
- if (node)
- stbuf.st_ino = (ino_t) node->nodeid;
- pthread_mutex_unlock(&dh->fuse->lock);
- }
- }
-
- if (off) {
- if (extend_contents(dh, dh->needlen) == -1)
- return 1;
-
- dh->filled = 0;
- newlen = dh->len + fuse_add_direntry(dh->req, dh->contents + dh->len,
- dh->needlen - dh->len, name,
- &stbuf, off);
- if (newlen > dh->needlen)
- return 1;
- } else {
- newlen = dh->len + fuse_add_direntry(dh->req, NULL, 0, name, NULL, 0);
- if (extend_contents(dh, newlen) == -1)
- return 1;
-
- fuse_add_direntry(dh->req, dh->contents + dh->len, dh->size - dh->len,
- name, &stbuf, newlen);
- }
- dh->len = newlen;
- return 0;
+ off_t off)
+{
+ struct fuse_dh *dh = (struct fuse_dh *) dh_;
+ struct stat stbuf;
+ size_t newlen;
+
+ if (statp)
+ stbuf = *statp;
+ else {
+ memset(&stbuf, 0, sizeof(stbuf));
+ stbuf.st_ino = FUSE_UNKNOWN_INO;
+ }
+
+ if (!dh->fuse->conf.use_ino) {
+ stbuf.st_ino = FUSE_UNKNOWN_INO;
+ if (dh->fuse->conf.readdir_ino) {
+ struct node *node;
+ pthread_mutex_lock(&dh->fuse->lock);
+ node = lookup_node(dh->fuse, dh->nodeid, name);
+ if (node)
+ stbuf.st_ino = (ino_t) node->nodeid;
+ pthread_mutex_unlock(&dh->fuse->lock);
+ }
+ }
+
+ if (off) {
+ if (extend_contents(dh, dh->needlen) == -1)
+ return 1;
+
+ dh->filled = 0;
+ newlen = dh->len +
+ fuse_add_direntry(dh->req, dh->contents + dh->len,
+ dh->needlen - dh->len, name,
+ &stbuf, off);
+ if (newlen > dh->needlen)
+ return 1;
+ } else {
+ newlen = dh->len +
+ fuse_add_direntry(dh->req, NULL, 0, name, NULL, 0);
+ if (extend_contents(dh, newlen) == -1)
+ return 1;
+
+ fuse_add_direntry(dh->req, dh->contents + dh->len,
+ dh->size - dh->len, name, &stbuf, newlen);
+ }
+ dh->len = newlen;
+ return 0;
}
static int readdir_fill(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
- size_t size, off_t off, struct fuse_dh *dh,
- struct fuse_file_info *fi)
-{
- int err = -ENOENT;
- char *path;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
-
- dh->len = 0;
- dh->error = 0;
- dh->needlen = size;
- dh->filled = 1;
- dh->req = req;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_readdir(f->fs, path, dh, fill_dir, off, fi);
- fuse_finish_interrupt(f, req, &d);
- dh->req = NULL;
- if (!err)
- err = dh->error;
- if (err)
- dh->filled = 0;
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- return err;
+ size_t size, off_t off, struct fuse_dh *dh,
+ struct fuse_file_info *fi)
+{
+ int err = -ENOENT;
+ char *path;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+
+ dh->len = 0;
+ dh->error = 0;
+ dh->needlen = size;
+ dh->filled = 1;
+ dh->req = req;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_readdir(f->fs, path, dh, fill_dir, off, fi);
+ fuse_finish_interrupt(f, req, &d);
+ dh->req = NULL;
+ if (!err)
+ err = dh->error;
+ if (err)
+ dh->filled = 0;
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ return err;
}
static void fuse_lib_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
- off_t off, struct fuse_file_info *llfi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_file_info fi;
- struct fuse_dh *dh = get_dirhandle(llfi, &fi);
-
- pthread_mutex_lock(&dh->lock);
- /* According to SUS, directory contents need to be refreshed on
- rewinddir() */
- if (!off)
- dh->filled = 0;
-
- if (!dh->filled) {
- int err = readdir_fill(f, req, ino, size, off, dh, &fi);
- if (err) {
- reply_err(req, err);
- goto out;
- }
- }
- if (dh->filled) {
- if (off < dh->len) {
- if (off + size > dh->len)
- size = dh->len - off;
- } else
- size = 0;
- } else {
- size = dh->len;
- off = 0;
- }
- fuse_reply_buf(req, dh->contents + off, size);
- out:
- pthread_mutex_unlock(&dh->lock);
+ off_t off, struct fuse_file_info *llfi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_file_info fi;
+ struct fuse_dh *dh = get_dirhandle(llfi, &fi);
+
+ pthread_mutex_lock(&dh->lock);
+ /* According to SUS, directory contents need to be refreshed on
+ rewinddir() */
+ if (!off)
+ dh->filled = 0;
+
+ if (!dh->filled) {
+ int err = readdir_fill(f, req, ino, size, off, dh, &fi);
+ if (err) {
+ reply_err(req, err);
+ goto out;
+ }
+ }
+ if (dh->filled) {
+ if (off < dh->len) {
+ if (off + size > dh->len)
+ size = dh->len - off;
+ } else
+ size = 0;
+ } else {
+ size = dh->len;
+ off = 0;
+ }
+ fuse_reply_buf(req, dh->contents + off, size);
+out:
+ pthread_mutex_unlock(&dh->lock);
}
static void fuse_lib_releasedir(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *llfi)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_intr_data d;
- struct fuse_file_info fi;
- struct fuse_dh *dh = get_dirhandle(llfi, &fi);
- char *path;
-
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- fuse_prepare_interrupt(f, req, &d);
- fuse_fs_releasedir(f->fs, path ? path : "-", &fi);
- fuse_finish_interrupt(f, req, &d);
- if (path)
- free(path);
- pthread_rwlock_unlock(&f->tree_lock);
- pthread_mutex_lock(&dh->lock);
- pthread_mutex_unlock(&dh->lock);
- pthread_mutex_destroy(&dh->lock);
- free(dh->contents);
- free(dh);
- reply_err(req, 0);
+ struct fuse_file_info *llfi)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_intr_data d;
+ struct fuse_file_info fi;
+ struct fuse_dh *dh = get_dirhandle(llfi, &fi);
+ char *path;
+
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ fuse_prepare_interrupt(f, req, &d);
+ fuse_fs_releasedir(f->fs, path ? path : "-", &fi);
+ fuse_finish_interrupt(f, req, &d);
+ if (path)
+ free(path);
+ pthread_rwlock_unlock(&f->tree_lock);
+ pthread_mutex_lock(&dh->lock);
+ pthread_mutex_unlock(&dh->lock);
+ pthread_mutex_destroy(&dh->lock);
+ free(dh->contents);
+ free(dh);
+ reply_err(req, 0);
}
static void fuse_lib_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
- struct fuse_file_info *llfi)
+ struct fuse_file_info *llfi)
{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_file_info fi;
- char *path;
- int err;
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_file_info fi;
+ char *path;
+ int err;
- get_dirhandle(llfi, &fi);
+ get_dirhandle(llfi, &fi);
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_fsyncdir(f->fs, path, datasync, &fi);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino)
{
- struct fuse *f = req_fuse_prepare(req);
- struct statvfs buf;
- char *path;
- int err;
-
- memset(&buf, 0, sizeof(buf));
- pthread_rwlock_rdlock(&f->tree_lock);
- if (!ino) {
- err = -ENOMEM;
- path = strdup("/");
- } else {
- err = -ENOENT;
- path = get_path(f, ino);
- }
- if (path) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_statfs(f->fs, path, &buf);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
-
- if (!err)
- fuse_reply_statfs(req, &buf);
- else
- reply_err(req, err);
+ struct fuse *f = req_fuse_prepare(req);
+ struct statvfs buf;
+ char *path;
+ int err;
+
+ memset(&buf, 0, sizeof(buf));
+ pthread_rwlock_rdlock(&f->tree_lock);
+ if (!ino) {
+ err = -ENOMEM;
+ path = strdup("/");
+ } else {
+ err = -ENOENT;
+ path = get_path(f, ino);
+ }
+ if (path) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_statfs(f->fs, path, &buf);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+
+ if (!err)
+ fuse_reply_statfs(req, &buf);
+ else
+ reply_err(req, err);
}
static void fuse_lib_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
- const char *value, size_t size, int flags)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ const char *value, size_t size, int flags)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_setxattr(f->fs, path, name, value, size, flags);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static int common_getxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
- const char *name, char *value, size_t size)
+ const char *name, char *value, size_t size)
{
- int err;
- char *path;
+ int err;
+ char *path;
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_getxattr(f->fs, path, name, value, size);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- return err;
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_getxattr(f->fs, path, name, value, size);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ return err;
}
static void fuse_lib_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
- size_t size)
-{
- struct fuse *f = req_fuse_prepare(req);
- int res;
-
- if (size) {
- char *value = (char *) malloc(size);
- if (value == NULL) {
- reply_err(req, -ENOMEM);
- return;
- }
- res = common_getxattr(f, req, ino, name, value, size);
- if (res > 0)
- fuse_reply_buf(req, value, res);
- else
- reply_err(req, res);
- free(value);
- } else {
- res = common_getxattr(f, req, ino, name, NULL, 0);
- if (res >= 0)
- fuse_reply_xattr(req, res);
- else
- reply_err(req, res);
- }
+ size_t size)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ int res;
+
+ if (size) {
+ char *value = (char *) malloc(size);
+ if (value == NULL) {
+ reply_err(req, -ENOMEM);
+ return;
+ }
+ res = common_getxattr(f, req, ino, name, value, size);
+ if (res > 0)
+ fuse_reply_buf(req, value, res);
+ else
+ reply_err(req, res);
+ free(value);
+ } else {
+ res = common_getxattr(f, req, ino, name, NULL, 0);
+ if (res >= 0)
+ fuse_reply_xattr(req, res);
+ else
+ reply_err(req, res);
+ }
}
static int common_listxattr(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
- char *list, size_t size)
+ char *list, size_t size)
{
- char *path;
- int err;
+ char *path;
+ int err;
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_listxattr(f->fs, path, list, size);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- return err;
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_listxattr(f->fs, path, list, size);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ return err;
}
static void fuse_lib_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
{
- struct fuse *f = req_fuse_prepare(req);
- int res;
-
- if (size) {
- char *list = (char *) malloc(size);
- if (list == NULL) {
- reply_err(req, -ENOMEM);
- return;
- }
- res = common_listxattr(f, req, ino, list, size);
- if (res > 0)
- fuse_reply_buf(req, list, res);
- else
- reply_err(req, res);
- free(list);
- } else {
- res = common_listxattr(f, req, ino, NULL, 0);
- if (res >= 0)
- fuse_reply_xattr(req, res);
- else
- reply_err(req, res);
- }
+ struct fuse *f = req_fuse_prepare(req);
+ int res;
+
+ if (size) {
+ char *list = (char *) malloc(size);
+ if (list == NULL) {
+ reply_err(req, -ENOMEM);
+ return;
+ }
+ res = common_listxattr(f, req, ino, list, size);
+ if (res > 0)
+ fuse_reply_buf(req, list, res);
+ else
+ reply_err(req, res);
+ free(list);
+ } else {
+ res = common_listxattr(f, req, ino, NULL, 0);
+ if (res >= 0)
+ fuse_reply_xattr(req, res);
+ else
+ reply_err(req, res);
+ }
}
static void fuse_lib_removexattr(fuse_req_t req, fuse_ino_t ino,
- const char *name)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_removexattr(f->fs, path, name);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ const char *name)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_removexattr(f->fs, path, name);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static struct lock *locks_conflict(struct node *node, const struct lock *lock)
{
- struct lock *l;
+ struct lock *l;
- for (l = node->locks; l; l = l->next)
- if (l->owner != lock->owner &&
- lock->start <= l->end && l->start <= lock->end &&
- (l->type == F_WRLCK || lock->type == F_WRLCK))
- break;
+ for (l = node->locks; l; l = l->next)
+ if (l->owner != lock->owner &&
+ lock->start <= l->end && l->start <= lock->end &&
+ (l->type == F_WRLCK || lock->type == F_WRLCK))
+ break;
- return l;
+ return l;
}
static void delete_lock(struct lock **lockp)
{
- struct lock *l = *lockp;
- *lockp = l->next;
- free(l);
+ struct lock *l = *lockp;
+ *lockp = l->next;
+ free(l);
}
static void insert_lock(struct lock **pos, struct lock *lock)
{
- lock->next = *pos;
- *pos = lock;
+ lock->next = *pos;
+ *pos = lock;
}
static int locks_insert(struct node *node, struct lock *lock)
{
- struct lock **lp;
- struct lock *newl1 = NULL;
- struct lock *newl2 = NULL;
-
- if (lock->type != F_UNLCK || lock->start != 0 || lock->end != OFFSET_MAX) {
- newl1 = malloc(sizeof(struct lock));
- newl2 = malloc(sizeof(struct lock));
-
- if (!newl1 || !newl2) {
- free(newl1);
- free(newl2);
- return -ENOLCK;
- }
- }
-
- for (lp = &node->locks; *lp;) {
- struct lock *l = *lp;
- if (l->owner != lock->owner)
- goto skip;
-
- if (lock->type == l->type) {
- if (l->end < lock->start - 1)
- goto skip;
- if (lock->end < l->start - 1)
- break;
- if (l->start <= lock->start && lock->end <= l->end)
- goto out;
- if (l->start < lock->start)
- lock->start = l->start;
- if (lock->end < l->end)
- lock->end = l->end;
- goto delete;
- } else {
- if (l->end < lock->start)
- goto skip;
- if (lock->end < l->start)
- break;
- if (lock->start <= l->start && l->end <= lock->end)
- goto delete;
- if (l->end <= lock->end) {
- l->end = lock->start - 1;
- goto skip;
- }
- if (lock->start <= l->start) {
- l->start = lock->end + 1;
- break;
- }
- *newl2 = *l;
- newl2->start = lock->end + 1;
- l->end = lock->start - 1;
- insert_lock(&l->next, newl2);
- newl2 = NULL;
- }
- skip:
- lp = &l->next;
- continue;
-
- delete:
- delete_lock(lp);
- }
- if (lock->type != F_UNLCK) {
- *newl1 = *lock;
- insert_lock(lp, newl1);
- newl1 = NULL;
- }
+ struct lock **lp;
+ struct lock *newl1 = NULL;
+ struct lock *newl2 = NULL;
+
+ if (lock->type != F_UNLCK || lock->start != 0 ||
+ lock->end != OFFSET_MAX) {
+ newl1 = malloc(sizeof(struct lock));
+ newl2 = malloc(sizeof(struct lock));
+
+ if (!newl1 || !newl2) {
+ free(newl1);
+ free(newl2);
+ return -ENOLCK;
+ }
+ }
+
+ for (lp = &node->locks; *lp;) {
+ struct lock *l = *lp;
+ if (l->owner != lock->owner)
+ goto skip;
+
+ if (lock->type == l->type) {
+ if (l->end < lock->start - 1)
+ goto skip;
+ if (lock->end < l->start - 1)
+ break;
+ if (l->start <= lock->start && lock->end <= l->end)
+ goto out;
+ if (l->start < lock->start)
+ lock->start = l->start;
+ if (lock->end < l->end)
+ lock->end = l->end;
+ goto delete;
+ } else {
+ if (l->end < lock->start)
+ goto skip;
+ if (lock->end < l->start)
+ break;
+ if (lock->start <= l->start && l->end <= lock->end)
+ goto delete;
+ if (l->end <= lock->end) {
+ l->end = lock->start - 1;
+ goto skip;
+ }
+ if (lock->start <= l->start) {
+ l->start = lock->end + 1;
+ break;
+ }
+ *newl2 = *l;
+ newl2->start = lock->end + 1;
+ l->end = lock->start - 1;
+ insert_lock(&l->next, newl2);
+ newl2 = NULL;
+ }
+ skip:
+ lp = &l->next;
+ continue;
+
+ delete:
+ delete_lock(lp);
+ }
+ if (lock->type != F_UNLCK) {
+ *newl1 = *lock;
+ insert_lock(lp, newl1);
+ newl1 = NULL;
+ }
out:
- free(newl1);
- free(newl2);
- return 0;
+ free(newl1);
+ free(newl2);
+ return 0;
}
static void flock_to_lock(struct flock *flock, struct lock *lock)
{
- memset(lock, 0, sizeof(struct lock));
- lock->type = flock->l_type;
- lock->start = flock->l_start;
- lock->end = flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
- lock->pid = flock->l_pid;
+ memset(lock, 0, sizeof(struct lock));
+ lock->type = flock->l_type;
+ lock->start = flock->l_start;
+ lock->end =
+ flock->l_len ? flock->l_start + flock->l_len - 1 : OFFSET_MAX;
+ lock->pid = flock->l_pid;
}
static void lock_to_flock(struct lock *lock, struct flock *flock)
{
- flock->l_type = lock->type;
- flock->l_start = lock->start;
- flock->l_len = (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
- flock->l_pid = lock->pid;
+ flock->l_type = lock->type;
+ flock->l_start = lock->start;
+ flock->l_len =
+ (lock->end == OFFSET_MAX) ? 0 : lock->end - lock->start + 1;
+ flock->l_pid = lock->pid;
}
static int fuse_flush_common(struct fuse *f, fuse_req_t req, fuse_ino_t ino,
- const char *path, struct fuse_file_info *fi)
-{
- struct fuse_intr_data d;
- struct flock lock;
- struct lock l;
- int err;
- int errlock;
-
- fuse_prepare_interrupt(f, req, &d);
- memset(&lock, 0, sizeof(lock));
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- err = fuse_fs_flush(f->fs, path, fi);
- errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
- fuse_finish_interrupt(f, req, &d);
-
- if (errlock != -ENOSYS) {
- flock_to_lock(&lock, &l);
- l.owner = fi->lock_owner;
- pthread_mutex_lock(&f->lock);
- locks_insert(get_node(f, ino), &l);
- pthread_mutex_unlock(&f->lock);
-
- /* if op.lock() is defined FLUSH is needed regardless of op.flush() */
- if (err == -ENOSYS)
- err = 0;
- }
- return err;
+ const char *path, struct fuse_file_info *fi)
+{
+ struct fuse_intr_data d;
+ struct flock lock;
+ struct lock l;
+ int err;
+ int errlock;
+
+ fuse_prepare_interrupt(f, req, &d);
+ memset(&lock, 0, sizeof(lock));
+ lock.l_type = F_UNLCK;
+ lock.l_whence = SEEK_SET;
+ err = fuse_fs_flush(f->fs, path, fi);
+ errlock = fuse_fs_lock(f->fs, path, fi, F_SETLK, &lock);
+ fuse_finish_interrupt(f, req, &d);
+
+ if (errlock != -ENOSYS) {
+ flock_to_lock(&lock, &l);
+ l.owner = fi->lock_owner;
+ pthread_mutex_lock(&f->lock);
+ locks_insert(get_node(f, ino), &l);
+ pthread_mutex_unlock(&f->lock);
+
+ /* if op.lock() is defined FLUSH is needed regardless
+ of op.flush() */
+ if (err == -ENOSYS)
+ err = 0;
+ }
+ return err;
}
static void fuse_lib_release(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_intr_data d;
- char *path;
- int err = 0;
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_intr_data d;
+ char *path;
+ int err = 0;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (f->conf.debug)
- fprintf(stderr, "RELEASE%s[%llu] flags: 0x%x\n",
- fi->flush ? "+FLUSH" : "",
- (unsigned long long) fi->fh, fi->flags);
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (f->conf.debug)
+ fprintf(stderr, "RELEASE%s[%llu] flags: 0x%x\n",
+ fi->flush ? "+FLUSH" : "",
+ (unsigned long long) fi->fh, fi->flags);
- if (fi->flush) {
- err = fuse_flush_common(f, req, ino, path, fi);
- if (err == -ENOSYS)
- err = 0;
- }
+ if (fi->flush) {
+ err = fuse_flush_common(f, req, ino, path, fi);
+ if (err == -ENOSYS)
+ err = 0;
+ }
- fuse_prepare_interrupt(f, req, &d);
- fuse_do_release(f, ino, path, fi);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- pthread_rwlock_unlock(&f->tree_lock);
+ fuse_prepare_interrupt(f, req, &d);
+ fuse_do_release(f, ino, path, fi);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ reply_err(req, err);
}
static void fuse_lib_flush(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path && f->conf.debug)
- fprintf(stderr, "FLUSH[%llu]\n", (unsigned long long) fi->fh);
- err = fuse_flush_common(f, req, ino, path, fi);
- free(path);
- pthread_rwlock_unlock(&f->tree_lock);
- reply_err(req, err);
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path && f->conf.debug)
+ fprintf(stderr, "FLUSH[%llu]\n", (unsigned long long) fi->fh);
+ err = fuse_flush_common(f, req, ino, path, fi);
+ free(path);
+ pthread_rwlock_unlock(&f->tree_lock);
+ reply_err(req, err);
}
static int fuse_lock_common(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi, struct flock *lock,
- int cmd)
-{
- struct fuse *f = req_fuse_prepare(req);
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- struct fuse_intr_data d;
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- return err;
+ struct fuse_file_info *fi, struct flock *lock,
+ int cmd)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ struct fuse_intr_data d;
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_lock(f->fs, path, fi, cmd, lock);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ return err;
}
static void fuse_lib_getlk(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi, struct flock *lock)
-{
- int err;
- struct lock l;
- struct lock *conflict;
- struct fuse *f = req_fuse(req);
-
- flock_to_lock(lock, &l);
- l.owner = fi->lock_owner;
- pthread_mutex_lock(&f->lock);
- conflict = locks_conflict(get_node(f, ino), &l);
- if (conflict)
- lock_to_flock(conflict, lock);
- pthread_mutex_unlock(&f->lock);
- if (!conflict)
- err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
- else
- err = 0;
-
- if (!err)
- fuse_reply_lock(req, lock);
- else
- reply_err(req, err);
+ struct fuse_file_info *fi, struct flock *lock)
+{
+ int err;
+ struct lock l;
+ struct lock *conflict;
+ struct fuse *f = req_fuse(req);
+
+ flock_to_lock(lock, &l);
+ l.owner = fi->lock_owner;
+ pthread_mutex_lock(&f->lock);
+ conflict = locks_conflict(get_node(f, ino), &l);
+ if (conflict)
+ lock_to_flock(conflict, lock);
+ pthread_mutex_unlock(&f->lock);
+ if (!conflict)
+ err = fuse_lock_common(req, ino, fi, lock, F_GETLK);
+ else
+ err = 0;
+
+ if (!err)
+ fuse_reply_lock(req, lock);
+ else
+ reply_err(req, err);
}
static void fuse_lib_setlk(fuse_req_t req, fuse_ino_t ino,
- struct fuse_file_info *fi, struct flock *lock,
- int sleep)
-{
- int err = fuse_lock_common(req, ino, fi, lock, sleep ? F_SETLKW : F_SETLK);
- if (!err) {
- struct fuse *f = req_fuse(req);
- struct lock l;
- flock_to_lock(lock, &l);
- l.owner = fi->lock_owner;
- pthread_mutex_lock(&f->lock);
- locks_insert(get_node(f, ino), &l);
- pthread_mutex_unlock(&f->lock);
- }
- reply_err(req, err);
+ struct fuse_file_info *fi, struct flock *lock,
+ int sleep)
+{
+ int err = fuse_lock_common(req, ino, fi, lock,
+ sleep ? F_SETLKW : F_SETLK);
+ if (!err) {
+ struct fuse *f = req_fuse(req);
+ struct lock l;
+ flock_to_lock(lock, &l);
+ l.owner = fi->lock_owner;
+ pthread_mutex_lock(&f->lock);
+ locks_insert(get_node(f, ino), &l);
+ pthread_mutex_unlock(&f->lock);
+ }
+ reply_err(req, err);
}
static void fuse_lib_bmap(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
- uint64_t idx)
-{
- struct fuse *f = req_fuse_prepare(req);
- struct fuse_intr_data d;
- char *path;
- int err;
-
- err = -ENOENT;
- pthread_rwlock_rdlock(&f->tree_lock);
- path = get_path(f, ino);
- if (path != NULL) {
- fuse_prepare_interrupt(f, req, &d);
- err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
- fuse_finish_interrupt(f, req, &d);
- free(path);
- }
- pthread_rwlock_unlock(&f->tree_lock);
- if (!err)
- fuse_reply_bmap(req, idx);
- else
- reply_err(req, err);
+ uint64_t idx)
+{
+ struct fuse *f = req_fuse_prepare(req);
+ struct fuse_intr_data d;
+ char *path;
+ int err;
+
+ err = -ENOENT;
+ pthread_rwlock_rdlock(&f->tree_lock);
+ path = get_path(f, ino);
+ if (path != NULL) {
+ fuse_prepare_interrupt(f, req, &d);
+ err = fuse_fs_bmap(f->fs, path, blocksize, &idx);
+ fuse_finish_interrupt(f, req, &d);
+ free(path);
+ }
+ pthread_rwlock_unlock(&f->tree_lock);
+ if (!err)
+ fuse_reply_bmap(req, idx);
+ else
+ reply_err(req, err);
}
static struct fuse_lowlevel_ops fuse_path_ops = {
- .init = fuse_lib_init,
- .destroy = fuse_lib_destroy,
- .lookup = fuse_lib_lookup,
- .forget = fuse_lib_forget,
- .getattr = fuse_lib_getattr,
- .setattr = fuse_lib_setattr,
- .access = fuse_lib_access,
- .readlink = fuse_lib_readlink,
- .mknod = fuse_lib_mknod,
- .mkdir = fuse_lib_mkdir,
- .unlink = fuse_lib_unlink,
- .rmdir = fuse_lib_rmdir,
- .symlink = fuse_lib_symlink,
- .rename = fuse_lib_rename,
- .link = fuse_lib_link,
- .create = fuse_lib_create,
- .open = fuse_lib_open,
- .read = fuse_lib_read,
- .write = fuse_lib_write,
- .flush = fuse_lib_flush,
- .release = fuse_lib_release,
- .fsync = fuse_lib_fsync,
- .opendir = fuse_lib_opendir,
- .readdir = fuse_lib_readdir,
- .releasedir = fuse_lib_releasedir,
- .fsyncdir = fuse_lib_fsyncdir,
- .statfs = fuse_lib_statfs,
- .setxattr = fuse_lib_setxattr,
- .getxattr = fuse_lib_getxattr,
- .listxattr = fuse_lib_listxattr,
- .removexattr = fuse_lib_removexattr,
- .getlk = fuse_lib_getlk,
- .setlk = fuse_lib_setlk,
- .bmap = fuse_lib_bmap,
+ .init = fuse_lib_init,
+ .destroy = fuse_lib_destroy,
+ .lookup = fuse_lib_lookup,
+ .forget = fuse_lib_forget,
+ .getattr = fuse_lib_getattr,
+ .setattr = fuse_lib_setattr,
+ .access = fuse_lib_access,
+ .readlink = fuse_lib_readlink,
+ .mknod = fuse_lib_mknod,
+ .mkdir = fuse_lib_mkdir,
+ .unlink = fuse_lib_unlink,
+ .rmdir = fuse_lib_rmdir,
+ .symlink = fuse_lib_symlink,
+ .rename = fuse_lib_rename,
+ .link = fuse_lib_link,
+ .create = fuse_lib_create,
+ .open = fuse_lib_open,
+ .read = fuse_lib_read,
+ .write = fuse_lib_write,
+ .flush = fuse_lib_flush,
+ .release = fuse_lib_release,
+ .fsync = fuse_lib_fsync,
+ .opendir = fuse_lib_opendir,
+ .readdir = fuse_lib_readdir,
+ .releasedir = fuse_lib_releasedir,
+ .fsyncdir = fuse_lib_fsyncdir,
+ .statfs = fuse_lib_statfs,
+ .setxattr = fuse_lib_setxattr,
+ .getxattr = fuse_lib_getxattr,
+ .listxattr = fuse_lib_listxattr,
+ .removexattr = fuse_lib_removexattr,
+ .getlk = fuse_lib_getlk,
+ .setlk = fuse_lib_setlk,
+ .bmap = fuse_lib_bmap,
};
static void free_cmd(struct fuse_cmd *cmd)
{
- free(cmd->buf);
- free(cmd);
+ free(cmd->buf);
+ free(cmd);
}
void fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd)
{
- fuse_session_process(f->se, cmd->buf, cmd->buflen, cmd->ch);
- free_cmd(cmd);
+ fuse_session_process(f->se, cmd->buf, cmd->buflen, cmd->ch);
+ free_cmd(cmd);
}
int fuse_exited(struct fuse *f)
{
- return fuse_session_exited(f->se);
+ return fuse_session_exited(f->se);
}
struct fuse_session *fuse_get_session(struct fuse *f)
{
- return f->se;
+ return f->se;
}
static struct fuse_cmd *fuse_alloc_cmd(size_t bufsize)
{
- struct fuse_cmd *cmd = (struct fuse_cmd *) malloc(sizeof(*cmd));
- if (cmd == NULL) {
- fprintf(stderr, "fuse: failed to allocate cmd\n");
- return NULL;
- }
- cmd->buf = (char *) malloc(bufsize);
- if (cmd->buf == NULL) {
- fprintf(stderr, "fuse: failed to allocate read buffer\n");
- free(cmd);
- return NULL;
- }
- return cmd;
+ struct fuse_cmd *cmd = (struct fuse_cmd *) malloc(sizeof(*cmd));
+ if (cmd == NULL) {
+ fprintf(stderr, "fuse: failed to allocate cmd\n");
+ return NULL;
+ }
+ cmd->buf = (char *) malloc(bufsize);
+ if (cmd->buf == NULL) {
+ fprintf(stderr, "fuse: failed to allocate read buffer\n");
+ free(cmd);
+ return NULL;
+ }
+ return cmd;
}
struct fuse_cmd *fuse_read_cmd(struct fuse *f)
{
- struct fuse_chan *ch = fuse_session_next_chan(f->se, NULL);
- size_t bufsize = fuse_chan_bufsize(ch);
- struct fuse_cmd *cmd = fuse_alloc_cmd(bufsize);
- if (cmd != NULL) {
- int res = fuse_chan_recv(&ch, cmd->buf, bufsize);
- if (res <= 0) {
- free_cmd(cmd);
- if (res < 0 && res != -EINTR && res != -EAGAIN)
- fuse_exit(f);
- return NULL;
- }
- cmd->buflen = res;
- cmd->ch = ch;
- }
- return cmd;
+ struct fuse_chan *ch = fuse_session_next_chan(f->se, NULL);
+ size_t bufsize = fuse_chan_bufsize(ch);
+ struct fuse_cmd *cmd = fuse_alloc_cmd(bufsize);
+ if (cmd != NULL) {
+ int res = fuse_chan_recv(&ch, cmd->buf, bufsize);
+ if (res <= 0) {
+ free_cmd(cmd);
+ if (res < 0 && res != -EINTR && res != -EAGAIN)
+ fuse_exit(f);
+ return NULL;
+ }
+ cmd->buflen = res;
+ cmd->ch = ch;
+ }
+ return cmd;
}
int fuse_loop(struct fuse *f)
{
- if (f)
- return fuse_session_loop(f->se);
- else
- return -1;
+ if (f)
+ return fuse_session_loop(f->se);
+ else
+ return -1;
}
int fuse_invalidate(struct fuse *f, const char *path)
{
- (void) f;
- (void) path;
- return -EINVAL;
+ (void) f;
+ (void) path;
+ return -EINVAL;
}
void fuse_exit(struct fuse *f)
{
- fuse_session_exit(f->se);
+ fuse_session_exit(f->se);
}
struct fuse_context *fuse_get_context(void)
{
- return &fuse_get_context_internal()->ctx;
+ return &fuse_get_context_internal()->ctx;
}
int fuse_interrupted(void)
{
- return fuse_req_interrupted(fuse_get_context_internal()->req);
+ return fuse_req_interrupted(fuse_get_context_internal()->req);
}
void fuse_set_getcontext_func(struct fuse_context *(*func)(void))
{
- (void) func;
- /* no-op */
+ (void) func;
+ /* no-op */
}
enum {
- KEY_HELP,
+ KEY_HELP,
};
#define FUSE_LIB_OPT(t, p, v) { t, offsetof(struct fuse_config, p), v }
static const struct fuse_opt fuse_lib_opts[] = {
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
- FUSE_LIB_OPT("debug", debug, 1),
- FUSE_LIB_OPT("-d", debug, 1),
- FUSE_LIB_OPT("hard_remove", hard_remove, 1),
- FUSE_LIB_OPT("use_ino", use_ino, 1),
- FUSE_LIB_OPT("readdir_ino", readdir_ino, 1),
- FUSE_LIB_OPT("direct_io", direct_io, 1),
- FUSE_LIB_OPT("kernel_cache", kernel_cache, 1),
- FUSE_LIB_OPT("auto_cache", auto_cache, 1),
- FUSE_LIB_OPT("noauto_cache", auto_cache, 0),
- FUSE_LIB_OPT("umask=", set_mode, 1),
- FUSE_LIB_OPT("umask=%o", umask, 0),
- FUSE_LIB_OPT("uid=", set_uid, 1),
- FUSE_LIB_OPT("uid=%d", uid, 0),
- FUSE_LIB_OPT("gid=", set_gid, 1),
- FUSE_LIB_OPT("gid=%d", gid, 0),
- FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout, 0),
- FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout, 0),
- FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout, 0),
- FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set, 1),
- FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout, 0),
- FUSE_LIB_OPT("intr", intr, 1),
- FUSE_LIB_OPT("intr_signal=%d", intr_signal, 0),
- FUSE_LIB_OPT("modules=%s", modules, 0),
- FUSE_OPT_END
+ FUSE_OPT_KEY("-h", KEY_HELP),
+ FUSE_OPT_KEY("--help", KEY_HELP),
+ FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
+ FUSE_LIB_OPT("debug", debug, 1),
+ FUSE_LIB_OPT("-d", debug, 1),
+ FUSE_LIB_OPT("hard_remove", hard_remove, 1),
+ FUSE_LIB_OPT("use_ino", use_ino, 1),
+ FUSE_LIB_OPT("readdir_ino", readdir_ino, 1),
+ FUSE_LIB_OPT("direct_io", direct_io, 1),
+ FUSE_LIB_OPT("kernel_cache", kernel_cache, 1),
+ FUSE_LIB_OPT("auto_cache", auto_cache, 1),
+ FUSE_LIB_OPT("noauto_cache", auto_cache, 0),
+ FUSE_LIB_OPT("umask=", set_mode, 1),
+ FUSE_LIB_OPT("umask=%o", umask, 0),
+ FUSE_LIB_OPT("uid=", set_uid, 1),
+ FUSE_LIB_OPT("uid=%d", uid, 0),
+ FUSE_LIB_OPT("gid=", set_gid, 1),
+ FUSE_LIB_OPT("gid=%d", gid, 0),
+ FUSE_LIB_OPT("entry_timeout=%lf", entry_timeout, 0),
+ FUSE_LIB_OPT("attr_timeout=%lf", attr_timeout, 0),
+ FUSE_LIB_OPT("ac_attr_timeout=%lf", ac_attr_timeout, 0),
+ FUSE_LIB_OPT("ac_attr_timeout=", ac_attr_timeout_set, 1),
+ FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout, 0),
+ FUSE_LIB_OPT("intr", intr, 1),
+ FUSE_LIB_OPT("intr_signal=%d", intr_signal, 0),
+ FUSE_LIB_OPT("modules=%s", modules, 0),
+ FUSE_OPT_END
};
static void fuse_lib_help(void)
{
- fprintf(stderr,
-" -o hard_remove immediate removal (don't hide files)\n"
-" -o use_ino let filesystem set inode numbers\n"
-" -o readdir_ino try to fill in d_ino in readdir\n"
-" -o direct_io use direct I/O\n"
-" -o kernel_cache cache files in kernel\n"
-" -o [no]auto_cache enable caching based on modification times\n"
-" -o umask=M set file permissions (octal)\n"
-" -o uid=N set file owner\n"
-" -o gid=N set file group\n"
-" -o entry_timeout=T cache timeout for names (1.0s)\n"
+ fprintf(stderr,
+" -o hard_remove immediate removal (don't hide files)\n"
+" -o use_ino let filesystem set inode numbers\n"
+" -o readdir_ino try to fill in d_ino in readdir\n"
+" -o direct_io use direct I/O\n"
+" -o kernel_cache cache files in kernel\n"
+" -o [no]auto_cache enable caching based on modification times\n"
+" -o umask=M set file permissions (octal)\n"
+" -o uid=N set file owner\n"
+" -o gid=N set file group\n"
+" -o entry_timeout=T cache timeout for names (1.0s)\n"
" -o negative_timeout=T cache timeout for deleted names (0.0s)\n"
-" -o attr_timeout=T cache timeout for attributes (1.0s)\n"
+" -o attr_timeout=T cache timeout for attributes (1.0s)\n"
" -o ac_attr_timeout=T auto cache timeout for attributes (attr_timeout)\n"
-" -o intr allow requests to be interrupted\n"
-" -o intr_signal=NUM signal to send on interrupt (%i)\n"
+" -o intr allow requests to be interrupted\n"
+" -o intr_signal=NUM signal to send on interrupt (%i)\n"
" -o modules=M1[:M2...] names of modules to push onto filesystem stack\n"
"\n", FUSE_DEFAULT_INTR_SIGNAL);
}
static void fuse_lib_help_modules(void)
{
- struct fuse_module *m;
- fprintf(stderr, "\nModule options:\n");
- pthread_mutex_lock(&fuse_context_lock);
- for (m = fuse_modules; m; m = m->next) {
- struct fuse_fs *fs = NULL;
- struct fuse_fs *newfs;
- struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
- if (fuse_opt_add_arg(&args, "") != -1 &&
- fuse_opt_add_arg(&args, "-h") != -1) {
- fprintf(stderr, "\n[%s]\n", m->name);
- newfs = m->factory(&args, &fs);
- assert(newfs == NULL);
- }
- fuse_opt_free_args(&args);
- }
- pthread_mutex_unlock(&fuse_context_lock);
+ struct fuse_module *m;
+ fprintf(stderr, "\nModule options:\n");
+ pthread_mutex_lock(&fuse_context_lock);
+ for (m = fuse_modules; m; m = m->next) {
+ struct fuse_fs *fs = NULL;
+ struct fuse_fs *newfs;
+ struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
+ if (fuse_opt_add_arg(&args, "") != -1 &&
+ fuse_opt_add_arg(&args, "-h") != -1) {
+ fprintf(stderr, "\n[%s]\n", m->name);
+ newfs = m->factory(&args, &fs);
+ assert(newfs == NULL);
+ }
+ fuse_opt_free_args(&args);
+ }
+ pthread_mutex_unlock(&fuse_context_lock);
}
static int fuse_lib_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- (void) arg; (void) outargs;
+ (void) arg; (void) outargs;
- if (key == KEY_HELP) {
- struct fuse_config *conf = (struct fuse_config *) data;
- fuse_lib_help();
- conf->help = 1;
- }
+ if (key == KEY_HELP) {
+ struct fuse_config *conf = (struct fuse_config *) data;
+ fuse_lib_help();
+ conf->help = 1;
+ }
- return 1;
+ return 1;
}
int fuse_is_lib_option(const char *opt)
{
- return fuse_lowlevel_is_lib_option(opt) ||
- fuse_opt_match(fuse_lib_opts, opt);
+ return fuse_lowlevel_is_lib_option(opt) ||
+ fuse_opt_match(fuse_lib_opts, opt);
}
static int fuse_init_intr_signal(int signum, int *installed)
{
- struct sigaction old_sa;
+ struct sigaction old_sa;
- if (sigaction(signum, NULL, &old_sa) == -1) {
- perror("fuse: cannot get old signal handler");
- return -1;
- }
+ if (sigaction(signum, NULL, &old_sa) == -1) {
+ perror("fuse: cannot get old signal handler");
+ return -1;
+ }
- if (old_sa.sa_handler == SIG_DFL) {
- struct sigaction sa;
+ if (old_sa.sa_handler == SIG_DFL) {
+ struct sigaction sa;
- memset(&sa, 0, sizeof(struct sigaction));
- sa.sa_handler = fuse_intr_sighandler;
- sigemptyset(&sa.sa_mask);
+ memset(&sa, 0, sizeof(struct sigaction));
+ sa.sa_handler = fuse_intr_sighandler;
+ sigemptyset(&sa.sa_mask);
- if (sigaction(signum, &sa, NULL) == -1) {
- perror("fuse: cannot set interrupt signal handler");
- return -1;
- }
- *installed = 1;
- }
- return 0;
+ if (sigaction(signum, &sa, NULL) == -1) {
+ perror("fuse: cannot set interrupt signal handler");
+ return -1;
+ }
+ *installed = 1;
+ }
+ return 0;
}
static void fuse_restore_intr_signal(int signum)
{
- struct sigaction sa;
+ struct sigaction sa;
- memset(&sa, 0, sizeof(struct sigaction));
- sa.sa_handler = SIG_DFL;
- sigaction(signum, &sa, NULL);
+ memset(&sa, 0, sizeof(struct sigaction));
+ sa.sa_handler = SIG_DFL;
+ sigaction(signum, &sa, NULL);
}
static int fuse_push_module(struct fuse *f, const char *module,
- struct fuse_args *args)
+ struct fuse_args *args)
{
- struct fuse_fs *fs[2] = { f->fs, NULL };
- struct fuse_fs *newfs;
- struct fuse_module *m = fuse_get_module(module);
+ struct fuse_fs *fs[2] = { f->fs, NULL };
+ struct fuse_fs *newfs;
+ struct fuse_module *m = fuse_get_module(module);
- if (!m)
- return -1;
+ if (!m)
+ return -1;
- newfs = m->factory(args, fs);
- if (!newfs) {
- fuse_put_module(m);
- return -1;
- }
- newfs->m = m;
- f->fs = newfs;
- return 0;
+ newfs = m->factory(args, fs);
+ if (!newfs) {
+ fuse_put_module(m);
+ return -1;
+ }
+ newfs->m = m;
+ f->fs = newfs;
+ return 0;
}
struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
- void *user_data)
+ void *user_data)
{
- struct fuse_fs *fs;
+ struct fuse_fs *fs;
- if (sizeof(struct fuse_operations) < op_size) {
- fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n");
- op_size = sizeof(struct fuse_operations);
- }
+ if (sizeof(struct fuse_operations) < op_size) {
+ fprintf(stderr, "fuse: warning: library too old, some operations may not not work\n");
+ op_size = sizeof(struct fuse_operations);
+ }
- fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs));
- if (!fs) {
- fprintf(stderr, "fuse: failed to allocate fuse_fs object\n");
- return NULL;
- }
+ fs = (struct fuse_fs *) calloc(1, sizeof(struct fuse_fs));
+ if (!fs) {
+ fprintf(stderr, "fuse: failed to allocate fuse_fs object\n");
+ return NULL;
+ }
- fs->user_data = user_data;
- if (op)
- memcpy(&fs->op, op, op_size);
- return fs;
+ fs->user_data = user_data;
+ if (op)
+ memcpy(&fs->op, op, op_size);
+ return fs;
}
struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
- const struct fuse_operations *op,
- size_t op_size, void *user_data, int compat)
-{
- struct fuse *f;
- struct node *root;
- struct fuse_fs *fs;
- struct fuse_lowlevel_ops llop = fuse_path_ops;
-
- if (fuse_create_context_key() == -1)
- goto out;
-
- f = (struct fuse *) calloc(1, sizeof(struct fuse));
- if (f == NULL) {
- fprintf(stderr, "fuse: failed to allocate fuse object\n");
- goto out_delete_context_key;
- }
-
- fs = fuse_fs_new(op, op_size, user_data);
- if (!fs)
- goto out_free;
-
- fs->compat = compat;
- f->fs = fs;
-
- /* Oh f**k, this is ugly! */
- if (!fs->op.lock) {
- llop.getlk = NULL;
- llop.setlk = NULL;
- }
-
- f->conf.entry_timeout = 1.0;
- f->conf.attr_timeout = 1.0;
- f->conf.negative_timeout = 0.0;
- f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
-
- if (fuse_opt_parse(args, &f->conf, fuse_lib_opts, fuse_lib_opt_proc) == -1)
- goto out_free_fs;
-
- if (f->conf.modules) {
- char *module;
- char *next;
-
- for (module = f->conf.modules; module; module = next) {
- char *p;
- for (p = module; *p && *p != ':'; p++);
- next = *p ? p + 1 : NULL;
- *p = '\0';
- if (module[0] && fuse_push_module(f, module, args) == -1)
- goto out_free_fs;
- }
- }
-
- if (!f->conf.ac_attr_timeout_set)
- f->conf.ac_attr_timeout = f->conf.attr_timeout;
+ const struct fuse_operations *op,
+ size_t op_size, void *user_data, int compat)
+{
+ struct fuse *f;
+ struct node *root;
+ struct fuse_fs *fs;
+ struct fuse_lowlevel_ops llop = fuse_path_ops;
+
+ if (fuse_create_context_key() == -1)
+ goto out;
+
+ f = (struct fuse *) calloc(1, sizeof(struct fuse));
+ if (f == NULL) {
+ fprintf(stderr, "fuse: failed to allocate fuse object\n");
+ goto out_delete_context_key;
+ }
+
+ fs = fuse_fs_new(op, op_size, user_data);
+ if (!fs)
+ goto out_free;
+
+ fs->compat = compat;
+ f->fs = fs;
+
+ /* Oh f**k, this is ugly! */
+ if (!fs->op.lock) {
+ llop.getlk = NULL;
+ llop.setlk = NULL;
+ }
+
+ f->conf.entry_timeout = 1.0;
+ f->conf.attr_timeout = 1.0;
+ f->conf.negative_timeout = 0.0;
+ f->conf.intr_signal = FUSE_DEFAULT_INTR_SIGNAL;
+
+ if (fuse_opt_parse(args, &f->conf, fuse_lib_opts,
+ fuse_lib_opt_proc) == -1)
+ goto out_free_fs;
+
+ if (f->conf.modules) {
+ char *module;
+ char *next;
+
+ for (module = f->conf.modules; module; module = next) {
+ char *p;
+ for (p = module; *p && *p != ':'; p++);
+ next = *p ? p + 1 : NULL;
+ *p = '\0';
+ if (module[0] &&
+ fuse_push_module(f, module, args) == -1)
+ goto out_free_fs;
+ }
+ }
+
+ if (!f->conf.ac_attr_timeout_set)
+ f->conf.ac_attr_timeout = f->conf.attr_timeout;
#ifdef __FreeBSD__
- /*
- * In FreeBSD, we always use these settings as inode numbers are needed to
- * make getcwd(3) work.
- */
- f->conf.readdir_ino = 1;
+ /*
+ * In FreeBSD, we always use these settings as inode numbers
+ * are needed to make getcwd(3) work.
+ */
+ f->conf.readdir_ino = 1;
#endif
- if (compat && compat <= 25) {
- if (fuse_sync_compat_args(args) == -1)
- goto out_free_fs;
- }
-
- f->se = fuse_lowlevel_new_common(args, &llop, sizeof(llop), f);
- if (f->se == NULL) {
- if (f->conf.help)
- fuse_lib_help_modules();
- goto out_free_fs;
- }
-
- fuse_session_add_chan(f->se, ch);
-
- f->ctr = 0;
- f->generation = 0;
- /* FIXME: Dynamic hash table */
- f->name_table_size = 14057;
- f->name_table = (struct node **)
- calloc(1, sizeof(struct node *) * f->name_table_size);
- if (f->name_table == NULL) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- goto out_free_session;
- }
-
- f->id_table_size = 14057;
- f->id_table = (struct node **)
- calloc(1, sizeof(struct node *) * f->id_table_size);
- if (f->id_table == NULL) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- goto out_free_name_table;
- }
-
- fuse_mutex_init(&f->lock);
- pthread_rwlock_init(&f->tree_lock, NULL);
-
- root = (struct node *) calloc(1, sizeof(struct node));
- if (root == NULL) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- goto out_free_id_table;
- }
-
- root->name = strdup("/");
- if (root->name == NULL) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- goto out_free_root;
- }
-
- if (f->conf.intr &&
- fuse_init_intr_signal(f->conf.intr_signal, &f->intr_installed) == -1)
- goto out_free_root_name;
-
- root->parent = NULL;
- root->nodeid = FUSE_ROOT_ID;
- root->generation = 0;
- root->refctr = 1;
- root->nlookup = 1;
- hash_id(f, root);
-
- return f;
-
- out_free_root_name:
- free(root->name);
- out_free_root:
- free(root);
- out_free_id_table:
- free(f->id_table);
- out_free_name_table:
- free(f->name_table);
- out_free_session:
- fuse_session_destroy(f->se);
- out_free_fs:
- /* Horrible compatibility hack to stop the destructor from being
- called on the filesystem without init being called first */
- fs->op.destroy = NULL;
- fuse_fs_destroy(f->fs);
- free(f->conf.modules);
- out_free:
- free(f);
- out_delete_context_key:
- fuse_delete_context_key();
- out:
- return NULL;
+ if (compat && compat <= 25) {
+ if (fuse_sync_compat_args(args) == -1)
+ goto out_free_fs;
+ }
+
+ f->se = fuse_lowlevel_new_common(args, &llop, sizeof(llop), f);
+ if (f->se == NULL) {
+ if (f->conf.help)
+ fuse_lib_help_modules();
+ goto out_free_fs;
+ }
+
+ fuse_session_add_chan(f->se, ch);
+
+ f->ctr = 0;
+ f->generation = 0;
+ /* FIXME: Dynamic hash table */
+ f->name_table_size = 14057;
+ f->name_table = (struct node **)
+ calloc(1, sizeof(struct node *) * f->name_table_size);
+ if (f->name_table == NULL) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ goto out_free_session;
+ }
+
+ f->id_table_size = 14057;
+ f->id_table = (struct node **)
+ calloc(1, sizeof(struct node *) * f->id_table_size);
+ if (f->id_table == NULL) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ goto out_free_name_table;
+ }
+
+ fuse_mutex_init(&f->lock);
+ pthread_rwlock_init(&f->tree_lock, NULL);
+
+ root = (struct node *) calloc(1, sizeof(struct node));
+ if (root == NULL) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ goto out_free_id_table;
+ }
+
+ root->name = strdup("/");
+ if (root->name == NULL) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ goto out_free_root;
+ }
+
+ if (f->conf.intr &&
+ fuse_init_intr_signal(f->conf.intr_signal,
+ &f->intr_installed) == -1)
+ goto out_free_root_name;
+
+ root->parent = NULL;
+ root->nodeid = FUSE_ROOT_ID;
+ root->generation = 0;
+ root->refctr = 1;
+ root->nlookup = 1;
+ hash_id(f, root);
+
+ return f;
+
+out_free_root_name:
+ free(root->name);
+out_free_root:
+ free(root);
+out_free_id_table:
+ free(f->id_table);
+out_free_name_table:
+ free(f->name_table);
+out_free_session:
+ fuse_session_destroy(f->se);
+out_free_fs:
+ /* Horrible compatibility hack to stop the destructor from being
+ called on the filesystem without init being called first */
+ fs->op.destroy = NULL;
+ fuse_fs_destroy(f->fs);
+ free(f->conf.modules);
+out_free:
+ free(f);
+out_delete_context_key:
+ fuse_delete_context_key();
+out:
+ return NULL;
}
struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
- const struct fuse_operations *op, size_t op_size,
- void *user_data)
+ const struct fuse_operations *op, size_t op_size,
+ void *user_data)
{
- return fuse_new_common(ch, args, op, op_size, user_data, 0);
+ return fuse_new_common(ch, args, op, op_size, user_data, 0);
}
void fuse_destroy(struct fuse *f)
{
- size_t i;
-
- if (f->conf.intr && f->intr_installed)
- fuse_restore_intr_signal(f->conf.intr_signal);
-
- if (f->fs) {
- struct fuse_context_i *c = fuse_get_context_internal();
-
- memset(c, 0, sizeof(*c));
- c->ctx.fuse = f;
-
- for (i = 0; i < f->id_table_size; i++) {
- struct node *node;
-
- for (node = f->id_table[i]; node != NULL; node = node->id_next) {
- if (node->is_hidden) {
- char *path = get_path(f, node->nodeid);
- if (path) {
- fuse_fs_unlink(f->fs, path);
- free(path);
- }
- }
- }
- }
- }
- for (i = 0; i < f->id_table_size; i++) {
- struct node *node;
- struct node *next;
-
- for (node = f->id_table[i]; node != NULL; node = next) {
- next = node->id_next;
- free_node(node);
- }
- }
- free(f->id_table);
- free(f->name_table);
- pthread_mutex_destroy(&f->lock);
- pthread_rwlock_destroy(&f->tree_lock);
- fuse_session_destroy(f->se);
- free(f->conf.modules);
- free(f);
- fuse_delete_context_key();
+ size_t i;
+
+ if (f->conf.intr && f->intr_installed)
+ fuse_restore_intr_signal(f->conf.intr_signal);
+
+ if (f->fs) {
+ struct fuse_context_i *c = fuse_get_context_internal();
+
+ memset(c, 0, sizeof(*c));
+ c->ctx.fuse = f;
+
+ for (i = 0; i < f->id_table_size; i++) {
+ struct node *node;
+
+ for (node = f->id_table[i]; node != NULL;
+ node = node->id_next) {
+ if (node->is_hidden) {
+ char *path = get_path(f, node->nodeid);
+ if (path) {
+ fuse_fs_unlink(f->fs, path);
+ free(path);
+ }
+ }
+ }
+ }
+ }
+ for (i = 0; i < f->id_table_size; i++) {
+ struct node *node;
+ struct node *next;
+
+ for (node = f->id_table[i]; node != NULL; node = next) {
+ next = node->id_next;
+ free_node(node);
+ }
+ }
+ free(f->id_table);
+ free(f->name_table);
+ pthread_mutex_destroy(&f->lock);
+ pthread_rwlock_destroy(&f->tree_lock);
+ fuse_session_destroy(f->se);
+ free(f->conf.modules);
+ free(f);
+ fuse_delete_context_key();
}
static struct fuse *fuse_new_common_compat25(int fd, struct fuse_args *args,
- const struct fuse_operations *op,
- size_t op_size, int compat)
+ const struct fuse_operations *op,
+ size_t op_size, int compat)
{
- struct fuse *f = NULL;
- struct fuse_chan *ch = fuse_kern_chan_new(fd);
+ struct fuse *f = NULL;
+ struct fuse_chan *ch = fuse_kern_chan_new(fd);
- if (ch)
- f = fuse_new_common(ch, args, op, op_size, NULL, compat);
+ if (ch)
+ f = fuse_new_common(ch, args, op, op_size, NULL, compat);
- return f;
+ return f;
}
/* called with fuse_context_lock held or during initialization (before
main() has been called) */
void fuse_register_module(struct fuse_module *mod)
{
- mod->ctr = 0;
- mod->so = fuse_current_so;
- if (mod->so)
- mod->so->ctr++;
- mod->next = fuse_modules;
- fuse_modules = mod;
+ mod->ctr = 0;
+ mod->so = fuse_current_so;
+ if (mod->so)
+ mod->so->ctr++;
+ mod->next = fuse_modules;
+ fuse_modules = mod;
}
#ifndef __FreeBSD__
static struct fuse *fuse_new_common_compat(int fd, const char *opts,
- const struct fuse_operations *op,
- size_t op_size, int compat)
+ const struct fuse_operations *op,
+ size_t op_size, int compat)
{
- struct fuse *f;
- struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
+ struct fuse *f;
+ struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
- if (fuse_opt_add_arg(&args, "") == -1)
- return NULL;
- if (opts &&
- (fuse_opt_add_arg(&args, "-o") == -1 ||
- fuse_opt_add_arg(&args, opts) == -1)) {
- fuse_opt_free_args(&args);
- return NULL;
- }
- f = fuse_new_common_compat25(fd, &args, op, op_size, compat);
- fuse_opt_free_args(&args);
+ if (fuse_opt_add_arg(&args, "") == -1)
+ return NULL;
+ if (opts &&
+ (fuse_opt_add_arg(&args, "-o") == -1 ||
+ fuse_opt_add_arg(&args, opts) == -1)) {
+ fuse_opt_free_args(&args);
+ return NULL;
+ }
+ f = fuse_new_common_compat25(fd, &args, op, op_size, compat);
+ fuse_opt_free_args(&args);
- return f;
+ return f;
}
struct fuse *fuse_new_compat22(int fd, const char *opts,
- const struct fuse_operations_compat22 *op,
- size_t op_size)
+ const struct fuse_operations_compat22 *op,
+ size_t op_size)
{
- return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
- op_size, 22);
+ return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
+ op_size, 22);
}
struct fuse *fuse_new_compat2(int fd, const char *opts,
- const struct fuse_operations_compat2 *op)
+ const struct fuse_operations_compat2 *op)
{
- return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat2), 21);
+ return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
+ sizeof(struct fuse_operations_compat2),
+ 21);
}
struct fuse *fuse_new_compat1(int fd, int flags,
- const struct fuse_operations_compat1 *op)
+ const struct fuse_operations_compat1 *op)
{
- const char *opts = NULL;
- if (flags & FUSE_DEBUG_COMPAT1)
- opts = "debug";
- return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat1), 11);
+ const char *opts = NULL;
+ if (flags & FUSE_DEBUG_COMPAT1)
+ opts = "debug";
+ return fuse_new_common_compat(fd, opts, (struct fuse_operations *) op,
+ sizeof(struct fuse_operations_compat1),
+ 11);
}
FUSE_SYMVER(".symver fuse_exited,__fuse_exited@");
@@ -3300,11 +3339,11 @@ FUSE_SYMVER(".symver fuse_new_compat22,fuse_new@FUSE_2.2");
#endif /* __FreeBSD__ */
struct fuse *fuse_new_compat25(int fd, struct fuse_args *args,
- const struct fuse_operations_compat25 *op,
- size_t op_size)
+ const struct fuse_operations_compat25 *op,
+ size_t op_size)
{
- return fuse_new_common_compat25(fd, args, (struct fuse_operations *) op,
- op_size, 25);
+ return fuse_new_common_compat25(fd, args, (struct fuse_operations *) op,
+ op_size, 25);
}
FUSE_SYMVER(".symver fuse_new_compat25,fuse_new@FUSE_2.5");
diff --git a/lib/fuse_i.h b/lib/fuse_i.h
index 55ce048..ec6e5d6 100644
--- a/lib/fuse_i.h
+++ b/lib/fuse_i.h
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse.h"
@@ -14,22 +14,22 @@ struct fuse_lowlevel_ops;
struct fuse_req;
struct fuse_cmd {
- char *buf;
- size_t buflen;
- struct fuse_chan *ch;
+ char *buf;
+ size_t buflen;
+ struct fuse_chan *ch;
};
struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
- const struct fuse_operations *op,
- size_t op_size, void *user_data, int compat);
+ const struct fuse_operations *op,
+ size_t op_size, void *user_data, int compat);
int fuse_sync_compat_args(struct fuse_args *args);
struct fuse_chan *fuse_kern_chan_new(int fd);
struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args,
- const struct fuse_lowlevel_ops *op,
- size_t op_size, void *userdata);
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size, void *userdata);
void fuse_kern_unmount_compat22(const char *mountpoint);
void fuse_kern_unmount(const char *mountpoint, int fd);
diff --git a/lib/fuse_kern_chan.c b/lib/fuse_kern_chan.c
index 49e88b7..03291c3 100644
--- a/lib/fuse_kern_chan.c
+++ b/lib/fuse_kern_chan.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse_lowlevel.h"
@@ -16,80 +16,80 @@
#include <assert.h>
static int fuse_kern_chan_receive(struct fuse_chan **chp, char *buf,
- size_t size)
+ size_t size)
{
- struct fuse_chan *ch = *chp;
- int err;
- ssize_t res;
- struct fuse_session *se = fuse_chan_session(ch);
- assert(se != NULL);
+ struct fuse_chan *ch = *chp;
+ int err;
+ ssize_t res;
+ struct fuse_session *se = fuse_chan_session(ch);
+ assert(se != NULL);
- restart:
- res = read(fuse_chan_fd(ch), buf, size);
- err = errno;
+restart:
+ res = read(fuse_chan_fd(ch), buf, size);
+ err = errno;
- if (fuse_session_exited(se))
- return 0;
- if (res == -1) {
- /* ENOENT means the operation was interrupted, it's safe
- to restart */
- if (err == ENOENT)
- goto restart;
+ if (fuse_session_exited(se))
+ return 0;
+ if (res == -1) {
+ /* ENOENT means the operation was interrupted, it's safe
+ to restart */
+ if (err == ENOENT)
+ goto restart;
- if (err == ENODEV) {
- fuse_session_exit(se);
- return 0;
- }
- /* Errors occuring during normal operation: EINTR (read
- interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem
- umounted) */
- if (err != EINTR && err != EAGAIN)
- perror("fuse: reading device");
- return -err;
- }
- if ((size_t) res < sizeof(struct fuse_in_header)) {
- fprintf(stderr, "short read on fuse device\n");
- return -EIO;
- }
- return res;
+ if (err == ENODEV) {
+ fuse_session_exit(se);
+ return 0;
+ }
+ /* Errors occuring during normal operation: EINTR (read
+ interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem
+ umounted) */
+ if (err != EINTR && err != EAGAIN)
+ perror("fuse: reading device");
+ return -err;
+ }
+ if ((size_t) res < sizeof(struct fuse_in_header)) {
+ fprintf(stderr, "short read on fuse device\n");
+ return -EIO;
+ }
+ return res;
}
static int fuse_kern_chan_send(struct fuse_chan *ch, const struct iovec iov[],
- size_t count)
+ size_t count)
{
- if (iov) {
- ssize_t res = writev(fuse_chan_fd(ch), iov, count);
- int err = errno;
+ if (iov) {
+ ssize_t res = writev(fuse_chan_fd(ch), iov, count);
+ int err = errno;
- if (res == -1) {
- struct fuse_session *se = fuse_chan_session(ch);
+ if (res == -1) {
+ struct fuse_session *se = fuse_chan_session(ch);
- assert(se != NULL);
+ assert(se != NULL);
- /* ENOENT means the operation was interrupted */
- if (!fuse_session_exited(se) && err != ENOENT)
- perror("fuse: writing device");
- return -err;
- }
- }
- return 0;
+ /* ENOENT means the operation was interrupted */
+ if (!fuse_session_exited(se) && err != ENOENT)
+ perror("fuse: writing device");
+ return -err;
+ }
+ }
+ return 0;
}
static void fuse_kern_chan_destroy(struct fuse_chan *ch)
{
- close(fuse_chan_fd(ch));
+ close(fuse_chan_fd(ch));
}
#define MIN_BUFSIZE 0x21000
struct fuse_chan *fuse_kern_chan_new(int fd)
{
- struct fuse_chan_ops op = {
- .receive = fuse_kern_chan_receive,
- .send = fuse_kern_chan_send,
- .destroy = fuse_kern_chan_destroy,
- };
- size_t bufsize = getpagesize() + 0x1000;
- bufsize = bufsize < MIN_BUFSIZE ? MIN_BUFSIZE : bufsize;
- return fuse_chan_new(&op, fd, bufsize, NULL);
+ struct fuse_chan_ops op = {
+ .receive = fuse_kern_chan_receive,
+ .send = fuse_kern_chan_send,
+ .destroy = fuse_kern_chan_destroy,
+ };
+ size_t bufsize = getpagesize() + 0x1000;
+ bufsize = bufsize < MIN_BUFSIZE ? MIN_BUFSIZE : bufsize;
+ return fuse_chan_new(&op, fd, bufsize, NULL);
}
diff --git a/lib/fuse_loop.c b/lib/fuse_loop.c
index f7c17fa..104c5d4 100644
--- a/lib/fuse_loop.c
+++ b/lib/fuse_loop.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse_lowlevel.h"
@@ -14,26 +14,26 @@
int fuse_session_loop(struct fuse_session *se)
{
- int res = 0;
- struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
- size_t bufsize = fuse_chan_bufsize(ch);
- char *buf = (char *) malloc(bufsize);
- if (!buf) {
- fprintf(stderr, "fuse: failed to allocate read buffer\n");
- return -1;
- }
+ int res = 0;
+ struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
+ size_t bufsize = fuse_chan_bufsize(ch);
+ char *buf = (char *) malloc(bufsize);
+ if (!buf) {
+ fprintf(stderr, "fuse: failed to allocate read buffer\n");
+ return -1;
+ }
- while (!fuse_session_exited(se)) {
- struct fuse_chan *tmpch = ch;
- res = fuse_chan_recv(&tmpch, buf, bufsize);
- if (res == -EINTR)
- continue;
- if (res <= 0)
- break;
- fuse_session_process(se, buf, res, tmpch);
- }
+ while (!fuse_session_exited(se)) {
+ struct fuse_chan *tmpch = ch;
+ res = fuse_chan_recv(&tmpch, buf, bufsize);
+ if (res == -EINTR)
+ continue;
+ if (res <= 0)
+ break;
+ fuse_session_process(se, buf, res, tmpch);
+ }
- free(buf);
- fuse_session_reset(se);
- return res < 0 ? -1 : 0;
+ free(buf);
+ fuse_session_reset(se);
+ return res < 0 ? -1 : 0;
}
diff --git a/lib/fuse_loop_mt.c b/lib/fuse_loop_mt.c
index 533d9c3..dba8dbc 100644
--- a/lib/fuse_loop_mt.c
+++ b/lib/fuse_loop_mt.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "fuse_lowlevel.h"
@@ -20,202 +20,203 @@
#include <sys/time.h>
struct fuse_worker {
- struct fuse_worker *prev;
- struct fuse_worker *next;
- pthread_t thread_id;
- size_t bufsize;
- char *buf;
- struct fuse_mt *mt;
+ struct fuse_worker *prev;
+ struct fuse_worker *next;
+ pthread_t thread_id;
+ size_t bufsize;
+ char *buf;
+ struct fuse_mt *mt;
};
struct fuse_mt {
- pthread_mutex_t lock;
- int numworker;
- int numavail;
- struct fuse_session *se;
- struct fuse_chan *prevch;
- struct fuse_worker main;
- sem_t finish;
- int exit;
- int error;
+ pthread_mutex_t lock;
+ int numworker;
+ int numavail;
+ struct fuse_session *se;
+ struct fuse_chan *prevch;
+ struct fuse_worker main;
+ sem_t finish;
+ int exit;
+ int error;
};
static void list_add_worker(struct fuse_worker *w, struct fuse_worker *next)
{
- struct fuse_worker *prev = next->prev;
- w->next = next;
- w->prev = prev;
- prev->next = w;
- next->prev = w;
+ struct fuse_worker *prev = next->prev;
+ w->next = next;
+ w->prev = prev;
+ prev->next = w;
+ next->prev = w;
}
static void list_del_worker(struct fuse_worker *w)
{
- struct fuse_worker *prev = w->prev;
- struct fuse_worker *next = w->next;
- prev->next = next;
- next->prev = prev;
+ struct fuse_worker *prev = w->prev;
+ struct fuse_worker *next = w->next;
+ prev->next = next;
+ next->prev = prev;
}
static int fuse_start_thread(struct fuse_mt *mt);
static void *fuse_do_work(void *data)
{
- struct fuse_worker *w = (struct fuse_worker *) data;
- struct fuse_mt *mt = w->mt;
-
- while (!fuse_session_exited(mt->se)) {
- int isforget = 0;
- struct fuse_chan *ch = mt->prevch;
- int res = fuse_chan_recv(&ch, w->buf, w->bufsize);
- if (res == -EINTR)
- continue;
- if (res <= 0) {
- if (res < 0) {
- fuse_session_exit(mt->se);
- mt->error = -1;
- }
- break;
- }
-
- pthread_mutex_lock(&mt->lock);
- if (mt->exit) {
- pthread_mutex_unlock(&mt->lock);
- return NULL;
- }
-
- /*
- * This disgusting hack is needed so that zillions of threads
- * are not created on a burst of FORGET messages
- */
- if (((struct fuse_in_header *) w->buf)->opcode == FUSE_FORGET)
- isforget = 1;
-
- if (!isforget)
- mt->numavail--;
- if (mt->numavail == 0)
- fuse_start_thread(mt);
- pthread_mutex_unlock(&mt->lock);
-
- fuse_session_process(mt->se, w->buf, res, ch);
-
- pthread_mutex_lock(&mt->lock);
- if (!isforget)
- mt->numavail++;
- if (mt->numavail > 10) {
- if (mt->exit) {
- pthread_mutex_unlock(&mt->lock);
- return NULL;
- }
- list_del_worker(w);
- mt->numavail--;
- mt->numworker--;
- pthread_mutex_unlock(&mt->lock);
-
- pthread_detach(w->thread_id);
- free(w->buf);
- free(w);
- return NULL;
- }
- pthread_mutex_unlock(&mt->lock);
- }
-
- sem_post(&mt->finish);
- pause();
-
- return NULL;
+ struct fuse_worker *w = (struct fuse_worker *) data;
+ struct fuse_mt *mt = w->mt;
+
+ while (!fuse_session_exited(mt->se)) {
+ int isforget = 0;
+ struct fuse_chan *ch = mt->prevch;
+ int res = fuse_chan_recv(&ch, w->buf, w->bufsize);
+ if (res == -EINTR)
+ continue;
+ if (res <= 0) {
+ if (res < 0) {
+ fuse_session_exit(mt->se);
+ mt->error = -1;
+ }
+ break;
+ }
+
+ pthread_mutex_lock(&mt->lock);
+ if (mt->exit) {
+ pthread_mutex_unlock(&mt->lock);
+ return NULL;
+ }
+
+ /*
+ * This disgusting hack is needed so that zillions of threads
+ * are not created on a burst of FORGET messages
+ */
+ if (((struct fuse_in_header *) w->buf)->opcode == FUSE_FORGET)
+ isforget = 1;
+
+ if (!isforget)
+ mt->numavail--;
+ if (mt->numavail == 0)
+ fuse_start_thread(mt);
+ pthread_mutex_unlock(&mt->lock);
+
+ fuse_session_process(mt->se, w->buf, res, ch);
+
+ pthread_mutex_lock(&mt->lock);
+ if (!isforget)
+ mt->numavail++;
+ if (mt->numavail > 10) {
+ if (mt->exit) {
+ pthread_mutex_unlock(&mt->lock);
+ return NULL;
+ }
+ list_del_worker(w);
+ mt->numavail--;
+ mt->numworker--;
+ pthread_mutex_unlock(&mt->lock);
+
+ pthread_detach(w->thread_id);
+ free(w->buf);
+ free(w);
+ return NULL;
+ }
+ pthread_mutex_unlock(&mt->lock);
+ }
+
+ sem_post(&mt->finish);
+ pause();
+
+ return NULL;
}
static int fuse_start_thread(struct fuse_mt *mt)
{
- sigset_t oldset;
- sigset_t newset;
- int res;
- struct fuse_worker *w = malloc(sizeof(struct fuse_worker));
- if (!w) {
- fprintf(stderr, "fuse: failed to allocate worker structure\n");
- return -1;
- }
- memset(w, 0, sizeof(struct fuse_worker));
- w->bufsize = fuse_chan_bufsize(mt->prevch);
- w->buf = malloc(w->bufsize);
- w->mt = mt;
- if (!w->buf) {
- fprintf(stderr, "fuse: failed to allocate read buffer\n");
- free(w);
- return -1;
- }
-
- /* Disallow signal reception in worker threads */
- sigemptyset(&newset);
- sigaddset(&newset, SIGTERM);
- sigaddset(&newset, SIGINT);
- sigaddset(&newset, SIGHUP);
- sigaddset(&newset, SIGQUIT);
- pthread_sigmask(SIG_BLOCK, &newset, &oldset);
- res = pthread_create(&w->thread_id, NULL, fuse_do_work, w);
- pthread_sigmask(SIG_SETMASK, &oldset, NULL);
- if (res != 0) {
- fprintf(stderr, "fuse: error creating thread: %s\n", strerror(res));
- free(w->buf);
- free(w);
- return -1;
- }
- list_add_worker(w, &mt->main);
- mt->numavail ++;
- mt->numworker ++;
-
- return 0;
+ sigset_t oldset;
+ sigset_t newset;
+ int res;
+ struct fuse_worker *w = malloc(sizeof(struct fuse_worker));
+ if (!w) {
+ fprintf(stderr, "fuse: failed to allocate worker structure\n");
+ return -1;
+ }
+ memset(w, 0, sizeof(struct fuse_worker));
+ w->bufsize = fuse_chan_bufsize(mt->prevch);
+ w->buf = malloc(w->bufsize);
+ w->mt = mt;
+ if (!w->buf) {
+ fprintf(stderr, "fuse: failed to allocate read buffer\n");
+ free(w);
+ return -1;
+ }
+
+ /* Disallow signal reception in worker threads */
+ sigemptyset(&newset);
+ sigaddset(&newset, SIGTERM);
+ sigaddset(&newset, SIGINT);
+ sigaddset(&newset, SIGHUP);
+ sigaddset(&newset, SIGQUIT);
+ pthread_sigmask(SIG_BLOCK, &newset, &oldset);
+ res = pthread_create(&w->thread_id, NULL, fuse_do_work, w);
+ pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+ if (res != 0) {
+ fprintf(stderr, "fuse: error creating thread: %s\n",
+ strerror(res));
+ free(w->buf);
+ free(w);
+ return -1;
+ }
+ list_add_worker(w, &mt->main);
+ mt->numavail ++;
+ mt->numworker ++;
+
+ return 0;
}
static void fuse_join_worker(struct fuse_mt *mt, struct fuse_worker *w)
{
- pthread_join(w->thread_id, NULL);
- pthread_mutex_lock(&mt->lock);
- list_del_worker(w);
- pthread_mutex_unlock(&mt->lock);
- free(w->buf);
- free(w);
+ pthread_join(w->thread_id, NULL);
+ pthread_mutex_lock(&mt->lock);
+ list_del_worker(w);
+ pthread_mutex_unlock(&mt->lock);
+ free(w->buf);
+ free(w);
}
int fuse_session_loop_mt(struct fuse_session *se)
{
- int err;
- struct fuse_mt mt;
- struct fuse_worker *w;
-
- memset(&mt, 0, sizeof(struct fuse_mt));
- mt.se = se;
- mt.prevch = fuse_session_next_chan(se, NULL);
- mt.error = 0;
- mt.numworker = 0;
- mt.numavail = 0;
- mt.main.thread_id = pthread_self();
- mt.main.prev = mt.main.next = &mt.main;
- sem_init(&mt.finish, 0, 0);
- fuse_mutex_init(&mt.lock);
-
- pthread_mutex_lock(&mt.lock);
- err = fuse_start_thread(&mt);
- pthread_mutex_unlock(&mt.lock);
- if (!err) {
- /* sem_wait() is interruptible */
- while (!fuse_session_exited(se))
- sem_wait(&mt.finish);
-
- for (w = mt.main.next; w != &mt.main; w = w->next)
- pthread_cancel(w->thread_id);
- mt.exit = 1;
- pthread_mutex_unlock(&mt.lock);
-
- while (mt.main.next != &mt.main)
- fuse_join_worker(&mt, mt.main.next);
-
- err = mt.error;
- }
-
- pthread_mutex_destroy(&mt.lock);
- sem_destroy(&mt.finish);
- fuse_session_reset(se);
- return err;
+ int err;
+ struct fuse_mt mt;
+ struct fuse_worker *w;
+
+ memset(&mt, 0, sizeof(struct fuse_mt));
+ mt.se = se;
+ mt.prevch = fuse_session_next_chan(se, NULL);
+ mt.error = 0;
+ mt.numworker = 0;
+ mt.numavail = 0;
+ mt.main.thread_id = pthread_self();
+ mt.main.prev = mt.main.next = &mt.main;
+ sem_init(&mt.finish, 0, 0);
+ fuse_mutex_init(&mt.lock);
+
+ pthread_mutex_lock(&mt.lock);
+ err = fuse_start_thread(&mt);
+ pthread_mutex_unlock(&mt.lock);
+ if (!err) {
+ /* sem_wait() is interruptible */
+ while (!fuse_session_exited(se))
+ sem_wait(&mt.finish);
+
+ for (w = mt.main.next; w != &mt.main; w = w->next)
+ pthread_cancel(w->thread_id);
+ mt.exit = 1;
+ pthread_mutex_unlock(&mt.lock);
+
+ while (mt.main.next != &mt.main)
+ fuse_join_worker(&mt, mt.main.next);
+
+ err = mt.error;
+ }
+
+ pthread_mutex_destroy(&mt.lock);
+ sem_destroy(&mt.finish);
+ fuse_session_reset(se);
+ return err;
}
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index d39a4a1..5c9dc56 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse_lowlevel.h"
@@ -28,1225 +28,1234 @@
struct fuse_ll;
struct fuse_req {
- struct fuse_ll *f;
- uint64_t unique;
- int ctr;
- pthread_mutex_t lock;
- struct fuse_ctx ctx;
- struct fuse_chan *ch;
- int interrupted;
- union {
- struct {
- uint64_t unique;
- } i;
- struct {
- fuse_interrupt_func_t func;
- void *data;
- } ni;
- } u;
- struct fuse_req *next;
- struct fuse_req *prev;
+ struct fuse_ll *f;
+ uint64_t unique;
+ int ctr;
+ pthread_mutex_t lock;
+ struct fuse_ctx ctx;
+ struct fuse_chan *ch;
+ int interrupted;
+ union {
+ struct {
+ uint64_t unique;
+ } i;
+ struct {
+ fuse_interrupt_func_t func;
+ void *data;
+ } ni;
+ } u;
+ struct fuse_req *next;
+ struct fuse_req *prev;
};
struct fuse_ll {
- int debug;
- int allow_root;
- struct fuse_lowlevel_ops op;
- int got_init;
- void *userdata;
- uid_t owner;
- struct fuse_conn_info conn;
- struct fuse_req list;
- struct fuse_req interrupts;
- pthread_mutex_t lock;
- int got_destroy;
+ int debug;
+ int allow_root;
+ struct fuse_lowlevel_ops op;
+ int got_init;
+ void *userdata;
+ uid_t owner;
+ struct fuse_conn_info conn;
+ struct fuse_req list;
+ struct fuse_req interrupts;
+ pthread_mutex_t lock;
+ int got_destroy;
};
static void convert_stat(const struct stat *stbuf, struct fuse_attr *attr)
{
- attr->ino = stbuf->st_ino;
- attr->mode = stbuf->st_mode;
- attr->nlink = stbuf->st_nlink;
- attr->uid = stbuf->st_uid;
- attr->gid = stbuf->st_gid;
- attr->rdev = stbuf->st_rdev;
- attr->size = stbuf->st_size;
- attr->blocks = stbuf->st_blocks;
- attr->atime = stbuf->st_atime;
- attr->mtime = stbuf->st_mtime;
- attr->ctime = stbuf->st_ctime;
- attr->atimensec = ST_ATIM_NSEC(stbuf);
- attr->mtimensec = ST_MTIM_NSEC(stbuf);
- attr->ctimensec = ST_CTIM_NSEC(stbuf);
+ attr->ino = stbuf->st_ino;
+ attr->mode = stbuf->st_mode;
+ attr->nlink = stbuf->st_nlink;
+ attr->uid = stbuf->st_uid;
+ attr->gid = stbuf->st_gid;
+ attr->rdev = stbuf->st_rdev;
+ attr->size = stbuf->st_size;
+ attr->blocks = stbuf->st_blocks;
+ attr->atime = stbuf->st_atime;
+ attr->mtime = stbuf->st_mtime;
+ attr->ctime = stbuf->st_ctime;
+ attr->atimensec = ST_ATIM_NSEC(stbuf);
+ attr->mtimensec = ST_MTIM_NSEC(stbuf);
+ attr->ctimensec = ST_CTIM_NSEC(stbuf);
}
static void convert_attr(const struct fuse_setattr_in *attr, struct stat *stbuf)
{
- stbuf->st_mode = attr->mode;
- stbuf->st_uid = attr->uid;
- stbuf->st_gid = attr->gid;
- stbuf->st_size = attr->size;
- stbuf->st_atime = attr->atime;
- stbuf->st_mtime = attr->mtime;
- ST_ATIM_NSEC_SET(stbuf, attr->atimensec);
- ST_MTIM_NSEC_SET(stbuf, attr->mtimensec);
+ stbuf->st_mode = attr->mode;
+ stbuf->st_uid = attr->uid;
+ stbuf->st_gid = attr->gid;
+ stbuf->st_size = attr->size;
+ stbuf->st_atime = attr->atime;
+ stbuf->st_mtime = attr->mtime;
+ ST_ATIM_NSEC_SET(stbuf, attr->atimensec);
+ ST_MTIM_NSEC_SET(stbuf, attr->mtimensec);
}
-static size_t iov_length(const struct iovec *iov, size_t count)
+static size_t iov_length(const struct iovec *iov, size_t count)
{
- size_t seg;
- size_t ret = 0;
+ size_t seg;
+ size_t ret = 0;
- for (seg = 0; seg < count; seg++)
- ret += iov[seg].iov_len;
- return ret;
+ for (seg = 0; seg < count; seg++)
+ ret += iov[seg].iov_len;
+ return ret;
}
static void list_init_req(struct fuse_req *req)
{
- req->next = req;
- req->prev = req;
+ req->next = req;
+ req->prev = req;
}
static void list_del_req(struct fuse_req *req)
{
- struct fuse_req *prev = req->prev;
- struct fuse_req *next = req->next;
- prev->next = next;
- next->prev = prev;
+ struct fuse_req *prev = req->prev;
+ struct fuse_req *next = req->next;
+ prev->next = next;
+ next->prev = prev;
}
static void list_add_req(struct fuse_req *req, struct fuse_req *next)
{
- struct fuse_req *prev = next->prev;
- req->next = next;
- req->prev = prev;
- prev->next = req;
- next->prev = req;
+ struct fuse_req *prev = next->prev;
+ req->next = next;
+ req->prev = prev;
+ prev->next = req;
+ next->prev = req;
}
static void destroy_req(fuse_req_t req)
{
- pthread_mutex_destroy(&req->lock);
- free(req);
+ pthread_mutex_destroy(&req->lock);
+ free(req);
}
static void free_req(fuse_req_t req)
{
- int ctr;
- struct fuse_ll *f = req->f;
+ int ctr;
+ struct fuse_ll *f = req->f;
- pthread_mutex_lock(&req->lock);
- req->u.ni.func = NULL;
- req->u.ni.data = NULL;
- pthread_mutex_unlock(&req->lock);
+ pthread_mutex_lock(&req->lock);
+ req->u.ni.func = NULL;
+ req->u.ni.data = NULL;
+ pthread_mutex_unlock(&req->lock);
- pthread_mutex_lock(&f->lock);
- list_del_req(req);
- ctr = --req->ctr;
- pthread_mutex_unlock(&f->lock);
- if (!ctr)
- destroy_req(req);
+ pthread_mutex_lock(&f->lock);
+ list_del_req(req);
+ ctr = --req->ctr;
+ pthread_mutex_unlock(&f->lock);
+ if (!ctr)
+ destroy_req(req);
}
static int send_reply_iov(fuse_req_t req, int error, struct iovec *iov,
- int count)
+ int count)
{
- struct fuse_out_header out;
- int res;
+ struct fuse_out_header out;
+ int res;
- if (error <= -1000 || error > 0) {
- fprintf(stderr, "fuse: bad error value: %i\n", error);
- error = -ERANGE;
- }
+ if (error <= -1000 || error > 0) {
+ fprintf(stderr, "fuse: bad error value: %i\n", error);
+ error = -ERANGE;
+ }
- out.unique = req->unique;
- out.error = error;
- iov[0].iov_base = &out;
- iov[0].iov_len = sizeof(struct fuse_out_header);
- out.len = iov_length(iov, count);
+ out.unique = req->unique;
+ out.error = error;
+ iov[0].iov_base = &out;
+ iov[0].iov_len = sizeof(struct fuse_out_header);
+ out.len = iov_length(iov, count);
- if (req->f->debug)
- fprintf(stderr, " unique: %llu, error: %i (%s), outsize: %i\n",
- (unsigned long long) out.unique, out.error,
- strerror(-out.error), out.len);
- res = fuse_chan_send(req->ch, iov, count);
- free_req(req);
+ if (req->f->debug)
+ fprintf(stderr,
+ " unique: %llu, error: %i (%s), outsize: %i\n",
+ (unsigned long long) out.unique, out.error,
+ strerror(-out.error), out.len);
+ res = fuse_chan_send(req->ch, iov, count);
+ free_req(req);
- return res;
+ return res;
}
static int send_reply(fuse_req_t req, int error, const void *arg,
- size_t argsize)
+ size_t argsize)
{
- struct iovec iov[2];
- int count = 1;
- if (argsize) {
- iov[1].iov_base = (void *) arg;
- iov[1].iov_len = argsize;
- count++;
- }
- return send_reply_iov(req, error, iov, count);
+ struct iovec iov[2];
+ int count = 1;
+ if (argsize) {
+ iov[1].iov_base = (void *) arg;
+ iov[1].iov_len = argsize;
+ count++;
+ }
+ return send_reply_iov(req, error, iov, count);
}
int fuse_reply_iov(fuse_req_t req, const struct iovec *iov, int count)
{
- int res;
- struct iovec *padded_iov;
+ int res;
+ struct iovec *padded_iov;
- padded_iov = malloc((count + 1) * sizeof(struct iovec));
- if (padded_iov == NULL)
- return fuse_reply_err(req, -ENOMEM);
+ padded_iov = malloc((count + 1) * sizeof(struct iovec));
+ if (padded_iov == NULL)
+ return fuse_reply_err(req, -ENOMEM);
- memcpy(padded_iov + 1, iov, count * sizeof(struct iovec));
- count++;
+ memcpy(padded_iov + 1, iov, count * sizeof(struct iovec));
+ count++;
- res = send_reply_iov(req, 0, padded_iov, count);
- free(padded_iov);
+ res = send_reply_iov(req, 0, padded_iov, count);
+ free(padded_iov);
- return res;
+ return res;
}
size_t fuse_dirent_size(size_t namelen)
{
- return FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + namelen);
+ return FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + namelen);
}
char *fuse_add_dirent(char *buf, const char *name, const struct stat *stbuf,
- off_t off)
+ off_t off)
{
- unsigned namelen = strlen(name);
- unsigned entlen = FUSE_NAME_OFFSET + namelen;
- unsigned entsize = fuse_dirent_size(namelen);
- unsigned padlen = entsize - entlen;
- struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
+ unsigned namelen = strlen(name);
+ unsigned entlen = FUSE_NAME_OFFSET + namelen;
+ unsigned entsize = fuse_dirent_size(namelen);
+ unsigned padlen = entsize - entlen;
+ struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
- dirent->ino = stbuf->st_ino;
- dirent->off = off;
- dirent->namelen = namelen;
- dirent->type = (stbuf->st_mode & 0170000) >> 12;
- strncpy(dirent->name, name, namelen);
- if (padlen)
- memset(buf + entlen, 0, padlen);
+ dirent->ino = stbuf->st_ino;
+ dirent->off = off;
+ dirent->namelen = namelen;
+ dirent->type = (stbuf->st_mode & 0170000) >> 12;
+ strncpy(dirent->name, name, namelen);
+ if (padlen)
+ memset(buf + entlen, 0, padlen);
- return buf + entsize;
+ return buf + entsize;
}
size_t fuse_add_direntry(fuse_req_t req, char *buf, size_t bufsize,
- const char *name, const struct stat *stbuf, off_t off)
+ const char *name, const struct stat *stbuf, off_t off)
{
- size_t entsize;
+ size_t entsize;
- (void) req;
- entsize = fuse_dirent_size(strlen(name));
- if (entsize <= bufsize && buf)
- fuse_add_dirent(buf, name, stbuf, off);
- return entsize;
+ (void) req;
+ entsize = fuse_dirent_size(strlen(name));
+ if (entsize <= bufsize && buf)
+ fuse_add_dirent(buf, name, stbuf, off);
+ return entsize;
}
static void convert_statfs(const struct statvfs *stbuf,
- struct fuse_kstatfs *kstatfs)
+ struct fuse_kstatfs *kstatfs)
{
- kstatfs->bsize = stbuf->f_bsize;
- kstatfs->frsize = stbuf->f_frsize;
- kstatfs->blocks = stbuf->f_blocks;
- kstatfs->bfree = stbuf->f_bfree;
- kstatfs->bavail = stbuf->f_bavail;
- kstatfs->files = stbuf->f_files;
- kstatfs->ffree = stbuf->f_ffree;
- kstatfs->namelen = stbuf->f_namemax;
+ kstatfs->bsize = stbuf->f_bsize;
+ kstatfs->frsize = stbuf->f_frsize;
+ kstatfs->blocks = stbuf->f_blocks;
+ kstatfs->bfree = stbuf->f_bfree;
+ kstatfs->bavail = stbuf->f_bavail;
+ kstatfs->files = stbuf->f_files;
+ kstatfs->ffree = stbuf->f_ffree;
+ kstatfs->namelen = stbuf->f_namemax;
}
static int send_reply_ok(fuse_req_t req, const void *arg, size_t argsize)
{
- return send_reply(req, 0, arg, argsize);
+ return send_reply(req, 0, arg, argsize);
}
int fuse_reply_err(fuse_req_t req, int err)
{
- return send_reply(req, -err, NULL, 0);
+ return send_reply(req, -err, NULL, 0);
}
void fuse_reply_none(fuse_req_t req)
{
- fuse_chan_send(req->ch, NULL, 0);
- free_req(req);
+ fuse_chan_send(req->ch, NULL, 0);
+ free_req(req);
}
static unsigned long calc_timeout_sec(double t)
{
- if (t > (double) ULONG_MAX)
- return ULONG_MAX;
- else if (t < 0.0)
- return 0;
- else
- return (unsigned long) t;
+ if (t > (double) ULONG_MAX)
+ return ULONG_MAX;
+ else if (t < 0.0)
+ return 0;
+ else
+ return (unsigned long) t;
}
static unsigned int calc_timeout_nsec(double t)
{
- double f = t - (double) calc_timeout_sec(t);
- if (f < 0.0)
- return 0;
- else if (f >= 0.999999999)
- return 999999999;
- else
- return (unsigned int) (f * 1.0e9);
+ double f = t - (double) calc_timeout_sec(t);
+ if (f < 0.0)
+ return 0;
+ else if (f >= 0.999999999)
+ return 999999999;
+ else
+ return (unsigned int) (f * 1.0e9);
}
static void fill_entry(struct fuse_entry_out *arg,
- const struct fuse_entry_param *e)
+ const struct fuse_entry_param *e)
{
- arg->nodeid = e->ino;
- arg->generation = e->generation;
- arg->entry_valid = calc_timeout_sec(e->entry_timeout);
- arg->entry_valid_nsec = calc_timeout_nsec(e->entry_timeout);
- arg->attr_valid = calc_timeout_sec(e->attr_timeout);
- arg->attr_valid_nsec = calc_timeout_nsec(e->attr_timeout);
- convert_stat(&e->attr, &arg->attr);
+ arg->nodeid = e->ino;
+ arg->generation = e->generation;
+ arg->entry_valid = calc_timeout_sec(e->entry_timeout);
+ arg->entry_valid_nsec = calc_timeout_nsec(e->entry_timeout);
+ arg->attr_valid = calc_timeout_sec(e->attr_timeout);
+ arg->attr_valid_nsec = calc_timeout_nsec(e->attr_timeout);
+ convert_stat(&e->attr, &arg->attr);
}
static void fill_open(struct fuse_open_out *arg,
- const struct fuse_file_info *f)
+ const struct fuse_file_info *f)
{
- arg->fh = f->fh;
- if (f->direct_io)
- arg->open_flags |= FOPEN_DIRECT_IO;
- if (f->keep_cache)
- arg->open_flags |= FOPEN_KEEP_CACHE;
+ arg->fh = f->fh;
+ if (f->direct_io)
+ arg->open_flags |= FOPEN_DIRECT_IO;
+ if (f->keep_cache)
+ arg->open_flags |= FOPEN_KEEP_CACHE;
}
int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e)
{
- struct fuse_entry_out arg;
+ struct fuse_entry_out arg;
- /* before ABI 7.4 e->ino == 0 was invalid, only ENOENT meant
- negative entry */
- if (!e->ino && req->f->conn.proto_minor < 4)
- return fuse_reply_err(req, ENOENT);
+ /* before ABI 7.4 e->ino == 0 was invalid, only ENOENT meant
+ negative entry */
+ if (!e->ino && req->f->conn.proto_minor < 4)
+ return fuse_reply_err(req, ENOENT);
- memset(&arg, 0, sizeof(arg));
- fill_entry(&arg, e);
- return send_reply_ok(req, &arg, sizeof(arg));
+ memset(&arg, 0, sizeof(arg));
+ fill_entry(&arg, e);
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e,
- const struct fuse_file_info *f)
+ const struct fuse_file_info *f)
{
- struct {
- struct fuse_entry_out e;
- struct fuse_open_out o;
- } arg;
+ struct {
+ struct fuse_entry_out e;
+ struct fuse_open_out o;
+ } arg;
- memset(&arg, 0, sizeof(arg));
- fill_entry(&arg.e, e);
- fill_open(&arg.o, f);
- return send_reply_ok(req, &arg, sizeof(arg));
+ memset(&arg, 0, sizeof(arg));
+ fill_entry(&arg.e, e);
+ fill_open(&arg.o, f);
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_attr(fuse_req_t req, const struct stat *attr,
- double attr_timeout)
+ double attr_timeout)
{
- struct fuse_attr_out arg;
+ struct fuse_attr_out arg;
- memset(&arg, 0, sizeof(arg));
- arg.attr_valid = calc_timeout_sec(attr_timeout);
- arg.attr_valid_nsec = calc_timeout_nsec(attr_timeout);
- convert_stat(attr, &arg.attr);
+ memset(&arg, 0, sizeof(arg));
+ arg.attr_valid = calc_timeout_sec(attr_timeout);
+ arg.attr_valid_nsec = calc_timeout_nsec(attr_timeout);
+ convert_stat(attr, &arg.attr);
- return send_reply_ok(req, &arg, sizeof(arg));
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_readlink(fuse_req_t req, const char *linkname)
{
- return send_reply_ok(req, linkname, strlen(linkname));
+ return send_reply_ok(req, linkname, strlen(linkname));
}
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *f)
{
- struct fuse_open_out arg;
+ struct fuse_open_out arg;
- memset(&arg, 0, sizeof(arg));
- fill_open(&arg, f);
- return send_reply_ok(req, &arg, sizeof(arg));
+ memset(&arg, 0, sizeof(arg));
+ fill_open(&arg, f);
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_write(fuse_req_t req, size_t count)
{
- struct fuse_write_out arg;
+ struct fuse_write_out arg;
- memset(&arg, 0, sizeof(arg));
- arg.size = count;
+ memset(&arg, 0, sizeof(arg));
+ arg.size = count;
- return send_reply_ok(req, &arg, sizeof(arg));
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size)
{
- return send_reply_ok(req, buf, size);
+ return send_reply_ok(req, buf, size);
}
int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf)
{
- struct fuse_statfs_out arg;
- size_t size = req->f->conn.proto_minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(arg);
+ struct fuse_statfs_out arg;
+ size_t size = req->f->conn.proto_minor < 4 ?
+ FUSE_COMPAT_STATFS_SIZE : sizeof(arg);
- memset(&arg, 0, sizeof(arg));
- convert_statfs(stbuf, &arg.st);
+ memset(&arg, 0, sizeof(arg));
+ convert_statfs(stbuf, &arg.st);
- return send_reply_ok(req, &arg, size);
+ return send_reply_ok(req, &arg, size);
}
int fuse_reply_xattr(fuse_req_t req, size_t count)
{
- struct fuse_getxattr_out arg;
+ struct fuse_getxattr_out arg;
- memset(&arg, 0, sizeof(arg));
- arg.size = count;
+ memset(&arg, 0, sizeof(arg));
+ arg.size = count;
- return send_reply_ok(req, &arg, sizeof(arg));
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_lock(fuse_req_t req, struct flock *lock)
{
- struct fuse_lk_out arg;
+ struct fuse_lk_out arg;
- memset(&arg, 0, sizeof(arg));
- arg.lk.type = lock->l_type;
- if (lock->l_type != F_UNLCK) {
- arg.lk.start = lock->l_start;
- if (lock->l_len == 0)
- arg.lk.end = OFFSET_MAX;
- else
- arg.lk.end = lock->l_start + lock->l_len - 1;
- }
- arg.lk.pid = lock->l_pid;
- return send_reply_ok(req, &arg, sizeof(arg));
+ memset(&arg, 0, sizeof(arg));
+ arg.lk.type = lock->l_type;
+ if (lock->l_type != F_UNLCK) {
+ arg.lk.start = lock->l_start;
+ if (lock->l_len == 0)
+ arg.lk.end = OFFSET_MAX;
+ else
+ arg.lk.end = lock->l_start + lock->l_len - 1;
+ }
+ arg.lk.pid = lock->l_pid;
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_bmap(fuse_req_t req, uint64_t idx)
{
- struct fuse_bmap_out arg;
+ struct fuse_bmap_out arg;
- memset(&arg, 0, sizeof(arg));
- arg.block = idx;
+ memset(&arg, 0, sizeof(arg));
+ arg.block = idx;
- return send_reply_ok(req, &arg, sizeof(arg));
+ return send_reply_ok(req, &arg, sizeof(arg));
}
static void do_lookup(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- char *name = (char *) inarg;
+ char *name = (char *) inarg;
- if (req->f->op.lookup)
- req->f->op.lookup(req, nodeid, name);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.lookup)
+ req->f->op.lookup(req, nodeid, name);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_forget(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_forget_in *arg = (struct fuse_forget_in *) inarg;
+ struct fuse_forget_in *arg = (struct fuse_forget_in *) inarg;
- if (req->f->op.forget)
- req->f->op.forget(req, nodeid, arg->nlookup);
- else
- fuse_reply_none(req);
+ if (req->f->op.forget)
+ req->f->op.forget(req, nodeid, arg->nlookup);
+ else
+ fuse_reply_none(req);
}
static void do_getattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- (void) inarg;
+ (void) inarg;
- if (req->f->op.getattr)
- req->f->op.getattr(req, nodeid, NULL);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.getattr)
+ req->f->op.getattr(req, nodeid, NULL);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_setattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_setattr_in *arg = (struct fuse_setattr_in *) inarg;
-
- if (req->f->op.setattr) {
- struct fuse_file_info *fi = NULL;
- struct fuse_file_info fi_store;
- struct stat stbuf;
- memset(&stbuf, 0, sizeof(stbuf));
- convert_attr(arg, &stbuf);
- if (arg->valid & FATTR_FH) {
- arg->valid &= ~FATTR_FH;
- memset(&fi_store, 0, sizeof(fi_store));
- fi = &fi_store;
- fi->fh = arg->fh;
- fi->fh_old = fi->fh;
- }
- req->f->op.setattr(req, nodeid, &stbuf, arg->valid, fi);
- } else
- fuse_reply_err(req, ENOSYS);
+ struct fuse_setattr_in *arg = (struct fuse_setattr_in *) inarg;
+
+ if (req->f->op.setattr) {
+ struct fuse_file_info *fi = NULL;
+ struct fuse_file_info fi_store;
+ struct stat stbuf;
+ memset(&stbuf, 0, sizeof(stbuf));
+ convert_attr(arg, &stbuf);
+ if (arg->valid & FATTR_FH) {
+ arg->valid &= ~FATTR_FH;
+ memset(&fi_store, 0, sizeof(fi_store));
+ fi = &fi_store;
+ fi->fh = arg->fh;
+ fi->fh_old = fi->fh;
+ }
+ req->f->op.setattr(req, nodeid, &stbuf, arg->valid, fi);
+ } else
+ fuse_reply_err(req, ENOSYS);
}
static void do_access(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_access_in *arg = (struct fuse_access_in *) inarg;
+ struct fuse_access_in *arg = (struct fuse_access_in *) inarg;
- if (req->f->op.access)
- req->f->op.access(req, nodeid, arg->mask);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.access)
+ req->f->op.access(req, nodeid, arg->mask);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_readlink(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- (void) inarg;
+ (void) inarg;
- if (req->f->op.readlink)
- req->f->op.readlink(req, nodeid);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.readlink)
+ req->f->op.readlink(req, nodeid);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_mknod(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_mknod_in *arg = (struct fuse_mknod_in *) inarg;
+ struct fuse_mknod_in *arg = (struct fuse_mknod_in *) inarg;
- if (req->f->op.mknod)
- req->f->op.mknod(req, nodeid, PARAM(arg), arg->mode, arg->rdev);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.mknod)
+ req->f->op.mknod(req, nodeid, PARAM(arg), arg->mode, arg->rdev);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_mkdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_mkdir_in *arg = (struct fuse_mkdir_in *) inarg;
+ struct fuse_mkdir_in *arg = (struct fuse_mkdir_in *) inarg;
- if (req->f->op.mkdir)
- req->f->op.mkdir(req, nodeid, PARAM(arg), arg->mode);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.mkdir)
+ req->f->op.mkdir(req, nodeid, PARAM(arg), arg->mode);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_unlink(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- char *name = (char *) inarg;
+ char *name = (char *) inarg;
- if (req->f->op.unlink)
- req->f->op.unlink(req, nodeid, name);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.unlink)
+ req->f->op.unlink(req, nodeid, name);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_rmdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- char *name = (char *) inarg;
+ char *name = (char *) inarg;
- if (req->f->op.rmdir)
- req->f->op.rmdir(req, nodeid, name);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.rmdir)
+ req->f->op.rmdir(req, nodeid, name);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_symlink(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- char *name = (char *) inarg;
- char *linkname = ((char *) inarg) + strlen((char *) inarg) + 1;
+ char *name = (char *) inarg;
+ char *linkname = ((char *) inarg) + strlen((char *) inarg) + 1;
- if (req->f->op.symlink)
- req->f->op.symlink(req, linkname, nodeid, name);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.symlink)
+ req->f->op.symlink(req, linkname, nodeid, name);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_rename(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_rename_in *arg = (struct fuse_rename_in *) inarg;
- char *oldname = PARAM(arg);
- char *newname = oldname + strlen(oldname) + 1;
+ struct fuse_rename_in *arg = (struct fuse_rename_in *) inarg;
+ char *oldname = PARAM(arg);
+ char *newname = oldname + strlen(oldname) + 1;
- if (req->f->op.rename)
- req->f->op.rename(req, nodeid, oldname, arg->newdir, newname);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.rename)
+ req->f->op.rename(req, nodeid, oldname, arg->newdir, newname);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_link(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_link_in *arg = (struct fuse_link_in *) inarg;
+ struct fuse_link_in *arg = (struct fuse_link_in *) inarg;
- if (req->f->op.link)
- req->f->op.link(req, arg->oldnodeid, nodeid, PARAM(arg));
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.link)
+ req->f->op.link(req, arg->oldnodeid, nodeid, PARAM(arg));
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_create(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
+ struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
- if (req->f->op.create) {
- struct fuse_file_info fi;
+ if (req->f->op.create) {
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.flags = arg->flags;
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = arg->flags;
- req->f->op.create(req, nodeid, PARAM(arg), arg->mode, &fi);
- } else
- fuse_reply_err(req, ENOSYS);
+ req->f->op.create(req, nodeid, PARAM(arg), arg->mode, &fi);
+ } else
+ fuse_reply_err(req, ENOSYS);
}
static void do_open(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.flags = arg->flags;
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = arg->flags;
- if (req->f->op.open)
- req->f->op.open(req, nodeid, &fi);
- else
- fuse_reply_open(req, &fi);
+ if (req->f->op.open)
+ req->f->op.open(req, nodeid, &fi);
+ else
+ fuse_reply_open(req, &fi);
}
static void do_read(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_read_in *arg = (struct fuse_read_in *) inarg;
+ struct fuse_read_in *arg = (struct fuse_read_in *) inarg;
- if (req->f->op.read) {
- struct fuse_file_info fi;
+ if (req->f->op.read) {
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
- req->f->op.read(req, nodeid, arg->size, arg->offset, &fi);
- } else
- fuse_reply_err(req, ENOSYS);
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
+ req->f->op.read(req, nodeid, arg->size, arg->offset, &fi);
+ } else
+ fuse_reply_err(req, ENOSYS);
}
static void do_write(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_write_in *arg = (struct fuse_write_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_write_in *arg = (struct fuse_write_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
- fi.writepage = arg->write_flags & 1;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
+ fi.writepage = arg->write_flags & 1;
- if (req->f->op.write)
- req->f->op.write(req, nodeid, PARAM(arg), arg->size, arg->offset, &fi);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.write)
+ req->f->op.write(req, nodeid, PARAM(arg), arg->size,
+ arg->offset, &fi);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_flush(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_flush_in *arg = (struct fuse_flush_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_flush_in *arg = (struct fuse_flush_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
- fi.flush = 1;
- if (req->f->conn.proto_minor >= 7)
- fi.lock_owner = arg->lock_owner;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
+ fi.flush = 1;
+ if (req->f->conn.proto_minor >= 7)
+ fi.lock_owner = arg->lock_owner;
- if (req->f->op.flush)
- req->f->op.flush(req, nodeid, &fi);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.flush)
+ req->f->op.flush(req, nodeid, &fi);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_release(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_release_in *arg = (struct fuse_release_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_release_in *arg = (struct fuse_release_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.flags = arg->flags;
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
- if (req->f->conn.proto_minor >= 8) {
- fi.flush = (arg->release_flags & FUSE_RELEASE_FLUSH) ? 1 : 0;
- fi.lock_owner = arg->lock_owner;
- }
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = arg->flags;
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
+ if (req->f->conn.proto_minor >= 8) {
+ fi.flush = (arg->release_flags & FUSE_RELEASE_FLUSH) ? 1 : 0;
+ fi.lock_owner = arg->lock_owner;
+ }
- if (req->f->op.release)
- req->f->op.release(req, nodeid, &fi);
- else
- fuse_reply_err(req, 0);
+ if (req->f->op.release)
+ req->f->op.release(req, nodeid, &fi);
+ else
+ fuse_reply_err(req, 0);
}
static void do_fsync(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
- if (req->f->op.fsync)
- req->f->op.fsync(req, nodeid, arg->fsync_flags & 1, &fi);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.fsync)
+ req->f->op.fsync(req, nodeid, arg->fsync_flags & 1, &fi);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_opendir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_open_in *arg = (struct fuse_open_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.flags = arg->flags;
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = arg->flags;
- if (req->f->op.opendir)
- req->f->op.opendir(req, nodeid, &fi);
- else
- fuse_reply_open(req, &fi);
+ if (req->f->op.opendir)
+ req->f->op.opendir(req, nodeid, &fi);
+ else
+ fuse_reply_open(req, &fi);
}
static void do_readdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_read_in *arg = (struct fuse_read_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_read_in *arg = (struct fuse_read_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
- if (req->f->op.readdir)
- req->f->op.readdir(req, nodeid, arg->size, arg->offset, &fi);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.readdir)
+ req->f->op.readdir(req, nodeid, arg->size, arg->offset, &fi);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_releasedir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_release_in *arg = (struct fuse_release_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_release_in *arg = (struct fuse_release_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.flags = arg->flags;
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
+ memset(&fi, 0, sizeof(fi));
+ fi.flags = arg->flags;
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
- if (req->f->op.releasedir)
- req->f->op.releasedir(req, nodeid, &fi);
- else
- fuse_reply_err(req, 0);
+ if (req->f->op.releasedir)
+ req->f->op.releasedir(req, nodeid, &fi);
+ else
+ fuse_reply_err(req, 0);
}
static void do_fsyncdir(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg;
- struct fuse_file_info fi;
+ struct fuse_fsync_in *arg = (struct fuse_fsync_in *) inarg;
+ struct fuse_file_info fi;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.fh_old = fi.fh;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.fh_old = fi.fh;
- if (req->f->op.fsyncdir)
- req->f->op.fsyncdir(req, nodeid, arg->fsync_flags & 1, &fi);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.fsyncdir)
+ req->f->op.fsyncdir(req, nodeid, arg->fsync_flags & 1, &fi);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_statfs(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- (void) nodeid;
- (void) inarg;
+ (void) nodeid;
+ (void) inarg;
- if (req->f->op.statfs)
- req->f->op.statfs(req, nodeid);
- else {
- struct statvfs buf = {
- .f_namemax = 255,
- .f_bsize = 512,
- };
- fuse_reply_statfs(req, &buf);
- }
+ if (req->f->op.statfs)
+ req->f->op.statfs(req, nodeid);
+ else {
+ struct statvfs buf = {
+ .f_namemax = 255,
+ .f_bsize = 512,
+ };
+ fuse_reply_statfs(req, &buf);
+ }
}
static void do_setxattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_setxattr_in *arg = (struct fuse_setxattr_in *) inarg;
- char *name = PARAM(arg);
- char *value = name + strlen(name) + 1;
+ struct fuse_setxattr_in *arg = (struct fuse_setxattr_in *) inarg;
+ char *name = PARAM(arg);
+ char *value = name + strlen(name) + 1;
- if (req->f->op.setxattr)
- req->f->op.setxattr(req, nodeid, name, value, arg->size, arg->flags);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.setxattr)
+ req->f->op.setxattr(req, nodeid, name, value, arg->size,
+ arg->flags);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_getxattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg;
+ struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg;
- if (req->f->op.getxattr)
- req->f->op.getxattr(req, nodeid, PARAM(arg), arg->size);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.getxattr)
+ req->f->op.getxattr(req, nodeid, PARAM(arg), arg->size);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_listxattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg;
+ struct fuse_getxattr_in *arg = (struct fuse_getxattr_in *) inarg;
- if (req->f->op.listxattr)
- req->f->op.listxattr(req, nodeid, arg->size);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.listxattr)
+ req->f->op.listxattr(req, nodeid, arg->size);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_removexattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- char *name = (char *) inarg;
+ char *name = (char *) inarg;
- if (req->f->op.removexattr)
- req->f->op.removexattr(req, nodeid, name);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.removexattr)
+ req->f->op.removexattr(req, nodeid, name);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void convert_fuse_file_lock(struct fuse_file_lock *fl,
- struct flock *flock)
+ struct flock *flock)
{
- memset(flock, 0, sizeof(struct flock));
- flock->l_type = fl->type;
- flock->l_whence = SEEK_SET;
- flock->l_start = fl->start;
- if (fl->end == OFFSET_MAX)
- flock->l_len = 0;
- else
- flock->l_len = fl->end - fl->start + 1;
- flock->l_pid = fl->pid;
+ memset(flock, 0, sizeof(struct flock));
+ flock->l_type = fl->type;
+ flock->l_whence = SEEK_SET;
+ flock->l_start = fl->start;
+ if (fl->end == OFFSET_MAX)
+ flock->l_len = 0;
+ else
+ flock->l_len = fl->end - fl->start + 1;
+ flock->l_pid = fl->pid;
}
static void do_getlk(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_lk_in *arg = (struct fuse_lk_in *) inarg;
- struct fuse_file_info fi;
- struct flock flock;
+ struct fuse_lk_in *arg = (struct fuse_lk_in *) inarg;
+ struct fuse_file_info fi;
+ struct flock flock;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.lock_owner = arg->owner;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.lock_owner = arg->owner;
- convert_fuse_file_lock(&arg->lk, &flock);
- if (req->f->op.getlk)
- req->f->op.getlk(req, nodeid, &fi, &flock);
- else
- fuse_reply_err(req, ENOSYS);
+ convert_fuse_file_lock(&arg->lk, &flock);
+ if (req->f->op.getlk)
+ req->f->op.getlk(req, nodeid, &fi, &flock);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_setlk_common(fuse_req_t req, fuse_ino_t nodeid,
- const void *inarg, int sleep)
+ const void *inarg, int sleep)
{
- struct fuse_lk_in *arg = (struct fuse_lk_in *) inarg;
- struct fuse_file_info fi;
- struct flock flock;
+ struct fuse_lk_in *arg = (struct fuse_lk_in *) inarg;
+ struct fuse_file_info fi;
+ struct flock flock;
- memset(&fi, 0, sizeof(fi));
- fi.fh = arg->fh;
- fi.lock_owner = arg->owner;
+ memset(&fi, 0, sizeof(fi));
+ fi.fh = arg->fh;
+ fi.lock_owner = arg->owner;
- convert_fuse_file_lock(&arg->lk, &flock);
- if (req->f->op.setlk)
- req->f->op.setlk(req, nodeid, &fi, &flock, sleep);
- else
- fuse_reply_err(req, ENOSYS);
+ convert_fuse_file_lock(&arg->lk, &flock);
+ if (req->f->op.setlk)
+ req->f->op.setlk(req, nodeid, &fi, &flock, sleep);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_setlk(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- do_setlk_common(req, nodeid, inarg, 0);
+ do_setlk_common(req, nodeid, inarg, 0);
}
static void do_setlkw(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- do_setlk_common(req, nodeid, inarg, 1);
+ do_setlk_common(req, nodeid, inarg, 1);
}
static int find_interrupted(struct fuse_ll *f, struct fuse_req *req)
{
- struct fuse_req *curr;
-
- for (curr = f->list.next; curr != &f->list; curr = curr->next) {
- if (curr->unique == req->u.i.unique) {
- curr->ctr++;
- pthread_mutex_unlock(&f->lock);
-
- /* Ugh, ugly locking */
- pthread_mutex_lock(&curr->lock);
- pthread_mutex_lock(&f->lock);
- curr->interrupted = 1;
- pthread_mutex_unlock(&f->lock);
- if (curr->u.ni.func)
- curr->u.ni.func(curr, curr->u.ni.data);
- pthread_mutex_unlock(&curr->lock);
-
- pthread_mutex_lock(&f->lock);
- curr->ctr--;
- if (!curr->ctr)
- destroy_req(curr);
-
- return 1;
- }
- }
- for (curr = f->interrupts.next; curr != &f->interrupts;
- curr = curr->next) {
- if (curr->u.i.unique == req->u.i.unique)
- return 1;
- }
- return 0;
+ struct fuse_req *curr;
+
+ for (curr = f->list.next; curr != &f->list; curr = curr->next) {
+ if (curr->unique == req->u.i.unique) {
+ curr->ctr++;
+ pthread_mutex_unlock(&f->lock);
+
+ /* Ugh, ugly locking */
+ pthread_mutex_lock(&curr->lock);
+ pthread_mutex_lock(&f->lock);
+ curr->interrupted = 1;
+ pthread_mutex_unlock(&f->lock);
+ if (curr->u.ni.func)
+ curr->u.ni.func(curr, curr->u.ni.data);
+ pthread_mutex_unlock(&curr->lock);
+
+ pthread_mutex_lock(&f->lock);
+ curr->ctr--;
+ if (!curr->ctr)
+ destroy_req(curr);
+
+ return 1;
+ }
+ }
+ for (curr = f->interrupts.next; curr != &f->interrupts;
+ curr = curr->next) {
+ if (curr->u.i.unique == req->u.i.unique)
+ return 1;
+ }
+ return 0;
}
static void do_interrupt(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_interrupt_in *arg = (struct fuse_interrupt_in *) inarg;
- struct fuse_ll *f = req->f;
+ struct fuse_interrupt_in *arg = (struct fuse_interrupt_in *) inarg;
+ struct fuse_ll *f = req->f;
- (void) nodeid;
- if (f->debug)
- fprintf(stderr, "INTERRUPT: %llu\n", (unsigned long long) arg->unique);
+ (void) nodeid;
+ if (f->debug)
+ fprintf(stderr, "INTERRUPT: %llu\n",
+ (unsigned long long) arg->unique);
- req->u.i.unique = arg->unique;
+ req->u.i.unique = arg->unique;
- pthread_mutex_lock(&f->lock);
- if (find_interrupted(f, req))
- destroy_req(req);
- else
- list_add_req(req, &f->interrupts);
- pthread_mutex_unlock(&f->lock);
+ pthread_mutex_lock(&f->lock);
+ if (find_interrupted(f, req))
+ destroy_req(req);
+ else
+ list_add_req(req, &f->interrupts);
+ pthread_mutex_unlock(&f->lock);
}
static struct fuse_req *check_interrupt(struct fuse_ll *f, struct fuse_req *req)
{
- struct fuse_req *curr;
-
- for (curr = f->interrupts.next; curr != &f->interrupts; curr = curr->next) {
- if (curr->u.i.unique == req->unique) {
- req->interrupted = 1;
- list_del_req(curr);
- free(curr);
- return NULL;
- }
- }
- curr = f->interrupts.next;
- if (curr != &f->interrupts) {
- list_del_req(curr);
- list_init_req(curr);
- return curr;
- } else
- return NULL;
+ struct fuse_req *curr;
+
+ for (curr = f->interrupts.next; curr != &f->interrupts;
+ curr = curr->next) {
+ if (curr->u.i.unique == req->unique) {
+ req->interrupted = 1;
+ list_del_req(curr);
+ free(curr);
+ return NULL;
+ }
+ }
+ curr = f->interrupts.next;
+ if (curr != &f->interrupts) {
+ list_del_req(curr);
+ list_init_req(curr);
+ return curr;
+ } else
+ return NULL;
}
static void do_bmap(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_bmap_in *arg = (struct fuse_bmap_in *) inarg;
+ struct fuse_bmap_in *arg = (struct fuse_bmap_in *) inarg;
- if (req->f->op.bmap)
- req->f->op.bmap(req, nodeid, arg->blocksize, arg->block);
- else
- fuse_reply_err(req, ENOSYS);
+ if (req->f->op.bmap)
+ req->f->op.bmap(req, nodeid, arg->blocksize, arg->block);
+ else
+ fuse_reply_err(req, ENOSYS);
}
static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_init_in *arg = (struct fuse_init_in *) inarg;
- struct fuse_init_out outarg;
- struct fuse_ll *f = req->f;
- size_t bufsize = fuse_chan_bufsize(req->ch);
-
- (void) nodeid;
- if (f->debug) {
- fprintf(stderr, "INIT: %u.%u\n", arg->major, arg->minor);
- if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) {
- fprintf(stderr, "flags=0x%08x\n", arg->flags);
- fprintf(stderr, "max_readahead=0x%08x\n", arg->max_readahead);
- }
- }
- f->conn.proto_major = arg->major;
- f->conn.proto_minor = arg->minor;
-
- if (arg->major < 7) {
- fprintf(stderr, "fuse: unsupported protocol version: %u.%u\n",
- arg->major, arg->minor);
- fuse_reply_err(req, EPROTO);
- return;
- }
-
- if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) {
- if (f->conn.async_read)
- f->conn.async_read = arg->flags & FUSE_ASYNC_READ;
- if (arg->max_readahead < f->conn.max_readahead)
- f->conn.max_readahead = arg->max_readahead;
- } else {
- f->conn.async_read = 0;
- f->conn.max_readahead = 0;
- }
-
- if (bufsize < FUSE_MIN_READ_BUFFER) {
- fprintf(stderr, "fuse: warning: buffer size too small: %zu\n",
- bufsize);
- bufsize = FUSE_MIN_READ_BUFFER;
- }
-
- bufsize -= 4096;
- if (bufsize < f->conn.max_write)
- f->conn.max_write = bufsize;
-
- f->got_init = 1;
- if (f->op.init)
- f->op.init(f->userdata, &f->conn);
-
- memset(&outarg, 0, sizeof(outarg));
- outarg.major = FUSE_KERNEL_VERSION;
- outarg.minor = FUSE_KERNEL_MINOR_VERSION;
- if (f->conn.async_read)
- outarg.flags |= FUSE_ASYNC_READ;
- if (f->op.getlk && f->op.setlk)
- outarg.flags |= FUSE_POSIX_LOCKS;
- outarg.max_readahead = f->conn.max_readahead;
- outarg.max_write = f->conn.max_write;
-
- if (f->debug) {
- fprintf(stderr, " INIT: %u.%u\n", outarg.major, outarg.minor);
- fprintf(stderr, " flags=0x%08x\n", outarg.flags);
- fprintf(stderr, " max_readahead=0x%08x\n", outarg.max_readahead);
- fprintf(stderr, " max_write=0x%08x\n", outarg.max_write);
- }
-
- send_reply_ok(req, &outarg, arg->minor < 5 ? 8 : sizeof(outarg));
+ struct fuse_init_in *arg = (struct fuse_init_in *) inarg;
+ struct fuse_init_out outarg;
+ struct fuse_ll *f = req->f;
+ size_t bufsize = fuse_chan_bufsize(req->ch);
+
+ (void) nodeid;
+ if (f->debug) {
+ fprintf(stderr, "INIT: %u.%u\n", arg->major, arg->minor);
+ if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) {
+ fprintf(stderr, "flags=0x%08x\n", arg->flags);
+ fprintf(stderr, "max_readahead=0x%08x\n",
+ arg->max_readahead);
+ }
+ }
+ f->conn.proto_major = arg->major;
+ f->conn.proto_minor = arg->minor;
+
+ if (arg->major < 7) {
+ fprintf(stderr, "fuse: unsupported protocol version: %u.%u\n",
+ arg->major, arg->minor);
+ fuse_reply_err(req, EPROTO);
+ return;
+ }
+
+ if (arg->major > 7 || (arg->major == 7 && arg->minor >= 6)) {
+ if (f->conn.async_read)
+ f->conn.async_read = arg->flags & FUSE_ASYNC_READ;
+ if (arg->max_readahead < f->conn.max_readahead)
+ f->conn.max_readahead = arg->max_readahead;
+ } else {
+ f->conn.async_read = 0;
+ f->conn.max_readahead = 0;
+ }
+
+ if (bufsize < FUSE_MIN_READ_BUFFER) {
+ fprintf(stderr, "fuse: warning: buffer size too small: %zu\n",
+ bufsize);
+ bufsize = FUSE_MIN_READ_BUFFER;
+ }
+
+ bufsize -= 4096;
+ if (bufsize < f->conn.max_write)
+ f->conn.max_write = bufsize;
+
+ f->got_init = 1;
+ if (f->op.init)
+ f->op.init(f->userdata, &f->conn);
+
+ memset(&outarg, 0, sizeof(outarg));
+ outarg.major = FUSE_KERNEL_VERSION;
+ outarg.minor = FUSE_KERNEL_MINOR_VERSION;
+ if (f->conn.async_read)
+ outarg.flags |= FUSE_ASYNC_READ;
+ if (f->op.getlk && f->op.setlk)
+ outarg.flags |= FUSE_POSIX_LOCKS;
+ outarg.max_readahead = f->conn.max_readahead;
+ outarg.max_write = f->conn.max_write;
+
+ if (f->debug) {
+ fprintf(stderr, " INIT: %u.%u\n", outarg.major, outarg.minor);
+ fprintf(stderr, " flags=0x%08x\n", outarg.flags);
+ fprintf(stderr, " max_readahead=0x%08x\n",
+ outarg.max_readahead);
+ fprintf(stderr, " max_write=0x%08x\n", outarg.max_write);
+ }
+
+ send_reply_ok(req, &outarg, arg->minor < 5 ? 8 : sizeof(outarg));
}
static void do_destroy(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
{
- struct fuse_ll *f = req->f;
+ struct fuse_ll *f = req->f;
- (void) nodeid;
- (void) inarg;
+ (void) nodeid;
+ (void) inarg;
- f->got_destroy = 1;
- if (f->op.destroy)
- f->op.destroy(f->userdata);
+ f->got_destroy = 1;
+ if (f->op.destroy)
+ f->op.destroy(f->userdata);
- send_reply_ok(req, NULL, 0);
+ send_reply_ok(req, NULL, 0);
}
void *fuse_req_userdata(fuse_req_t req)
{
- return req->f->userdata;
+ return req->f->userdata;
}
const struct fuse_ctx *fuse_req_ctx(fuse_req_t req)
{
- return &req->ctx;
+ return &req->ctx;
}
void fuse_req_interrupt_func(fuse_req_t req, fuse_interrupt_func_t func,
- void *data)
+ void *data)
{
- pthread_mutex_lock(&req->lock);
- req->u.ni.func = func;
- req->u.ni.data = data;
- if (req->interrupted && func)
- func(req, data);
- pthread_mutex_unlock(&req->lock);
+ pthread_mutex_lock(&req->lock);
+ req->u.ni.func = func;
+ req->u.ni.data = data;
+ if (req->interrupted && func)
+ func(req, data);
+ pthread_mutex_unlock(&req->lock);
}
int fuse_req_interrupted(fuse_req_t req)
{
- int interrupted;
+ int interrupted;
- pthread_mutex_lock(&req->f->lock);
- interrupted = req->interrupted;
- pthread_mutex_unlock(&req->f->lock);
+ pthread_mutex_lock(&req->f->lock);
+ interrupted = req->interrupted;
+ pthread_mutex_unlock(&req->f->lock);
- return interrupted;
+ return interrupted;
}
static struct {
- void (*func)(fuse_req_t, fuse_ino_t, const void *);
- const char *name;
+ void (*func)(fuse_req_t, fuse_ino_t, const void *);
+ const char *name;
} fuse_ll_ops[] = {
- [FUSE_LOOKUP] = { do_lookup, "LOOKUP" },
- [FUSE_FORGET] = { do_forget, "FORGET" },
- [FUSE_GETATTR] = { do_getattr, "GETATTR" },
- [FUSE_SETATTR] = { do_setattr, "SETATTR" },
- [FUSE_READLINK] = { do_readlink, "READLINK" },
- [FUSE_SYMLINK] = { do_symlink, "SYMLINK" },
- [FUSE_MKNOD] = { do_mknod, "MKNOD" },
- [FUSE_MKDIR] = { do_mkdir, "MKDIR" },
- [FUSE_UNLINK] = { do_unlink, "UNLINK" },
- [FUSE_RMDIR] = { do_rmdir, "RMDIR" },
- [FUSE_RENAME] = { do_rename, "RENAME" },
- [FUSE_LINK] = { do_link, "LINK" },
- [FUSE_OPEN] = { do_open, "OPEN" },
- [FUSE_READ] = { do_read, "READ" },
- [FUSE_WRITE] = { do_write, "WRITE" },
- [FUSE_STATFS] = { do_statfs, "STATFS" },
- [FUSE_RELEASE] = { do_release, "RELEASE" },
- [FUSE_FSYNC] = { do_fsync, "FSYNC" },
- [FUSE_SETXATTR] = { do_setxattr, "SETXATTR" },
- [FUSE_GETXATTR] = { do_getxattr, "GETXATTR" },
- [FUSE_LISTXATTR] = { do_listxattr, "LISTXATTR" },
- [FUSE_REMOVEXATTR] = { do_removexattr, "REMOVEXATTR" },
- [FUSE_FLUSH] = { do_flush, "FLUSH" },
- [FUSE_INIT] = { do_init, "INIT" },
- [FUSE_OPENDIR] = { do_opendir, "OPENDIR" },
- [FUSE_READDIR] = { do_readdir, "READDIR" },
- [FUSE_RELEASEDIR] = { do_releasedir, "RELEASEDIR" },
- [FUSE_FSYNCDIR] = { do_fsyncdir, "FSYNCDIR" },
- [FUSE_GETLK] = { do_getlk, "GETLK" },
- [FUSE_SETLK] = { do_setlk, "SETLK" },
- [FUSE_SETLKW] = { do_setlkw, "SETLKW" },
- [FUSE_ACCESS] = { do_access, "ACCESS" },
- [FUSE_CREATE] = { do_create, "CREATE" },
- [FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" },
- [FUSE_BMAP] = { do_bmap, "BMAP" },
- [FUSE_DESTROY] = { do_destroy, "DESTROY" },
+ [FUSE_LOOKUP] = { do_lookup, "LOOKUP" },
+ [FUSE_FORGET] = { do_forget, "FORGET" },
+ [FUSE_GETATTR] = { do_getattr, "GETATTR" },
+ [FUSE_SETATTR] = { do_setattr, "SETATTR" },
+ [FUSE_READLINK] = { do_readlink, "READLINK" },
+ [FUSE_SYMLINK] = { do_symlink, "SYMLINK" },
+ [FUSE_MKNOD] = { do_mknod, "MKNOD" },
+ [FUSE_MKDIR] = { do_mkdir, "MKDIR" },
+ [FUSE_UNLINK] = { do_unlink, "UNLINK" },
+ [FUSE_RMDIR] = { do_rmdir, "RMDIR" },
+ [FUSE_RENAME] = { do_rename, "RENAME" },
+ [FUSE_LINK] = { do_link, "LINK" },
+ [FUSE_OPEN] = { do_open, "OPEN" },
+ [FUSE_READ] = { do_read, "READ" },
+ [FUSE_WRITE] = { do_write, "WRITE" },
+ [FUSE_STATFS] = { do_statfs, "STATFS" },
+ [FUSE_RELEASE] = { do_release, "RELEASE" },
+ [FUSE_FSYNC] = { do_fsync, "FSYNC" },
+ [FUSE_SETXATTR] = { do_setxattr, "SETXATTR" },
+ [FUSE_GETXATTR] = { do_getxattr, "GETXATTR" },
+ [FUSE_LISTXATTR] = { do_listxattr, "LISTXATTR" },
+ [FUSE_REMOVEXATTR] = { do_removexattr, "REMOVEXATTR" },
+ [FUSE_FLUSH] = { do_flush, "FLUSH" },
+ [FUSE_INIT] = { do_init, "INIT" },
+ [FUSE_OPENDIR] = { do_opendir, "OPENDIR" },
+ [FUSE_READDIR] = { do_readdir, "READDIR" },
+ [FUSE_RELEASEDIR] = { do_releasedir, "RELEASEDIR" },
+ [FUSE_FSYNCDIR] = { do_fsyncdir, "FSYNCDIR" },
+ [FUSE_GETLK] = { do_getlk, "GETLK" },
+ [FUSE_SETLK] = { do_setlk, "SETLK" },
+ [FUSE_SETLKW] = { do_setlkw, "SETLKW" },
+ [FUSE_ACCESS] = { do_access, "ACCESS" },
+ [FUSE_CREATE] = { do_create, "CREATE" },
+ [FUSE_INTERRUPT] = { do_interrupt, "INTERRUPT" },
+ [FUSE_BMAP] = { do_bmap, "BMAP" },
+ [FUSE_DESTROY] = { do_destroy, "DESTROY" },
};
#define FUSE_MAXOP (sizeof(fuse_ll_ops) / sizeof(fuse_ll_ops[0]))
static const char *opname(enum fuse_opcode opcode)
{
- if (opcode >= FUSE_MAXOP || !fuse_ll_ops[opcode].name)
- return "???";
- else
- return fuse_ll_ops[opcode].name;
+ if (opcode >= FUSE_MAXOP || !fuse_ll_ops[opcode].name)
+ return "???";
+ else
+ return fuse_ll_ops[opcode].name;
}
static void fuse_ll_process(void *data, const char *buf, size_t len,
- struct fuse_chan *ch)
-{
- struct fuse_ll *f = (struct fuse_ll *) data;
- struct fuse_in_header *in = (struct fuse_in_header *) buf;
- const void *inarg = buf + sizeof(struct fuse_in_header);
- struct fuse_req *req;
-
- if (f->debug)
- fprintf(stderr, "unique: %llu, opcode: %s (%i), nodeid: %lu, insize: %zu\n",
- (unsigned long long) in->unique,
- opname((enum fuse_opcode) in->opcode), in->opcode,
- (unsigned long) in->nodeid, len);
-
- req = (struct fuse_req *) calloc(1, sizeof(struct fuse_req));
- if (req == NULL) {
- fprintf(stderr, "fuse: failed to allocate request\n");
- return;
- }
-
- req->f = f;
- req->unique = in->unique;
- req->ctx.uid = in->uid;
- req->ctx.gid = in->gid;
- req->ctx.pid = in->pid;
- req->ch = ch;
- req->ctr = 1;
- list_init_req(req);
- fuse_mutex_init(&req->lock);
-
- if (!f->got_init && in->opcode != FUSE_INIT)
- fuse_reply_err(req, EIO);
- else if (f->allow_root && in->uid != f->owner && in->uid != 0 &&
- in->opcode != FUSE_INIT && in->opcode != FUSE_READ &&
- in->opcode != FUSE_WRITE && in->opcode != FUSE_FSYNC &&
- in->opcode != FUSE_RELEASE && in->opcode != FUSE_READDIR &&
- in->opcode != FUSE_FSYNCDIR && in->opcode != FUSE_RELEASEDIR) {
- fuse_reply_err(req, EACCES);
- } else if (in->opcode >= FUSE_MAXOP || !fuse_ll_ops[in->opcode].func)
- fuse_reply_err(req, ENOSYS);
- else {
- if (in->opcode != FUSE_INTERRUPT) {
- struct fuse_req *intr;
- pthread_mutex_lock(&f->lock);
- intr = check_interrupt(f, req);
- list_add_req(req, &f->list);
- pthread_mutex_unlock(&f->lock);
- if (intr)
- fuse_reply_err(intr, EAGAIN);
- }
- fuse_ll_ops[in->opcode].func(req, in->nodeid, inarg);
- }
+ struct fuse_chan *ch)
+{
+ struct fuse_ll *f = (struct fuse_ll *) data;
+ struct fuse_in_header *in = (struct fuse_in_header *) buf;
+ const void *inarg = buf + sizeof(struct fuse_in_header);
+ struct fuse_req *req;
+
+ if (f->debug)
+ fprintf(stderr,
+ "unique: %llu, opcode: %s (%i), nodeid: %lu, insize: %zu\n",
+ (unsigned long long) in->unique,
+ opname((enum fuse_opcode) in->opcode), in->opcode,
+ (unsigned long) in->nodeid, len);
+
+ req = (struct fuse_req *) calloc(1, sizeof(struct fuse_req));
+ if (req == NULL) {
+ fprintf(stderr, "fuse: failed to allocate request\n");
+ return;
+ }
+
+ req->f = f;
+ req->unique = in->unique;
+ req->ctx.uid = in->uid;
+ req->ctx.gid = in->gid;
+ req->ctx.pid = in->pid;
+ req->ch = ch;
+ req->ctr = 1;
+ list_init_req(req);
+ fuse_mutex_init(&req->lock);
+
+ if (!f->got_init && in->opcode != FUSE_INIT)
+ fuse_reply_err(req, EIO);
+ else if (f->allow_root && in->uid != f->owner && in->uid != 0 &&
+ in->opcode != FUSE_INIT && in->opcode != FUSE_READ &&
+ in->opcode != FUSE_WRITE && in->opcode != FUSE_FSYNC &&
+ in->opcode != FUSE_RELEASE && in->opcode != FUSE_READDIR &&
+ in->opcode != FUSE_FSYNCDIR && in->opcode != FUSE_RELEASEDIR) {
+ fuse_reply_err(req, EACCES);
+ } else if (in->opcode >= FUSE_MAXOP || !fuse_ll_ops[in->opcode].func)
+ fuse_reply_err(req, ENOSYS);
+ else {
+ if (in->opcode != FUSE_INTERRUPT) {
+ struct fuse_req *intr;
+ pthread_mutex_lock(&f->lock);
+ intr = check_interrupt(f, req);
+ list_add_req(req, &f->list);
+ pthread_mutex_unlock(&f->lock);
+ if (intr)
+ fuse_reply_err(intr, EAGAIN);
+ }
+ fuse_ll_ops[in->opcode].func(req, in->nodeid, inarg);
+ }
}
enum {
- KEY_HELP,
- KEY_VERSION,
+ KEY_HELP,
+ KEY_VERSION,
};
static struct fuse_opt fuse_ll_opts[] = {
- { "debug", offsetof(struct fuse_ll, debug), 1 },
- { "-d", offsetof(struct fuse_ll, debug), 1 },
- { "allow_root", offsetof(struct fuse_ll, allow_root), 1 },
- { "max_write=%u", offsetof(struct fuse_ll, conn.max_write), 0 },
- { "max_readahead=%u", offsetof(struct fuse_ll, conn.max_readahead), 0 },
- { "async_read", offsetof(struct fuse_ll, conn.async_read), 1 },
- { "sync_read", offsetof(struct fuse_ll, conn.async_read), 0 },
- FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_DISCARD),
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("-V", KEY_VERSION),
- FUSE_OPT_KEY("--version", KEY_VERSION),
- FUSE_OPT_END
+ { "debug", offsetof(struct fuse_ll, debug), 1 },
+ { "-d", offsetof(struct fuse_ll, debug), 1 },
+ { "allow_root", offsetof(struct fuse_ll, allow_root), 1 },
+ { "max_write=%u", offsetof(struct fuse_ll, conn.max_write), 0 },
+ { "max_readahead=%u", offsetof(struct fuse_ll, conn.max_readahead), 0 },
+ { "async_read", offsetof(struct fuse_ll, conn.async_read), 1 },
+ { "sync_read", offsetof(struct fuse_ll, conn.async_read), 0 },
+ FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_DISCARD),
+ FUSE_OPT_KEY("-h", KEY_HELP),
+ FUSE_OPT_KEY("--help", KEY_HELP),
+ FUSE_OPT_KEY("-V", KEY_VERSION),
+ FUSE_OPT_KEY("--version", KEY_VERSION),
+ FUSE_OPT_END
};
static void fuse_ll_version(void)
{
- fprintf(stderr, "using FUSE kernel interface version %i.%i\n",
- FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
+ fprintf(stderr, "using FUSE kernel interface version %i.%i\n",
+ FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);
}
static void fuse_ll_help(void)
{
- fprintf(stderr,
-" -o max_write=N set maximum size of write requests\n"
-" -o max_readahead=N set maximum readahead\n"
-" -o async_read perform reads asynchronously (default)\n"
-" -o sync_read perform reads synchronously\n");
+ fprintf(stderr,
+" -o max_write=N set maximum size of write requests\n"
+" -o max_readahead=N set maximum readahead\n"
+" -o async_read perform reads asynchronously (default)\n"
+" -o sync_read perform reads synchronously\n");
}
static int fuse_ll_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- (void) data; (void) outargs;
+ (void) data; (void) outargs;
- switch (key) {
- case KEY_HELP:
- fuse_ll_help();
- break;
+ switch (key) {
+ case KEY_HELP:
+ fuse_ll_help();
+ break;
- case KEY_VERSION:
- fuse_ll_version();
- break;
+ case KEY_VERSION:
+ fuse_ll_version();
+ break;
- default:
- fprintf(stderr, "fuse: unknown option `%s'\n", arg);
- }
+ default:
+ fprintf(stderr, "fuse: unknown option `%s'\n", arg);
+ }
- return -1;
+ return -1;
}
int fuse_lowlevel_is_lib_option(const char *opt)
{
- return fuse_opt_match(fuse_ll_opts, opt);
+ return fuse_opt_match(fuse_ll_opts, opt);
}
static void fuse_ll_destroy(void *data)
{
- struct fuse_ll *f = (struct fuse_ll *) data;
+ struct fuse_ll *f = (struct fuse_ll *) data;
- if (f->got_init && !f->got_destroy) {
- if (f->op.destroy)
- f->op.destroy(f->userdata);
- }
+ if (f->got_init && !f->got_destroy) {
+ if (f->op.destroy)
+ f->op.destroy(f->userdata);
+ }
- pthread_mutex_destroy(&f->lock);
- free(f);
+ pthread_mutex_destroy(&f->lock);
+ free(f);
}
/*
@@ -1255,158 +1264,158 @@ static void fuse_ll_destroy(void *data)
* version of a symbol to internal references.
*/
struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args,
- const struct fuse_lowlevel_ops *op,
- size_t op_size, void *userdata)
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size, void *userdata)
{
- struct fuse_ll *f;
- struct fuse_session *se;
- struct fuse_session_ops sop = {
- .process = fuse_ll_process,
- .destroy = fuse_ll_destroy,
- };
+ struct fuse_ll *f;
+ struct fuse_session *se;
+ struct fuse_session_ops sop = {
+ .process = fuse_ll_process,
+ .destroy = fuse_ll_destroy,
+ };
- if (sizeof(struct fuse_lowlevel_ops) < op_size) {
- fprintf(stderr, "fuse: warning: library too old, some operations may not work\n");
- op_size = sizeof(struct fuse_lowlevel_ops);
- }
+ if (sizeof(struct fuse_lowlevel_ops) < op_size) {
+ fprintf(stderr, "fuse: warning: library too old, some operations may not work\n");
+ op_size = sizeof(struct fuse_lowlevel_ops);
+ }
- f = (struct fuse_ll *) calloc(1, sizeof(struct fuse_ll));
- if (f == NULL) {
- fprintf(stderr, "fuse: failed to allocate fuse object\n");
- goto out;
- }
+ f = (struct fuse_ll *) calloc(1, sizeof(struct fuse_ll));
+ if (f == NULL) {
+ fprintf(stderr, "fuse: failed to allocate fuse object\n");
+ goto out;
+ }
- f->conn.async_read = 1;
- f->conn.max_write = UINT_MAX;
- f->conn.max_readahead = UINT_MAX;
- list_init_req(&f->list);
- list_init_req(&f->interrupts);
- fuse_mutex_init(&f->lock);
+ f->conn.async_read = 1;
+ f->conn.max_write = UINT_MAX;
+ f->conn.max_readahead = UINT_MAX;
+ list_init_req(&f->list);
+ list_init_req(&f->interrupts);
+ fuse_mutex_init(&f->lock);
- if (fuse_opt_parse(args, f, fuse_ll_opts, fuse_ll_opt_proc) == -1)
- goto out_free;
+ if (fuse_opt_parse(args, f, fuse_ll_opts, fuse_ll_opt_proc) == -1)
+ goto out_free;
- memcpy(&f->op, op, op_size);
- f->owner = getuid();
- f->userdata = userdata;
+ memcpy(&f->op, op, op_size);
+ f->owner = getuid();
+ f->userdata = userdata;
- se = fuse_session_new(&sop, f);
- if (!se)
- goto out_free;
+ se = fuse_session_new(&sop, f);
+ if (!se)
+ goto out_free;
- return se;
+ return se;
- out_free:
- free(f);
- out:
- return NULL;
+out_free:
+ free(f);
+out:
+ return NULL;
}
struct fuse_session *fuse_lowlevel_new(struct fuse_args *args,
- const struct fuse_lowlevel_ops *op,
- size_t op_size, void *userdata)
+ const struct fuse_lowlevel_ops *op,
+ size_t op_size, void *userdata)
{
- return fuse_lowlevel_new_common(args, op, op_size, userdata);
+ return fuse_lowlevel_new_common(args, op, op_size, userdata);
}
#ifndef __FreeBSD__
static void fill_open_compat(struct fuse_open_out *arg,
- const struct fuse_file_info_compat *f)
+ const struct fuse_file_info_compat *f)
{
- arg->fh = f->fh;
- if (f->direct_io)
- arg->open_flags |= FOPEN_DIRECT_IO;
- if (f->keep_cache)
- arg->open_flags |= FOPEN_KEEP_CACHE;
+ arg->fh = f->fh;
+ if (f->direct_io)
+ arg->open_flags |= FOPEN_DIRECT_IO;
+ if (f->keep_cache)
+ arg->open_flags |= FOPEN_KEEP_CACHE;
}
static void convert_statfs_compat(const struct statfs *compatbuf,
- struct statvfs *buf)
+ struct statvfs *buf)
{
- buf->f_bsize = compatbuf->f_bsize;
- buf->f_blocks = compatbuf->f_blocks;
- buf->f_bfree = compatbuf->f_bfree;
- buf->f_bavail = compatbuf->f_bavail;
- buf->f_files = compatbuf->f_files;
- buf->f_ffree = compatbuf->f_ffree;
- buf->f_namemax = compatbuf->f_namelen;
+ buf->f_bsize = compatbuf->f_bsize;
+ buf->f_blocks = compatbuf->f_blocks;
+ buf->f_bfree = compatbuf->f_bfree;
+ buf->f_bavail = compatbuf->f_bavail;
+ buf->f_files = compatbuf->f_files;
+ buf->f_ffree = compatbuf->f_ffree;
+ buf->f_namemax = compatbuf->f_namelen;
}
int fuse_reply_open_compat(fuse_req_t req,
- const struct fuse_file_info_compat *f)
+ const struct fuse_file_info_compat *f)
{
- struct fuse_open_out arg;
+ struct fuse_open_out arg;
- memset(&arg, 0, sizeof(arg));
- fill_open_compat(&arg, f);
- return send_reply_ok(req, &arg, sizeof(arg));
+ memset(&arg, 0, sizeof(arg));
+ fill_open_compat(&arg, f);
+ return send_reply_ok(req, &arg, sizeof(arg));
}
int fuse_reply_statfs_compat(fuse_req_t req, const struct statfs *stbuf)
{
- struct statvfs newbuf;
+ struct statvfs newbuf;
- memset(&newbuf, 0, sizeof(newbuf));
- convert_statfs_compat(stbuf, &newbuf);
+ memset(&newbuf, 0, sizeof(newbuf));
+ convert_statfs_compat(stbuf, &newbuf);
- return fuse_reply_statfs(req, &newbuf);
+ return fuse_reply_statfs(req, &newbuf);
}
struct fuse_session *fuse_lowlevel_new_compat(const char *opts,
- const struct fuse_lowlevel_ops_compat *op,
- size_t op_size, void *userdata)
+ const struct fuse_lowlevel_ops_compat *op,
+ size_t op_size, void *userdata)
{
- struct fuse_session *se;
- struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
+ struct fuse_session *se;
+ struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
- if (opts &&
- (fuse_opt_add_arg(&args, "") == -1 ||
- fuse_opt_add_arg(&args, "-o") == -1 ||
- fuse_opt_add_arg(&args, opts) == -1)) {
- fuse_opt_free_args(&args);
- return NULL;
- }
- se = fuse_lowlevel_new(&args, (const struct fuse_lowlevel_ops *) op,
- op_size, userdata);
- fuse_opt_free_args(&args);
+ if (opts &&
+ (fuse_opt_add_arg(&args, "") == -1 ||
+ fuse_opt_add_arg(&args, "-o") == -1 ||
+ fuse_opt_add_arg(&args, opts) == -1)) {
+ fuse_opt_free_args(&args);
+ return NULL;
+ }
+ se = fuse_lowlevel_new(&args, (const struct fuse_lowlevel_ops *) op,
+ op_size, userdata);
+ fuse_opt_free_args(&args);
- return se;
+ return se;
}
struct fuse_ll_compat_conf {
- unsigned max_read;
- int set_max_read;
+ unsigned max_read;
+ int set_max_read;
};
static const struct fuse_opt fuse_ll_opts_compat[] = {
- { "max_read=", offsetof(struct fuse_ll_compat_conf, set_max_read), 1 },
- { "max_read=%u", offsetof(struct fuse_ll_compat_conf, max_read), 0 },
- FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_END
+ { "max_read=", offsetof(struct fuse_ll_compat_conf, set_max_read), 1 },
+ { "max_read=%u", offsetof(struct fuse_ll_compat_conf, max_read), 0 },
+ FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_END
};
int fuse_sync_compat_args(struct fuse_args *args)
{
- struct fuse_ll_compat_conf conf;
+ struct fuse_ll_compat_conf conf;
- memset(&conf, 0, sizeof(conf));
- if (fuse_opt_parse(args, &conf, fuse_ll_opts_compat, NULL) == -1)
- return -1;
+ memset(&conf, 0, sizeof(conf));
+ if (fuse_opt_parse(args, &conf, fuse_ll_opts_compat, NULL) == -1)
+ return -1;
- if (fuse_opt_insert_arg(args, 1, "-osync_read"))
- return -1;
+ if (fuse_opt_insert_arg(args, 1, "-osync_read"))
+ return -1;
- if (conf.set_max_read) {
- char tmpbuf[64];
+ if (conf.set_max_read) {
+ char tmpbuf[64];
- sprintf(tmpbuf, "-omax_readahead=%u", conf.max_read);
- if (fuse_opt_insert_arg(args, 1, tmpbuf) == -1)
- return -1;
- }
- return 0;
+ sprintf(tmpbuf, "-omax_readahead=%u", conf.max_read);
+ if (fuse_opt_insert_arg(args, 1, tmpbuf) == -1)
+ return -1;
+ }
+ return 0;
}
FUSE_SYMVER(".symver fuse_reply_statfs_compat,fuse_reply_statfs@FUSE_2.4");
@@ -1417,22 +1426,22 @@ FUSE_SYMVER(".symver fuse_lowlevel_new_compat,fuse_lowlevel_new@FUSE_2.4");
int fuse_sync_compat_args(struct fuse_args *args)
{
- (void) args;
- return 0;
+ (void) args;
+ return 0;
}
#endif /* __FreeBSD__ */
struct fuse_session *fuse_lowlevel_new_compat25(struct fuse_args *args,
- const struct fuse_lowlevel_ops_compat25 *op,
- size_t op_size, void *userdata)
+ const struct fuse_lowlevel_ops_compat25 *op,
+ size_t op_size, void *userdata)
{
- if (fuse_sync_compat_args(args) == -1)
- return NULL;
+ if (fuse_sync_compat_args(args) == -1)
+ return NULL;
- return fuse_lowlevel_new_common(args,
- (const struct fuse_lowlevel_ops *) op,
- op_size, userdata);
+ return fuse_lowlevel_new_common(args,
+ (const struct fuse_lowlevel_ops *) op,
+ op_size, userdata);
}
FUSE_SYMVER(".symver fuse_lowlevel_new_compat25,fuse_lowlevel_new@FUSE_2.5");
diff --git a/lib/fuse_misc.h b/lib/fuse_misc.h
index 4f5236a..c2cfee1 100644
--- a/lib/fuse_misc.h
+++ b/lib/fuse_misc.h
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "config.h"
@@ -22,11 +22,11 @@
/* Is this hack still needed? */
static inline void fuse_mutex_init(pthread_mutex_t *mut)
{
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
- pthread_mutex_init(mut, &attr);
- pthread_mutexattr_destroy(&attr);
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
+ pthread_mutex_init(mut, &attr);
+ pthread_mutexattr_destroy(&attr);
}
#endif
diff --git a/lib/fuse_mt.c b/lib/fuse_mt.c
index cbdc1a3..95c3a5c 100644
--- a/lib/fuse_mt.c
+++ b/lib/fuse_mt.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "fuse_i.h"
@@ -17,100 +17,100 @@
#include <assert.h>
struct procdata {
- struct fuse *f;
- struct fuse_chan *prevch;
- struct fuse_session *prevse;
- fuse_processor_t proc;
- void *data;
+ struct fuse *f;
+ struct fuse_chan *prevch;
+ struct fuse_session *prevse;
+ fuse_processor_t proc;
+ void *data;
};
static void mt_session_proc(void *data, const char *buf, size_t len,
- struct fuse_chan *ch)
+ struct fuse_chan *ch)
{
- struct procdata *pd = (struct procdata *) data;
- struct fuse_cmd *cmd = *(struct fuse_cmd **) buf;
+ struct procdata *pd = (struct procdata *) data;
+ struct fuse_cmd *cmd = *(struct fuse_cmd **) buf;
- (void) len;
- (void) ch;
- pd->proc(pd->f, cmd, pd->data);
+ (void) len;
+ (void) ch;
+ pd->proc(pd->f, cmd, pd->data);
}
static void mt_session_exit(void *data, int val)
{
- struct procdata *pd = (struct procdata *) data;
- if (val)
- fuse_session_exit(pd->prevse);
- else
- fuse_session_reset(pd->prevse);
+ struct procdata *pd = (struct procdata *) data;
+ if (val)
+ fuse_session_exit(pd->prevse);
+ else
+ fuse_session_reset(pd->prevse);
}
static int mt_session_exited(void *data)
{
- struct procdata *pd = (struct procdata *) data;
- return fuse_session_exited(pd->prevse);
+ struct procdata *pd = (struct procdata *) data;
+ return fuse_session_exited(pd->prevse);
}
static int mt_chan_receive(struct fuse_chan **chp, char *buf, size_t size)
{
- struct fuse_cmd *cmd;
- struct procdata *pd = (struct procdata *) fuse_chan_data(*chp);
+ struct fuse_cmd *cmd;
+ struct procdata *pd = (struct procdata *) fuse_chan_data(*chp);
- assert(size >= sizeof(cmd));
+ assert(size >= sizeof(cmd));
- cmd = fuse_read_cmd(pd->f);
- if (cmd == NULL)
- return 0;
+ cmd = fuse_read_cmd(pd->f);
+ if (cmd == NULL)
+ return 0;
- *(struct fuse_cmd **) buf = cmd;
+ *(struct fuse_cmd **) buf = cmd;
- return sizeof(cmd);
+ return sizeof(cmd);
}
int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data)
{
- int res;
- struct procdata pd;
- struct fuse_session *prevse = fuse_get_session(f);
- struct fuse_session *se;
- struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL);
- struct fuse_chan *ch;
- struct fuse_session_ops sop = {
- .exit = mt_session_exit,
- .exited = mt_session_exited,
- .process = mt_session_proc,
- };
- struct fuse_chan_ops cop = {
- .receive = mt_chan_receive,
- };
-
- pd.f = f;
- pd.prevch = prevch;
- pd.prevse = prevse;
- pd.proc = proc;
- pd.data = data;
-
- se = fuse_session_new(&sop, &pd);
- if (se == NULL)
- return -1;
-
- ch = fuse_chan_new(&cop, fuse_chan_fd(prevch), sizeof(struct fuse_cmd *),
- &pd);
- if (ch == NULL) {
- fuse_session_destroy(se);
- return -1;
- }
- fuse_session_add_chan(se, ch);
- res = fuse_session_loop_mt(se);
- fuse_session_destroy(se);
- return res;
+ int res;
+ struct procdata pd;
+ struct fuse_session *prevse = fuse_get_session(f);
+ struct fuse_session *se;
+ struct fuse_chan *prevch = fuse_session_next_chan(prevse, NULL);
+ struct fuse_chan *ch;
+ struct fuse_session_ops sop = {
+ .exit = mt_session_exit,
+ .exited = mt_session_exited,
+ .process = mt_session_proc,
+ };
+ struct fuse_chan_ops cop = {
+ .receive = mt_chan_receive,
+ };
+
+ pd.f = f;
+ pd.prevch = prevch;
+ pd.prevse = prevse;
+ pd.proc = proc;
+ pd.data = data;
+
+ se = fuse_session_new(&sop, &pd);
+ if (se == NULL)
+ return -1;
+
+ ch = fuse_chan_new(&cop, fuse_chan_fd(prevch),
+ sizeof(struct fuse_cmd *), &pd);
+ if (ch == NULL) {
+ fuse_session_destroy(se);
+ return -1;
+ }
+ fuse_session_add_chan(se, ch);
+ res = fuse_session_loop_mt(se);
+ fuse_session_destroy(se);
+ return res;
}
int fuse_loop_mt(struct fuse *f)
{
- if (f == NULL)
- return -1;
+ if (f == NULL)
+ return -1;
- return fuse_session_loop_mt(fuse_get_session(f));
+ return fuse_session_loop_mt(fuse_get_session(f));
}
FUSE_SYMVER(".symver fuse_loop_mt_proc,__fuse_loop_mt@");
diff --git a/lib/fuse_opt.c b/lib/fuse_opt.c
index d10e624..8a9019b 100644
--- a/lib/fuse_opt.c
+++ b/lib/fuse_opt.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse_opt.h"
@@ -15,71 +15,71 @@
#include <assert.h>
struct fuse_opt_context {
- void *data;
- const struct fuse_opt *opt;
- fuse_opt_proc_t proc;
- int argctr;
- int argc;
- char **argv;
- struct fuse_args outargs;
- char *opts;
- int nonopt;
+ void *data;
+ const struct fuse_opt *opt;
+ fuse_opt_proc_t proc;
+ int argctr;
+ int argc;
+ char **argv;
+ struct fuse_args outargs;
+ char *opts;
+ int nonopt;
};
void fuse_opt_free_args(struct fuse_args *args)
{
- if (args) {
- if (args->argv && args->allocated) {
- int i;
- for (i = 0; i < args->argc; i++)
- free(args->argv[i]);
- free(args->argv);
- }
- args->argc = 0;
- args->argv = NULL;
- args->allocated = 0;
- }
+ if (args) {
+ if (args->argv && args->allocated) {
+ int i;
+ for (i = 0; i < args->argc; i++)
+ free(args->argv[i]);
+ free(args->argv);
+ }
+ args->argc = 0;
+ args->argv = NULL;
+ args->allocated = 0;
+ }
}
static int alloc_failed(void)
{
- fprintf(stderr, "fuse: memory allocation failed\n");
- return -1;
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ return -1;
}
int fuse_opt_add_arg(struct fuse_args *args, const char *arg)
{
- char **newargv;
- char *newarg;
+ char **newargv;
+ char *newarg;
- assert(!args->argv || args->allocated);
+ assert(!args->argv || args->allocated);
- newargv = realloc(args->argv, (args->argc + 2) * sizeof(char *));
- newarg = newargv ? strdup(arg) : NULL;
- if (!newargv || !newarg)
- return alloc_failed();
+ newargv = realloc(args->argv, (args->argc + 2) * sizeof(char *));
+ newarg = newargv ? strdup(arg) : NULL;
+ if (!newargv || !newarg)
+ return alloc_failed();
- args->argv = newargv;
- args->allocated = 1;
- args->argv[args->argc++] = newarg;
- args->argv[args->argc] = NULL;
- return 0;
+ args->argv = newargv;
+ args->allocated = 1;
+ args->argv[args->argc++] = newarg;
+ args->argv[args->argc] = NULL;
+ return 0;
}
static int fuse_opt_insert_arg_common(struct fuse_args *args, int pos,
const char *arg)
{
- assert(pos <= args->argc);
- if (fuse_opt_add_arg(args, arg) == -1)
- return -1;
-
- if (pos != args->argc - 1) {
- char *newarg = args->argv[args->argc - 1];
- memmove(&args->argv[pos + 1], &args->argv[pos],
- sizeof(char *) * (args->argc - pos - 1));
- args->argv[pos] = newarg;
- }
- return 0;
+ assert(pos <= args->argc);
+ if (fuse_opt_add_arg(args, arg) == -1)
+ return -1;
+
+ if (pos != args->argc - 1) {
+ char *newarg = args->argv[args->argc - 1];
+ memmove(&args->argv[pos + 1], &args->argv[pos],
+ sizeof(char *) * (args->argc - pos - 1));
+ args->argv[pos] = newarg;
+ }
+ return 0;
}
int fuse_opt_insert_arg(struct fuse_args *args, int pos, const char *arg)
@@ -96,288 +96,290 @@ int fuse_opt_insert_arg_compat(struct fuse_args *args, int pos, const char *arg)
static int next_arg(struct fuse_opt_context *ctx, const char *opt)
{
- if (ctx->argctr + 1 >= ctx->argc) {
- fprintf(stderr, "fuse: missing argument after `%s'\n", opt);
- return -1;
- }
- ctx->argctr++;
- return 0;
+ if (ctx->argctr + 1 >= ctx->argc) {
+ fprintf(stderr, "fuse: missing argument after `%s'\n", opt);
+ return -1;
+ }
+ ctx->argctr++;
+ return 0;
}
static int add_arg(struct fuse_opt_context *ctx, const char *arg)
{
- return fuse_opt_add_arg(&ctx->outargs, arg);
+ return fuse_opt_add_arg(&ctx->outargs, arg);
}
int fuse_opt_add_opt(char **opts, const char *opt)
{
- char *newopts;
- if (!*opts)
- newopts = strdup(opt);
- else {
- unsigned oldlen = strlen(*opts);
- newopts = realloc(*opts, oldlen + 1 + strlen(opt) + 1);
- if (newopts) {
- newopts[oldlen] = ',';
- strcpy(newopts + oldlen + 1, opt);
- }
- }
- if (!newopts)
- return alloc_failed();
-
- *opts = newopts;
- return 0;
+ char *newopts;
+ if (!*opts)
+ newopts = strdup(opt);
+ else {
+ unsigned oldlen = strlen(*opts);
+ newopts = realloc(*opts, oldlen + 1 + strlen(opt) + 1);
+ if (newopts) {
+ newopts[oldlen] = ',';
+ strcpy(newopts + oldlen + 1, opt);
+ }
+ }
+ if (!newopts)
+ return alloc_failed();
+
+ *opts = newopts;
+ return 0;
}
static int add_opt(struct fuse_opt_context *ctx, const char *opt)
{
- return fuse_opt_add_opt(&ctx->opts, opt);
+ return fuse_opt_add_opt(&ctx->opts, opt);
}
static int call_proc(struct fuse_opt_context *ctx, const char *arg, int key,
- int iso)
+ int iso)
{
- if (key == FUSE_OPT_KEY_DISCARD)
- return 0;
-
- if (key != FUSE_OPT_KEY_KEEP && ctx->proc) {
- int res = ctx->proc(ctx->data, arg, key, &ctx->outargs);
- if (res == -1 || !res)
- return res;
- }
- if (iso)
- return add_opt(ctx, arg);
- else
- return add_arg(ctx, arg);
+ if (key == FUSE_OPT_KEY_DISCARD)
+ return 0;
+
+ if (key != FUSE_OPT_KEY_KEEP && ctx->proc) {
+ int res = ctx->proc(ctx->data, arg, key, &ctx->outargs);
+ if (res == -1 || !res)
+ return res;
+ }
+ if (iso)
+ return add_opt(ctx, arg);
+ else
+ return add_arg(ctx, arg);
}
static int match_template(const char *t, const char *arg, unsigned *sepp)
{
- int arglen = strlen(arg);
- const char *sep = strchr(t, '=');
- sep = sep ? sep : strchr(t, ' ');
- if (sep && (!sep[1] || sep[1] == '%')) {
- int tlen = sep - t;
- if (sep[0] == '=')
- tlen ++;
- if (arglen >= tlen && strncmp(arg, t, tlen) == 0) {
- *sepp = sep - t;
- return 1;
- }
- }
- if (strcmp(t, arg) == 0) {
- *sepp = 0;
- return 1;
- }
- return 0;
+ int arglen = strlen(arg);
+ const char *sep = strchr(t, '=');
+ sep = sep ? sep : strchr(t, ' ');
+ if (sep && (!sep[1] || sep[1] == '%')) {
+ int tlen = sep - t;
+ if (sep[0] == '=')
+ tlen ++;
+ if (arglen >= tlen && strncmp(arg, t, tlen) == 0) {
+ *sepp = sep - t;
+ return 1;
+ }
+ }
+ if (strcmp(t, arg) == 0) {
+ *sepp = 0;
+ return 1;
+ }
+ return 0;
}
static const struct fuse_opt *find_opt(const struct fuse_opt *opt,
- const char *arg, unsigned *sepp)
+ const char *arg, unsigned *sepp)
{
- for (; opt && opt->templ; opt++)
- if (match_template(opt->templ, arg, sepp))
- return opt;
- return NULL;
+ for (; opt && opt->templ; opt++)
+ if (match_template(opt->templ, arg, sepp))
+ return opt;
+ return NULL;
}
int fuse_opt_match(const struct fuse_opt *opts, const char *opt)
{
- unsigned dummy;
- return find_opt(opts, opt, &dummy) ? 1 : 0;
+ unsigned dummy;
+ return find_opt(opts, opt, &dummy) ? 1 : 0;
}
static int process_opt_param(void *var, const char *format, const char *param,
- const char *arg)
+ const char *arg)
{
- assert(format[0] == '%');
- if (format[1] == 's') {
- char *copy = strdup(param);
- if (!copy)
- return alloc_failed();
-
- *(char **) var = copy;
- } else {
- if (sscanf(param, format, var) != 1) {
- fprintf(stderr, "fuse: invalid parameter in option `%s'\n", arg);
- return -1;
- }
- }
- return 0;
+ assert(format[0] == '%');
+ if (format[1] == 's') {
+ char *copy = strdup(param);
+ if (!copy)
+ return alloc_failed();
+
+ *(char **) var = copy;
+ } else {
+ if (sscanf(param, format, var) != 1) {
+ fprintf(stderr, "fuse: invalid parameter in option `%s'\n", arg);
+ return -1;
+ }
+ }
+ return 0;
}
static int process_opt(struct fuse_opt_context *ctx,
- const struct fuse_opt *opt, unsigned sep,
- const char *arg, int iso)
+ const struct fuse_opt *opt, unsigned sep,
+ const char *arg, int iso)
{
- if (opt->offset == -1U) {
- if (call_proc(ctx, arg, opt->value, iso) == -1)
- return -1;
- } else {
- void *var = ctx->data + opt->offset;
- if (sep && opt->templ[sep + 1]) {
- const char *param = arg + sep;
- if (opt->templ[sep] == '=')
- param ++;
- if (process_opt_param(var, opt->templ + sep + 1,
- param, arg) == -1)
- return -1;
- } else
- *(int *)var = opt->value;
- }
- return 0;
+ if (opt->offset == -1U) {
+ if (call_proc(ctx, arg, opt->value, iso) == -1)
+ return -1;
+ } else {
+ void *var = ctx->data + opt->offset;
+ if (sep && opt->templ[sep + 1]) {
+ const char *param = arg + sep;
+ if (opt->templ[sep] == '=')
+ param ++;
+ if (process_opt_param(var, opt->templ + sep + 1,
+ param, arg) == -1)
+ return -1;
+ } else
+ *(int *)var = opt->value;
+ }
+ return 0;
}
static int process_opt_sep_arg(struct fuse_opt_context *ctx,
- const struct fuse_opt *opt, unsigned sep,
- const char *arg, int iso)
+ const struct fuse_opt *opt, unsigned sep,
+ const char *arg, int iso)
{
- int res;
- char *newarg;
- char *param;
+ int res;
+ char *newarg;
+ char *param;
- if (next_arg(ctx, arg) == -1)
- return -1;
+ if (next_arg(ctx, arg) == -1)
+ return -1;
- param = ctx->argv[ctx->argctr];
- newarg = malloc(sep + strlen(param) + 1);
- if (!newarg)
- return alloc_failed();
+ param = ctx->argv[ctx->argctr];
+ newarg = malloc(sep + strlen(param) + 1);
+ if (!newarg)
+ return alloc_failed();
- memcpy(newarg, arg, sep);
- strcpy(newarg + sep, param);
- res = process_opt(ctx, opt, sep, newarg, iso);
- free(newarg);
+ memcpy(newarg, arg, sep);
+ strcpy(newarg + sep, param);
+ res = process_opt(ctx, opt, sep, newarg, iso);
+ free(newarg);
- return res;
+ return res;
}
static int process_gopt(struct fuse_opt_context *ctx, const char *arg, int iso)
{
- unsigned sep;
- const struct fuse_opt *opt = find_opt(ctx->opt, arg, &sep);
- if (opt) {
- for (; opt; opt = find_opt(opt + 1, arg, &sep)) {
- int res;
- if (sep && opt->templ[sep] == ' ' && !arg[sep])
- res = process_opt_sep_arg(ctx, opt, sep, arg, iso);
- else
- res = process_opt(ctx, opt, sep, arg, iso);
- if (res == -1)
- return -1;
- }
- return 0;
- } else
- return call_proc(ctx, arg, FUSE_OPT_KEY_OPT, iso);
+ unsigned sep;
+ const struct fuse_opt *opt = find_opt(ctx->opt, arg, &sep);
+ if (opt) {
+ for (; opt; opt = find_opt(opt + 1, arg, &sep)) {
+ int res;
+ if (sep && opt->templ[sep] == ' ' && !arg[sep])
+ res = process_opt_sep_arg(ctx, opt, sep, arg,
+ iso);
+ else
+ res = process_opt(ctx, opt, sep, arg, iso);
+ if (res == -1)
+ return -1;
+ }
+ return 0;
+ } else
+ return call_proc(ctx, arg, FUSE_OPT_KEY_OPT, iso);
}
static int process_real_option_group(struct fuse_opt_context *ctx, char *opts)
{
- char *sep;
-
- do {
- int res;
- sep = strchr(opts, ',');
- if (sep)
- *sep = '\0';
- res = process_gopt(ctx, opts, 1);
- if (res == -1)
- return -1;
- opts = sep + 1;
- } while (sep);
-
- return 0;
+ char *sep;
+
+ do {
+ int res;
+ sep = strchr(opts, ',');
+ if (sep)
+ *sep = '\0';
+ res = process_gopt(ctx, opts, 1);
+ if (res == -1)
+ return -1;
+ opts = sep + 1;
+ } while (sep);
+
+ return 0;
}
static int process_option_group(struct fuse_opt_context *ctx, const char *opts)
{
- int res;
- char *copy;
- const char *sep = strchr(opts, ',');
- if (!sep)
- return process_gopt(ctx, opts, 1);
-
- copy = strdup(opts);
- if (!copy) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- return -1;
- }
- res = process_real_option_group(ctx, copy);
- free(copy);
- return res;
+ int res;
+ char *copy;
+ const char *sep = strchr(opts, ',');
+ if (!sep)
+ return process_gopt(ctx, opts, 1);
+
+ copy = strdup(opts);
+ if (!copy) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ return -1;
+ }
+ res = process_real_option_group(ctx, copy);
+ free(copy);
+ return res;
}
static int process_one(struct fuse_opt_context *ctx, const char *arg)
{
- if (ctx->nonopt || arg[0] != '-')
- return call_proc(ctx, arg, FUSE_OPT_KEY_NONOPT, 0);
- else if (arg[1] == 'o') {
- if (arg[2])
- return process_option_group(ctx, arg + 2);
- else {
- if (next_arg(ctx, arg) == -1)
- return -1;
-
- return process_option_group(ctx, ctx->argv[ctx->argctr]);
- }
- } else if (arg[1] == '-' && !arg[2]) {
- if (add_arg(ctx, arg) == -1)
- return -1;
- ctx->nonopt = ctx->outargs.argc;
- return 0;
- } else
- return process_gopt(ctx, arg, 0);
+ if (ctx->nonopt || arg[0] != '-')
+ return call_proc(ctx, arg, FUSE_OPT_KEY_NONOPT, 0);
+ else if (arg[1] == 'o') {
+ if (arg[2])
+ return process_option_group(ctx, arg + 2);
+ else {
+ if (next_arg(ctx, arg) == -1)
+ return -1;
+
+ return process_option_group(ctx,
+ ctx->argv[ctx->argctr]);
+ }
+ } else if (arg[1] == '-' && !arg[2]) {
+ if (add_arg(ctx, arg) == -1)
+ return -1;
+ ctx->nonopt = ctx->outargs.argc;
+ return 0;
+ } else
+ return process_gopt(ctx, arg, 0);
}
static int opt_parse(struct fuse_opt_context *ctx)
{
- if (ctx->argc) {
- if (add_arg(ctx, ctx->argv[0]) == -1)
- return -1;
- }
-
- for (ctx->argctr = 1; ctx->argctr < ctx->argc; ctx->argctr++)
- if (process_one(ctx, ctx->argv[ctx->argctr]) == -1)
- return -1;
-
- if (ctx->opts) {
- if (fuse_opt_insert_arg(&ctx->outargs, 1, "-o") == -1 ||
- fuse_opt_insert_arg(&ctx->outargs, 2, ctx->opts) == -1)
- return -1;
- }
- if (ctx->nonopt && ctx->nonopt == ctx->outargs.argc) {
- free(ctx->outargs.argv[ctx->outargs.argc - 1]);
- ctx->outargs.argv[--ctx->outargs.argc] = NULL;
- }
-
- return 0;
+ if (ctx->argc) {
+ if (add_arg(ctx, ctx->argv[0]) == -1)
+ return -1;
+ }
+
+ for (ctx->argctr = 1; ctx->argctr < ctx->argc; ctx->argctr++)
+ if (process_one(ctx, ctx->argv[ctx->argctr]) == -1)
+ return -1;
+
+ if (ctx->opts) {
+ if (fuse_opt_insert_arg(&ctx->outargs, 1, "-o") == -1 ||
+ fuse_opt_insert_arg(&ctx->outargs, 2, ctx->opts) == -1)
+ return -1;
+ }
+ if (ctx->nonopt && ctx->nonopt == ctx->outargs.argc) {
+ free(ctx->outargs.argv[ctx->outargs.argc - 1]);
+ ctx->outargs.argv[--ctx->outargs.argc] = NULL;
+ }
+
+ return 0;
}
int fuse_opt_parse(struct fuse_args *args, void *data,
- const struct fuse_opt opts[], fuse_opt_proc_t proc)
+ const struct fuse_opt opts[], fuse_opt_proc_t proc)
{
- int res;
- struct fuse_opt_context ctx = {
- .data = data,
- .opt = opts,
- .proc = proc,
- };
-
- if (!args || !args->argv || !args->argc)
- return 0;
-
- ctx.argc = args->argc;
- ctx.argv = args->argv;
-
- res = opt_parse(&ctx);
- if (res != -1) {
- struct fuse_args tmp = *args;
- *args = ctx.outargs;
- ctx.outargs = tmp;
- }
- free(ctx.opts);
- fuse_opt_free_args(&ctx.outargs);
- return res;
+ int res;
+ struct fuse_opt_context ctx = {
+ .data = data,
+ .opt = opts,
+ .proc = proc,
+ };
+
+ if (!args || !args->argv || !args->argc)
+ return 0;
+
+ ctx.argc = args->argc;
+ ctx.argv = args->argv;
+
+ res = opt_parse(&ctx);
+ if (res != -1) {
+ struct fuse_args tmp = *args;
+ *args = ctx.outargs;
+ ctx.outargs = tmp;
+ }
+ free(ctx.opts);
+ fuse_opt_free_args(&ctx.outargs);
+ return res;
}
/* This symbol version was mistakenly added to the version script */
diff --git a/lib/fuse_session.c b/lib/fuse_session.c
index cf2e20b..5efedd9 100644
--- a/lib/fuse_session.c
+++ b/lib/fuse_session.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse_lowlevel.h"
@@ -18,190 +18,191 @@
#include <errno.h>
struct fuse_session {
- struct fuse_session_ops op;
+ struct fuse_session_ops op;
- void *data;
+ void *data;
- volatile int exited;
+ volatile int exited;
- struct fuse_chan *ch;
+ struct fuse_chan *ch;
};
struct fuse_chan {
- struct fuse_chan_ops op;
+ struct fuse_chan_ops op;
- struct fuse_session *se;
+ struct fuse_session *se;
- int fd;
+ int fd;
- size_t bufsize;
+ size_t bufsize;
- void *data;
+ void *data;
- int compat;
+ int compat;
};
struct fuse_session *fuse_session_new(struct fuse_session_ops *op, void *data)
{
- struct fuse_session *se = (struct fuse_session *) malloc(sizeof(*se));
- if (se == NULL) {
- fprintf(stderr, "fuse: failed to allocate session\n");
- return NULL;
- }
+ struct fuse_session *se = (struct fuse_session *) malloc(sizeof(*se));
+ if (se == NULL) {
+ fprintf(stderr, "fuse: failed to allocate session\n");
+ return NULL;
+ }
- memset(se, 0, sizeof(*se));
- se->op = *op;
- se->data = data;
+ memset(se, 0, sizeof(*se));
+ se->op = *op;
+ se->data = data;
- return se;
+ return se;
}
void fuse_session_add_chan(struct fuse_session *se, struct fuse_chan *ch)
{
- assert(se->ch == NULL);
- assert(ch->se == NULL);
- se->ch = ch;
- ch->se = se;
+ assert(se->ch == NULL);
+ assert(ch->se == NULL);
+ se->ch = ch;
+ ch->se = se;
}
void fuse_session_remove_chan(struct fuse_chan *ch)
{
- struct fuse_session *se = ch->se;
- if (se) {
- assert(se->ch == ch);
- se->ch = NULL;
- ch->se = NULL;
- }
+ struct fuse_session *se = ch->se;
+ if (se) {
+ assert(se->ch == ch);
+ se->ch = NULL;
+ ch->se = NULL;
+ }
}
struct fuse_chan *fuse_session_next_chan(struct fuse_session *se,
- struct fuse_chan *ch)
+ struct fuse_chan *ch)
{
- assert(ch == NULL || ch == se->ch);
- if (ch == NULL)
- return se->ch;
- else
- return NULL;
+ assert(ch == NULL || ch == se->ch);
+ if (ch == NULL)
+ return se->ch;
+ else
+ return NULL;
}
void fuse_session_process(struct fuse_session *se, const char *buf, size_t len,
- struct fuse_chan *ch)
+ struct fuse_chan *ch)
{
- se->op.process(se->data, buf, len, ch);
+ se->op.process(se->data, buf, len, ch);
}
void fuse_session_destroy(struct fuse_session *se)
{
- if (se->op.destroy)
- se->op.destroy(se->data);
- if (se->ch != NULL)
- fuse_chan_destroy(se->ch);
- free(se);
+ if (se->op.destroy)
+ se->op.destroy(se->data);
+ if (se->ch != NULL)
+ fuse_chan_destroy(se->ch);
+ free(se);
}
void fuse_session_exit(struct fuse_session *se)
{
- if (se->op.exit)
- se->op.exit(se->data, 1);
- se->exited = 1;
+ if (se->op.exit)
+ se->op.exit(se->data, 1);
+ se->exited = 1;
}
void fuse_session_reset(struct fuse_session *se)
{
- if (se->op.exit)
- se->op.exit(se->data, 0);
- se->exited = 0;
+ if (se->op.exit)
+ se->op.exit(se->data, 0);
+ se->exited = 0;
}
int fuse_session_exited(struct fuse_session *se)
{
- if (se->op.exited)
- return se->op.exited(se->data);
- else
- return se->exited;
+ if (se->op.exited)
+ return se->op.exited(se->data);
+ else
+ return se->exited;
}
static struct fuse_chan *fuse_chan_new_common(struct fuse_chan_ops *op, int fd,
- size_t bufsize, void *data, int compat)
+ size_t bufsize, void *data,
+ int compat)
{
- struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch));
- if (ch == NULL) {
- fprintf(stderr, "fuse: failed to allocate channel\n");
- return NULL;
- }
+ struct fuse_chan *ch = (struct fuse_chan *) malloc(sizeof(*ch));
+ if (ch == NULL) {
+ fprintf(stderr, "fuse: failed to allocate channel\n");
+ return NULL;
+ }
- memset(ch, 0, sizeof(*ch));
- ch->op = *op;
- ch->fd = fd;
- ch->bufsize = bufsize;
- ch->data = data;
- ch->compat = compat;
+ memset(ch, 0, sizeof(*ch));
+ ch->op = *op;
+ ch->fd = fd;
+ ch->bufsize = bufsize;
+ ch->data = data;
+ ch->compat = compat;
- return ch;
+ return ch;
}
struct fuse_chan *fuse_chan_new(struct fuse_chan_ops *op, int fd,
- size_t bufsize, void *data)
+ size_t bufsize, void *data)
{
- return fuse_chan_new_common(op, fd, bufsize, data, 0);
+ return fuse_chan_new_common(op, fd, bufsize, data, 0);
}
struct fuse_chan *fuse_chan_new_compat24(struct fuse_chan_ops_compat24 *op,
- int fd, size_t bufsize, void *data)
+ int fd, size_t bufsize, void *data)
{
- return fuse_chan_new_common((struct fuse_chan_ops *) op, fd, bufsize,
- data, 24);
+ return fuse_chan_new_common((struct fuse_chan_ops *) op, fd, bufsize,
+ data, 24);
}
int fuse_chan_fd(struct fuse_chan *ch)
{
- return ch->fd;
+ return ch->fd;
}
size_t fuse_chan_bufsize(struct fuse_chan *ch)
{
- return ch->bufsize;
+ return ch->bufsize;
}
void *fuse_chan_data(struct fuse_chan *ch)
{
- return ch->data;
+ return ch->data;
}
struct fuse_session *fuse_chan_session(struct fuse_chan *ch)
{
- return ch->se;
+ return ch->se;
}
int fuse_chan_recv(struct fuse_chan **chp, char *buf, size_t size)
{
- struct fuse_chan *ch = *chp;
- if (ch->compat)
- return ((struct fuse_chan_ops_compat24 *) &ch->op)
- ->receive(ch, buf, size);
- else
- return ch->op.receive(chp, buf, size);
+ struct fuse_chan *ch = *chp;
+ if (ch->compat)
+ return ((struct fuse_chan_ops_compat24 *) &ch->op)
+ ->receive(ch, buf, size);
+ else
+ return ch->op.receive(chp, buf, size);
}
int fuse_chan_receive(struct fuse_chan *ch, char *buf, size_t size)
{
- int res;
+ int res;
- res = fuse_chan_recv(&ch, buf, size);
- return res >= 0 ? res : (res != -EINTR && res != -EAGAIN) ? -1 : 0;
+ res = fuse_chan_recv(&ch, buf, size);
+ return res >= 0 ? res : (res != -EINTR && res != -EAGAIN) ? -1 : 0;
}
int fuse_chan_send(struct fuse_chan *ch, const struct iovec iov[], size_t count)
{
- return ch->op.send(ch, iov, count);
+ return ch->op.send(ch, iov, count);
}
void fuse_chan_destroy(struct fuse_chan *ch)
{
- fuse_session_remove_chan(ch);
- if (ch->op.destroy)
- ch->op.destroy(ch);
- free(ch);
+ fuse_session_remove_chan(ch);
+ if (ch->op.destroy)
+ ch->op.destroy(ch);
+ free(ch);
}
#ifndef __FreeBSD__
diff --git a/lib/fuse_signals.c b/lib/fuse_signals.c
index 25998bf..88ac39e 100644
--- a/lib/fuse_signals.c
+++ b/lib/fuse_signals.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#include "fuse_lowlevel.h"
@@ -16,57 +16,57 @@ static struct fuse_session *fuse_instance;
static void exit_handler(int sig)
{
- (void) sig;
- if (fuse_instance)
- fuse_session_exit(fuse_instance);
+ (void) sig;
+ if (fuse_instance)
+ fuse_session_exit(fuse_instance);
}
static int set_one_signal_handler(int sig, void (*handler)(int))
{
- struct sigaction sa;
- struct sigaction old_sa;
+ struct sigaction sa;
+ struct sigaction old_sa;
- memset(&sa, 0, sizeof(struct sigaction));
- sa.sa_handler = handler;
- sigemptyset(&(sa.sa_mask));
- sa.sa_flags = 0;
+ memset(&sa, 0, sizeof(struct sigaction));
+ sa.sa_handler = handler;
+ sigemptyset(&(sa.sa_mask));
+ sa.sa_flags = 0;
- if (sigaction(sig, NULL, &old_sa) == -1) {
- perror("fuse: cannot get old signal handler");
- return -1;
- }
+ if (sigaction(sig, NULL, &old_sa) == -1) {
+ perror("fuse: cannot get old signal handler");
+ return -1;
+ }
- if (old_sa.sa_handler == SIG_DFL &&
- sigaction(sig, &sa, NULL) == -1) {
- perror("fuse: cannot set signal handler");
- return -1;
- }
- return 0;
+ if (old_sa.sa_handler == SIG_DFL &&
+ sigaction(sig, &sa, NULL) == -1) {
+ perror("fuse: cannot set signal handler");
+ return -1;
+ }
+ return 0;
}
int fuse_set_signal_handlers(struct fuse_session *se)
{
- if (set_one_signal_handler(SIGHUP, exit_handler) == -1 ||
- set_one_signal_handler(SIGINT, exit_handler) == -1 ||
- set_one_signal_handler(SIGTERM, exit_handler) == -1 ||
- set_one_signal_handler(SIGPIPE, SIG_IGN) == -1)
- return -1;
+ if (set_one_signal_handler(SIGHUP, exit_handler) == -1 ||
+ set_one_signal_handler(SIGINT, exit_handler) == -1 ||
+ set_one_signal_handler(SIGTERM, exit_handler) == -1 ||
+ set_one_signal_handler(SIGPIPE, SIG_IGN) == -1)
+ return -1;
- fuse_instance = se;
- return 0;
+ fuse_instance = se;
+ return 0;
}
void fuse_remove_signal_handlers(struct fuse_session *se)
{
- if (fuse_instance != se)
- fprintf(stderr,
- "fuse: fuse_remove_signal_handlers: unknown session\n");
- else
- fuse_instance = NULL;
+ if (fuse_instance != se)
+ fprintf(stderr,
+ "fuse: fuse_remove_signal_handlers: unknown session\n");
+ else
+ fuse_instance = NULL;
- set_one_signal_handler(SIGHUP, SIG_DFL);
- set_one_signal_handler(SIGINT, SIG_DFL);
- set_one_signal_handler(SIGTERM, SIG_DFL);
- set_one_signal_handler(SIGPIPE, SIG_DFL);
+ set_one_signal_handler(SIGHUP, SIG_DFL);
+ set_one_signal_handler(SIGINT, SIG_DFL);
+ set_one_signal_handler(SIGTERM, SIG_DFL);
+ set_one_signal_handler(SIGPIPE, SIG_DFL);
}
diff --git a/lib/helper.c b/lib/helper.c
index fbbf4b2..a175ee9 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "config.h"
@@ -22,333 +22,336 @@
#include <errno.h>
enum {
- KEY_HELP,
- KEY_HELP_NOHEADER,
- KEY_VERSION,
+ KEY_HELP,
+ KEY_HELP_NOHEADER,
+ KEY_VERSION,
};
struct helper_opts {
- int singlethread;
- int foreground;
- int nodefault_subtype;
- char *mountpoint;
+ int singlethread;
+ int foreground;
+ int nodefault_subtype;
+ char *mountpoint;
};
#define FUSE_HELPER_OPT(t, p) { t, offsetof(struct helper_opts, p), 1 }
static const struct fuse_opt fuse_helper_opts[] = {
- FUSE_HELPER_OPT("-d", foreground),
- FUSE_HELPER_OPT("debug", foreground),
- FUSE_HELPER_OPT("-f", foreground),
- FUSE_HELPER_OPT("-s", singlethread),
- FUSE_HELPER_OPT("fsname=", nodefault_subtype),
- FUSE_HELPER_OPT("subtype=", nodefault_subtype),
-
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("-ho", KEY_HELP_NOHEADER),
- FUSE_OPT_KEY("-V", KEY_VERSION),
- FUSE_OPT_KEY("--version", KEY_VERSION),
- FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_KEY("fsname=", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_END
+ FUSE_HELPER_OPT("-d", foreground),
+ FUSE_HELPER_OPT("debug", foreground),
+ FUSE_HELPER_OPT("-f", foreground),
+ FUSE_HELPER_OPT("-s", singlethread),
+ FUSE_HELPER_OPT("fsname=", nodefault_subtype),
+ FUSE_HELPER_OPT("subtype=", nodefault_subtype),
+
+ FUSE_OPT_KEY("-h", KEY_HELP),
+ FUSE_OPT_KEY("--help", KEY_HELP),
+ FUSE_OPT_KEY("-ho", KEY_HELP_NOHEADER),
+ FUSE_OPT_KEY("-V", KEY_VERSION),
+ FUSE_OPT_KEY("--version", KEY_VERSION),
+ FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_KEY("fsname=", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_END
};
static void usage(const char *progname)
{
- fprintf(stderr,
- "usage: %s mountpoint [options]\n\n", progname);
- fprintf(stderr,
- "general options:\n"
- " -o opt,[opt...] mount options\n"
- " -h --help print help\n"
- " -V --version print version\n"
- "\n");
+ fprintf(stderr,
+ "usage: %s mountpoint [options]\n\n", progname);
+ fprintf(stderr,
+ "general options:\n"
+ " -o opt,[opt...] mount options\n"
+ " -h --help print help\n"
+ " -V --version print version\n"
+ "\n");
}
static void helper_help(void)
{
- fprintf(stderr,
- "FUSE options:\n"
- " -d -o debug enable debug output (implies -f)\n"
- " -f foreground operation\n"
- " -s disable multi-threaded operation\n"
- "\n"
- );
+ fprintf(stderr,
+ "FUSE options:\n"
+ " -d -o debug enable debug output (implies -f)\n"
+ " -f foreground operation\n"
+ " -s disable multi-threaded operation\n"
+ "\n"
+ );
}
static void helper_version(void)
{
- fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION);
+ fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION);
}
static int fuse_helper_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- struct helper_opts *hopts = data;
-
- switch (key) {
- case KEY_HELP:
- usage(outargs->argv[0]);
- /* fall through */
-
- case KEY_HELP_NOHEADER:
- helper_help();
- return fuse_opt_add_arg(outargs, "-h");
-
- case KEY_VERSION:
- helper_version();
- return 1;
-
- case FUSE_OPT_KEY_NONOPT:
- if (!hopts->mountpoint) {
- char mountpoint[PATH_MAX];
- if (realpath(arg, mountpoint) == NULL) {
- fprintf(stderr, "fuse: bad mount point `%s': %s\n", arg, strerror(errno));
- return -1;
- }
- return fuse_opt_add_opt(&hopts->mountpoint, mountpoint);
- } else {
- fprintf(stderr, "fuse: invalid argument `%s'\n", arg);
- return -1;
- }
-
- default:
- return 1;
- }
+ struct helper_opts *hopts = data;
+
+ switch (key) {
+ case KEY_HELP:
+ usage(outargs->argv[0]);
+ /* fall through */
+
+ case KEY_HELP_NOHEADER:
+ helper_help();
+ return fuse_opt_add_arg(outargs, "-h");
+
+ case KEY_VERSION:
+ helper_version();
+ return 1;
+
+ case FUSE_OPT_KEY_NONOPT:
+ if (!hopts->mountpoint) {
+ char mountpoint[PATH_MAX];
+ if (realpath(arg, mountpoint) == NULL) {
+ fprintf(stderr,
+ "fuse: bad mount point `%s': %s\n",
+ arg, strerror(errno));
+ return -1;
+ }
+ return fuse_opt_add_opt(&hopts->mountpoint, mountpoint);
+ } else {
+ fprintf(stderr, "fuse: invalid argument `%s'\n", arg);
+ return -1;
+ }
+
+ default:
+ return 1;
+ }
}
static int add_default_subtype(const char *progname, struct fuse_args *args)
{
- int res;
- char *subtype_opt;
- const char *basename = strrchr(progname, '/');
- if (basename == NULL)
- basename = progname;
- else if (basename[1] != '\0')
- basename++;
-
- subtype_opt = (char *) malloc(strlen(basename) + 64);
- if (subtype_opt == NULL) {
- fprintf(stderr, "fuse: memory allocation failed\n");
- return -1;
- }
- sprintf(subtype_opt, "-osubtype=%s", basename);
- res = fuse_opt_add_arg(args, subtype_opt);
- free(subtype_opt);
- return res;
+ int res;
+ char *subtype_opt;
+ const char *basename = strrchr(progname, '/');
+ if (basename == NULL)
+ basename = progname;
+ else if (basename[1] != '\0')
+ basename++;
+
+ subtype_opt = (char *) malloc(strlen(basename) + 64);
+ if (subtype_opt == NULL) {
+ fprintf(stderr, "fuse: memory allocation failed\n");
+ return -1;
+ }
+ sprintf(subtype_opt, "-osubtype=%s", basename);
+ res = fuse_opt_add_arg(args, subtype_opt);
+ free(subtype_opt);
+ return res;
}
int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint,
- int *multithreaded, int *foreground)
+ int *multithreaded, int *foreground)
{
- int res;
- struct helper_opts hopts;
-
- memset(&hopts, 0, sizeof(hopts));
- res = fuse_opt_parse(args, &hopts, fuse_helper_opts, fuse_helper_opt_proc);
- if (res == -1)
- return -1;
-
- if (!hopts.nodefault_subtype) {
- res = add_default_subtype(args->argv[0], args);
- if (res == -1)
- goto err;
- }
- if (mountpoint)
- *mountpoint = hopts.mountpoint;
- else
- free(hopts.mountpoint);
-
- if (multithreaded)
- *multithreaded = !hopts.singlethread;
- if (foreground)
- *foreground = hopts.foreground;
- return 0;
-
- err:
- free(hopts.mountpoint);
- return -1;
+ int res;
+ struct helper_opts hopts;
+
+ memset(&hopts, 0, sizeof(hopts));
+ res = fuse_opt_parse(args, &hopts, fuse_helper_opts,
+ fuse_helper_opt_proc);
+ if (res == -1)
+ return -1;
+
+ if (!hopts.nodefault_subtype) {
+ res = add_default_subtype(args->argv[0], args);
+ if (res == -1)
+ goto err;
+ }
+ if (mountpoint)
+ *mountpoint = hopts.mountpoint;
+ else
+ free(hopts.mountpoint);
+
+ if (multithreaded)
+ *multithreaded = !hopts.singlethread;
+ if (foreground)
+ *foreground = hopts.foreground;
+ return 0;
+
+err:
+ free(hopts.mountpoint);
+ return -1;
}
int fuse_daemonize(int foreground)
{
- int res;
-
- if (!foreground) {
- res = daemon(0, 0);
- if (res == -1) {
- perror("fuse: failed to daemonize program\n");
- return -1;
- }
- }
- return 0;
+ int res;
+
+ if (!foreground) {
+ res = daemon(0, 0);
+ if (res == -1) {
+ perror("fuse: failed to daemonize program\n");
+ return -1;
+ }
+ }
+ return 0;
}
static struct fuse_chan *fuse_mount_common(const char *mountpoint,
- struct fuse_args *args)
+ struct fuse_args *args)
{
- struct fuse_chan *ch;
- int fd;
-
- /*
- * Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
- * would ensue.
- */
- do {
- fd = open("/dev/null", O_RDWR);
- if (fd > 2)
- close(fd);
- } while (fd >= 0 && fd <= 2);
-
- fd = fuse_mount_compat25(mountpoint, args);
- if (fd == -1)
- return NULL;
-
- ch = fuse_kern_chan_new(fd);
- if (!ch)
- fuse_kern_unmount(mountpoint, fd);
-
- return ch;
+ struct fuse_chan *ch;
+ int fd;
+
+ /*
+ * Make sure file descriptors 0, 1 and 2 are open, otherwise chaos
+ * would ensue.
+ */
+ do {
+ fd = open("/dev/null", O_RDWR);
+ if (fd > 2)
+ close(fd);
+ } while (fd >= 0 && fd <= 2);
+
+ fd = fuse_mount_compat25(mountpoint, args);
+ if (fd == -1)
+ return NULL;
+
+ ch = fuse_kern_chan_new(fd);
+ if (!ch)
+ fuse_kern_unmount(mountpoint, fd);
+
+ return ch;
}
struct fuse_chan *fuse_mount(const char *mountpoint, struct fuse_args *args)
{
- return fuse_mount_common(mountpoint, args);
+ return fuse_mount_common(mountpoint, args);
}
static void fuse_unmount_common(const char *mountpoint, struct fuse_chan *ch)
{
- int fd = ch ? fuse_chan_fd(ch) : -1;
- fuse_kern_unmount(mountpoint, fd);
- fuse_chan_destroy(ch);
+ int fd = ch ? fuse_chan_fd(ch) : -1;
+ fuse_kern_unmount(mountpoint, fd);
+ fuse_chan_destroy(ch);
}
void fuse_unmount(const char *mountpoint, struct fuse_chan *ch)
{
- fuse_unmount_common(mountpoint, ch);
+ fuse_unmount_common(mountpoint, ch);
}
static struct fuse *fuse_setup_common(int argc, char *argv[],
- const struct fuse_operations *op,
- size_t op_size,
- char **mountpoint,
- int *multithreaded,
- int *fd,
- void *user_data,
- int compat)
+ const struct fuse_operations *op,
+ size_t op_size,
+ char **mountpoint,
+ int *multithreaded,
+ int *fd,
+ void *user_data,
+ int compat)
{
- struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
- struct fuse_chan *ch;
- struct fuse *fuse;
- int foreground;
- int res;
-
- res = fuse_parse_cmdline(&args, mountpoint, multithreaded, &foreground);
- if (res == -1)
- return NULL;
-
- ch = fuse_mount_common(*mountpoint, &args);
- if (!ch) {
- fuse_opt_free_args(&args);
- goto err_free;
- }
-
- fuse = fuse_new_common(ch, &args, op, op_size, user_data, compat);
- fuse_opt_free_args(&args);
- if (fuse == NULL)
- goto err_unmount;
-
- res = fuse_daemonize(foreground);
- if (res == -1)
- goto err_unmount;
-
- res = fuse_set_signal_handlers(fuse_get_session(fuse));
- if (res == -1)
- goto err_unmount;
-
- if (fd)
- *fd = fuse_chan_fd(ch);
-
- return fuse;
-
- err_unmount:
- fuse_unmount_common(*mountpoint, ch);
- if (fuse)
- fuse_destroy(fuse);
- err_free:
- free(*mountpoint);
- return NULL;
+ struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
+ struct fuse_chan *ch;
+ struct fuse *fuse;
+ int foreground;
+ int res;
+
+ res = fuse_parse_cmdline(&args, mountpoint, multithreaded, &foreground);
+ if (res == -1)
+ return NULL;
+
+ ch = fuse_mount_common(*mountpoint, &args);
+ if (!ch) {
+ fuse_opt_free_args(&args);
+ goto err_free;
+ }
+
+ fuse = fuse_new_common(ch, &args, op, op_size, user_data, compat);
+ fuse_opt_free_args(&args);
+ if (fuse == NULL)
+ goto err_unmount;
+
+ res = fuse_daemonize(foreground);
+ if (res == -1)
+ goto err_unmount;
+
+ res = fuse_set_signal_handlers(fuse_get_session(fuse));
+ if (res == -1)
+ goto err_unmount;
+
+ if (fd)
+ *fd = fuse_chan_fd(ch);
+
+ return fuse;
+
+err_unmount:
+ fuse_unmount_common(*mountpoint, ch);
+ if (fuse)
+ fuse_destroy(fuse);
+err_free:
+ free(*mountpoint);
+ return NULL;
}
struct fuse *fuse_setup(int argc, char *argv[],
- const struct fuse_operations *op, size_t op_size,
- char **mountpoint, int *multithreaded, void *user_data)
+ const struct fuse_operations *op, size_t op_size,
+ char **mountpoint, int *multithreaded, void *user_data)
{
- return fuse_setup_common(argc, argv, op, op_size, mountpoint,
- multithreaded, NULL, user_data, 0);
+ return fuse_setup_common(argc, argv, op, op_size, mountpoint,
+ multithreaded, NULL, user_data, 0);
}
static void fuse_teardown_common(struct fuse *fuse, char *mountpoint)
{
- struct fuse_session *se = fuse_get_session(fuse);
- struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
- fuse_remove_signal_handlers(se);
- fuse_unmount_common(mountpoint, ch);
- fuse_destroy(fuse);
- free(mountpoint);
+ struct fuse_session *se = fuse_get_session(fuse);
+ struct fuse_chan *ch = fuse_session_next_chan(se, NULL);
+ fuse_remove_signal_handlers(se);
+ fuse_unmount_common(mountpoint, ch);
+ fuse_destroy(fuse);
+ free(mountpoint);
}
void fuse_teardown(struct fuse *fuse, char *mountpoint)
{
- fuse_teardown_common(fuse, mountpoint);
+ fuse_teardown_common(fuse, mountpoint);
}
static int fuse_main_common(int argc, char *argv[],
- const struct fuse_operations *op, size_t op_size,
- void *user_data, int compat)
+ const struct fuse_operations *op, size_t op_size,
+ void *user_data, int compat)
{
- struct fuse *fuse;
- char *mountpoint;
- int multithreaded;
- int res;
-
- fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,
- &multithreaded, NULL, user_data, compat);
- if (fuse == NULL)
- return 1;
-
- if (multithreaded)
- res = fuse_loop_mt(fuse);
- else
- res = fuse_loop(fuse);
-
- fuse_teardown_common(fuse, mountpoint);
- if (res == -1)
- return 1;
-
- return 0;
+ struct fuse *fuse;
+ char *mountpoint;
+ int multithreaded;
+ int res;
+
+ fuse = fuse_setup_common(argc, argv, op, op_size, &mountpoint,
+ &multithreaded, NULL, user_data, compat);
+ if (fuse == NULL)
+ return 1;
+
+ if (multithreaded)
+ res = fuse_loop_mt(fuse);
+ else
+ res = fuse_loop(fuse);
+
+ fuse_teardown_common(fuse, mountpoint);
+ if (res == -1)
+ return 1;
+
+ return 0;
}
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
- size_t op_size, void *user_data)
+ size_t op_size, void *user_data)
{
- return fuse_main_common(argc, argv, op, op_size, user_data, 0);
+ return fuse_main_common(argc, argv, op, op_size, user_data, 0);
}
#undef fuse_main
int fuse_main(void);
int fuse_main(void)
{
- fprintf(stderr, "fuse_main(): This function does not exist\n");
- return -1;
+ fprintf(stderr, "fuse_main(): This function does not exist\n");
+ return -1;
}
int fuse_version(void)
{
- return FUSE_VERSION;
+ return FUSE_VERSION;
}
#include "fuse_compat.h"
@@ -356,51 +359,53 @@ int fuse_version(void)
#ifndef __FreeBSD__
struct fuse *fuse_setup_compat22(int argc, char *argv[],
- const struct fuse_operations_compat22 *op,
- size_t op_size, char **mountpoint,
- int *multithreaded, int *fd)
+ const struct fuse_operations_compat22 *op,
+ size_t op_size, char **mountpoint,
+ int *multithreaded, int *fd)
{
- return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
- op_size, mountpoint, multithreaded, fd, NULL, 22);
+ return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
+ op_size, mountpoint, multithreaded, fd, NULL,
+ 22);
}
struct fuse *fuse_setup_compat2(int argc, char *argv[],
- const struct fuse_operations_compat2 *op,
- char **mountpoint, int *multithreaded,
- int *fd)
+ const struct fuse_operations_compat2 *op,
+ char **mountpoint, int *multithreaded,
+ int *fd)
{
- return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat2),
- mountpoint, multithreaded, fd, NULL, 21);
+ return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
+ sizeof(struct fuse_operations_compat2),
+ mountpoint, multithreaded, fd, NULL, 21);
}
int fuse_main_real_compat22(int argc, char *argv[],
- const struct fuse_operations_compat22 *op,
- size_t op_size)
+ const struct fuse_operations_compat22 *op,
+ size_t op_size)
{
- return fuse_main_common(argc, argv, (struct fuse_operations *) op, op_size,
- NULL, 22);
+ return fuse_main_common(argc, argv, (struct fuse_operations *) op,
+ op_size, NULL, 22);
}
void fuse_main_compat1(int argc, char *argv[],
- const struct fuse_operations_compat1 *op)
+ const struct fuse_operations_compat1 *op)
{
- fuse_main_common(argc, argv, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat1), NULL, 11);
+ fuse_main_common(argc, argv, (struct fuse_operations *) op,
+ sizeof(struct fuse_operations_compat1), NULL, 11);
}
int fuse_main_compat2(int argc, char *argv[],
- const struct fuse_operations_compat2 *op)
+ const struct fuse_operations_compat2 *op)
{
- return fuse_main_common(argc, argv, (struct fuse_operations *) op,
- sizeof(struct fuse_operations_compat2), NULL, 21);
+ return fuse_main_common(argc, argv, (struct fuse_operations *) op,
+ sizeof(struct fuse_operations_compat2), NULL,
+ 21);
}
int fuse_mount_compat1(const char *mountpoint, const char *args[])
{
- /* just ignore mount args for now */
- (void) args;
- return fuse_mount_compat22(mountpoint, NULL);
+ /* just ignore mount args for now */
+ (void) args;
+ return fuse_mount_compat22(mountpoint, NULL);
}
FUSE_SYMVER(".symver fuse_setup_compat2,__fuse_setup@");
@@ -413,31 +418,32 @@ FUSE_SYMVER(".symver fuse_main_real_compat22,fuse_main_real@FUSE_2.2");
struct fuse *fuse_setup_compat25(int argc, char *argv[],
- const struct fuse_operations_compat25 *op,
- size_t op_size, char **mountpoint,
- int *multithreaded, int *fd)
+ const struct fuse_operations_compat25 *op,
+ size_t op_size, char **mountpoint,
+ int *multithreaded, int *fd)
{
- return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
- op_size, mountpoint, multithreaded, fd, NULL, 25);
+ return fuse_setup_common(argc, argv, (struct fuse_operations *) op,
+ op_size, mountpoint, multithreaded, fd, NULL,
+ 25);
}
int fuse_main_real_compat25(int argc, char *argv[],
- const struct fuse_operations_compat25 *op,
- size_t op_size)
+ const struct fuse_operations_compat25 *op,
+ size_t op_size)
{
- return fuse_main_common(argc, argv, (struct fuse_operations *) op, op_size,
- NULL, 25);
+ return fuse_main_common(argc, argv, (struct fuse_operations *) op,
+ op_size, NULL, 25);
}
void fuse_teardown_compat22(struct fuse *fuse, int fd, char *mountpoint)
{
- (void) fd;
- fuse_teardown_common(fuse, mountpoint);
+ (void) fd;
+ fuse_teardown_common(fuse, mountpoint);
}
int fuse_mount_compat25(const char *mountpoint, struct fuse_args *args)
{
- return fuse_kern_mount(mountpoint, args);
+ return fuse_kern_mount(mountpoint, args);
}
FUSE_SYMVER(".symver fuse_setup_compat25,fuse_setup@FUSE_2.5");
diff --git a/lib/modules/iconv.c b/lib/modules/iconv.c
index 350a472..c0e2b80 100644
--- a/lib/modules/iconv.c
+++ b/lib/modules/iconv.c
@@ -1,9 +1,9 @@
/*
- fuse iconv module: file name charset conversion
- Copyright (C) 2007 Miklos Szeredi <miklos@szeredi.hu>
+ fuse iconv module: file name charset conversion
+ Copyright (C) 2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#define FUSE_USE_VERSION 26
@@ -20,689 +20,690 @@
#include <langinfo.h>
struct iconv {
- struct fuse_fs *next;
- pthread_mutex_t lock;
- char *from_code;
- char *to_code;
- iconv_t tofs;
- iconv_t fromfs;
+ struct fuse_fs *next;
+ pthread_mutex_t lock;
+ char *from_code;
+ char *to_code;
+ iconv_t tofs;
+ iconv_t fromfs;
};
struct iconv_dh {
- struct iconv *ic;
- void *prev_buf;
- fuse_fill_dir_t prev_filler;
+ struct iconv *ic;
+ void *prev_buf;
+ fuse_fill_dir_t prev_filler;
};
static struct iconv *iconv_get(void)
{
- return fuse_get_context()->private_data;
+ return fuse_get_context()->private_data;
}
static int iconv_convpath(struct iconv *ic, const char *path, char **newpathp,
- int fromfs)
-{
- size_t pathlen = strlen(path);
- size_t newpathlen = pathlen * 4;
- char *newpath = malloc(newpathlen + 1);
- size_t plen = newpathlen;
- char *p = newpath;
- size_t res;
- int err;
-
- if (!newpath)
- return -ENOMEM;
-
- pthread_mutex_lock(&ic->lock);
- do {
- res = iconv(fromfs ? ic->fromfs : ic->tofs, (char **) &path, &pathlen,
- &p, &plen);
- if (res == (size_t) -1) {
- char *tmp;
- size_t inc;
-
- err = -EILSEQ;
- if (errno != E2BIG)
- goto err;
-
- inc = (pathlen + 1) * 4;
- newpathlen += inc;
- tmp = realloc(newpath, newpathlen + 1);
- err = -ENOMEM;
- if (!tmp)
- goto err;
-
- p = tmp + (p - newpath);
- plen += inc;
- newpath = tmp;
- }
- } while (res == (size_t) -1);
- pthread_mutex_unlock(&ic->lock);
- *p = '\0';
- *newpathp = newpath;
- return 0;
-
- err:
- iconv(fromfs ? ic->fromfs : ic->tofs, NULL, NULL, NULL, NULL);
- pthread_mutex_unlock(&ic->lock);
- free(newpath);
- return err;
+ int fromfs)
+{
+ size_t pathlen = strlen(path);
+ size_t newpathlen = pathlen * 4;
+ char *newpath = malloc(newpathlen + 1);
+ size_t plen = newpathlen;
+ char *p = newpath;
+ size_t res;
+ int err;
+
+ if (!newpath)
+ return -ENOMEM;
+
+ pthread_mutex_lock(&ic->lock);
+ do {
+ res = iconv(fromfs ? ic->fromfs : ic->tofs, (char **) &path,
+ &pathlen, &p, &plen);
+ if (res == (size_t) -1) {
+ char *tmp;
+ size_t inc;
+
+ err = -EILSEQ;
+ if (errno != E2BIG)
+ goto err;
+
+ inc = (pathlen + 1) * 4;
+ newpathlen += inc;
+ tmp = realloc(newpath, newpathlen + 1);
+ err = -ENOMEM;
+ if (!tmp)
+ goto err;
+
+ p = tmp + (p - newpath);
+ plen += inc;
+ newpath = tmp;
+ }
+ } while (res == (size_t) -1);
+ pthread_mutex_unlock(&ic->lock);
+ *p = '\0';
+ *newpathp = newpath;
+ return 0;
+
+err:
+ iconv(fromfs ? ic->fromfs : ic->tofs, NULL, NULL, NULL, NULL);
+ pthread_mutex_unlock(&ic->lock);
+ free(newpath);
+ return err;
}
static int iconv_getattr(const char *path, struct stat *stbuf)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_getattr(ic->next, newpath, stbuf);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_getattr(ic->next, newpath, stbuf);
+ free(newpath);
+ }
+ return err;
}
static int iconv_fgetattr(const char *path, struct stat *stbuf,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_fgetattr(ic->next, newpath, stbuf, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_fgetattr(ic->next, newpath, stbuf, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_access(const char *path, int mask)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_access(ic->next, newpath, mask);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_access(ic->next, newpath, mask);
+ free(newpath);
+ }
+ return err;
}
static int iconv_readlink(const char *path, char *buf, size_t size)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_readlink(ic->next, newpath, buf, size);
- if (!err) {
- char *newlink;
- err = iconv_convpath(ic, buf, &newlink, 1);
- if (!err) {
- strncpy(buf, newlink, size - 1);
- buf[size - 1] = '\0';
- free(newlink);
- }
- }
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_readlink(ic->next, newpath, buf, size);
+ if (!err) {
+ char *newlink;
+ err = iconv_convpath(ic, buf, &newlink, 1);
+ if (!err) {
+ strncpy(buf, newlink, size - 1);
+ buf[size - 1] = '\0';
+ free(newlink);
+ }
+ }
+ free(newpath);
+ }
+ return err;
}
static int iconv_opendir(const char *path, struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_opendir(ic->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_opendir(ic->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_dir_fill(void *buf, const char *name,
- const struct stat *stbuf, off_t off)
+ const struct stat *stbuf, off_t off)
{
- struct iconv_dh *dh = buf;
- char *newname;
- int res = 0;
- if (iconv_convpath(dh->ic, name, &newname, 1) == 0) {
- res = dh->prev_filler(dh->prev_buf, newname, stbuf, off);
- free(newname);
- }
- return res;
+ struct iconv_dh *dh = buf;
+ char *newname;
+ int res = 0;
+ if (iconv_convpath(dh->ic, name, &newname, 1) == 0) {
+ res = dh->prev_filler(dh->prev_buf, newname, stbuf, off);
+ free(newname);
+ }
+ return res;
}
static int iconv_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
- off_t offset, struct fuse_file_info *fi)
-{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- struct iconv_dh dh;
- dh.ic = ic;
- dh.prev_buf = buf;
- dh.prev_filler = filler;
- err = fuse_fs_readdir(ic->next, newpath, &dh, iconv_dir_fill, offset,
- fi);
- free(newpath);
- }
- return err;
+ off_t offset, struct fuse_file_info *fi)
+{
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ struct iconv_dh dh;
+ dh.ic = ic;
+ dh.prev_buf = buf;
+ dh.prev_filler = filler;
+ err = fuse_fs_readdir(ic->next, newpath, &dh, iconv_dir_fill,
+ offset, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_releasedir(const char *path, struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_releasedir(ic->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_releasedir(ic->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_mknod(const char *path, mode_t mode, dev_t rdev)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_mknod(ic->next, newpath, mode, rdev);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_mknod(ic->next, newpath, mode, rdev);
+ free(newpath);
+ }
+ return err;
}
static int iconv_mkdir(const char *path, mode_t mode)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_mkdir(ic->next, newpath, mode);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_mkdir(ic->next, newpath, mode);
+ free(newpath);
+ }
+ return err;
}
static int iconv_unlink(const char *path)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_unlink(ic->next, newpath);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_unlink(ic->next, newpath);
+ free(newpath);
+ }
+ return err;
}
static int iconv_rmdir(const char *path)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_rmdir(ic->next, newpath);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_rmdir(ic->next, newpath);
+ free(newpath);
+ }
+ return err;
}
static int iconv_symlink(const char *from, const char *to)
{
- struct iconv *ic = iconv_get();
- char *newfrom;
- char *newto;
- int err = iconv_convpath(ic, from, &newfrom, 0);
- if (!err) {
- err = iconv_convpath(ic, to, &newto, 0);
- if (!err) {
- err = fuse_fs_symlink(ic->next, newfrom, newto);
- free(newto);
- }
- free(newfrom);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newfrom;
+ char *newto;
+ int err = iconv_convpath(ic, from, &newfrom, 0);
+ if (!err) {
+ err = iconv_convpath(ic, to, &newto, 0);
+ if (!err) {
+ err = fuse_fs_symlink(ic->next, newfrom, newto);
+ free(newto);
+ }
+ free(newfrom);
+ }
+ return err;
}
static int iconv_rename(const char *from, const char *to)
{
- struct iconv *ic = iconv_get();
- char *newfrom;
- char *newto;
- int err = iconv_convpath(ic, from, &newfrom, 0);
- if (!err) {
- err = iconv_convpath(ic, to, &newto, 0);
- if (!err) {
- err = fuse_fs_rename(ic->next, newfrom, newto);
- free(newto);
- }
- free(newfrom);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newfrom;
+ char *newto;
+ int err = iconv_convpath(ic, from, &newfrom, 0);
+ if (!err) {
+ err = iconv_convpath(ic, to, &newto, 0);
+ if (!err) {
+ err = fuse_fs_rename(ic->next, newfrom, newto);
+ free(newto);
+ }
+ free(newfrom);
+ }
+ return err;
}
static int iconv_link(const char *from, const char *to)
{
- struct iconv *ic = iconv_get();
- char *newfrom;
- char *newto;
- int err = iconv_convpath(ic, from, &newfrom, 0);
- if (!err) {
- err = iconv_convpath(ic, to, &newto, 0);
- if (!err) {
- err = fuse_fs_link(ic->next, newfrom, newto);
- free(newto);
- }
- free(newfrom);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newfrom;
+ char *newto;
+ int err = iconv_convpath(ic, from, &newfrom, 0);
+ if (!err) {
+ err = iconv_convpath(ic, to, &newto, 0);
+ if (!err) {
+ err = fuse_fs_link(ic->next, newfrom, newto);
+ free(newto);
+ }
+ free(newfrom);
+ }
+ return err;
}
static int iconv_chmod(const char *path, mode_t mode)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_chmod(ic->next, newpath, mode);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_chmod(ic->next, newpath, mode);
+ free(newpath);
+ }
+ return err;
}
static int iconv_chown(const char *path, uid_t uid, gid_t gid)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_chown(ic->next, newpath, uid, gid);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_chown(ic->next, newpath, uid, gid);
+ free(newpath);
+ }
+ return err;
}
static int iconv_truncate(const char *path, off_t size)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_truncate(ic->next, newpath, size);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_truncate(ic->next, newpath, size);
+ free(newpath);
+ }
+ return err;
}
static int iconv_ftruncate(const char *path, off_t size,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_ftruncate(ic->next, newpath, size, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_ftruncate(ic->next, newpath, size, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_utimens(const char *path, const struct timespec ts[2])
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_utimens(ic->next, newpath, ts);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_utimens(ic->next, newpath, ts);
+ free(newpath);
+ }
+ return err;
}
static int iconv_create(const char *path, mode_t mode,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_create(ic->next, newpath, mode, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_create(ic->next, newpath, mode, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_open_file(const char *path, struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_open(ic->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_open(ic->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_read(const char *path, char *buf, size_t size, off_t offset,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_read(ic->next, newpath, buf, size, offset, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_read(ic->next, newpath, buf, size, offset, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_write(const char *path, const char *buf, size_t size,
- off_t offset, struct fuse_file_info *fi)
+ off_t offset, struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_write(ic->next, newpath, buf, size, offset, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_write(ic->next, newpath, buf, size, offset, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_statfs(const char *path, struct statvfs *stbuf)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_statfs(ic->next, newpath, stbuf);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_statfs(ic->next, newpath, stbuf);
+ free(newpath);
+ }
+ return err;
}
static int iconv_flush(const char *path, struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_flush(ic->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_flush(ic->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_release(const char *path, struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_release(ic->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_release(ic->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_fsync(const char *path, int isdatasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_fsync(ic->next, newpath, isdatasync, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_fsync(ic->next, newpath, isdatasync, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_fsyncdir(const char *path, int isdatasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_fsyncdir(ic->next, newpath, isdatasync, fi);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_fsyncdir(ic->next, newpath, isdatasync, fi);
+ free(newpath);
+ }
+ return err;
}
static int iconv_setxattr(const char *path, const char *name,
- const char *value, size_t size, int flags)
+ const char *value, size_t size, int flags)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_setxattr(ic->next, newpath, name, value, size, flags);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_setxattr(ic->next, newpath, name, value, size,
+ flags);
+ free(newpath);
+ }
+ return err;
}
static int iconv_getxattr(const char *path, const char *name, char *value,
- size_t size)
+ size_t size)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_getxattr(ic->next, newpath, name, value, size);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_getxattr(ic->next, newpath, name, value, size);
+ free(newpath);
+ }
+ return err;
}
static int iconv_listxattr(const char *path, char *list, size_t size)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_listxattr(ic->next, newpath, list, size);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_listxattr(ic->next, newpath, list, size);
+ free(newpath);
+ }
+ return err;
}
static int iconv_removexattr(const char *path, const char *name)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_removexattr(ic->next, newpath, name);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_removexattr(ic->next, newpath, name);
+ free(newpath);
+ }
+ return err;
}
static int iconv_lock(const char *path, struct fuse_file_info *fi, int cmd,
- struct flock *lock)
+ struct flock *lock)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_lock(ic->next, newpath, fi, cmd, lock);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_lock(ic->next, newpath, fi, cmd, lock);
+ free(newpath);
+ }
+ return err;
}
static int iconv_bmap(const char *path, size_t blocksize, uint64_t *idx)
{
- struct iconv *ic = iconv_get();
- char *newpath;
- int err = iconv_convpath(ic, path, &newpath, 0);
- if (!err) {
- err = fuse_fs_bmap(ic->next, newpath, blocksize, idx);
- free(newpath);
- }
- return err;
+ struct iconv *ic = iconv_get();
+ char *newpath;
+ int err = iconv_convpath(ic, path, &newpath, 0);
+ if (!err) {
+ err = fuse_fs_bmap(ic->next, newpath, blocksize, idx);
+ free(newpath);
+ }
+ return err;
}
static void *iconv_init(struct fuse_conn_info *conn)
{
- struct iconv *ic = iconv_get();
- fuse_fs_init(ic->next, conn);
- return ic;
+ struct iconv *ic = iconv_get();
+ fuse_fs_init(ic->next, conn);
+ return ic;
}
static void iconv_destroy(void *data)
{
- struct iconv *ic = data;
- fuse_fs_destroy(ic->next);
- iconv_close(ic->tofs);
- iconv_close(ic->fromfs);
- pthread_mutex_destroy(&ic->lock);
- free(ic->from_code);
- free(ic->to_code);
- free(ic);
+ struct iconv *ic = data;
+ fuse_fs_destroy(ic->next);
+ iconv_close(ic->tofs);
+ iconv_close(ic->fromfs);
+ pthread_mutex_destroy(&ic->lock);
+ free(ic->from_code);
+ free(ic->to_code);
+ free(ic);
}
static struct fuse_operations iconv_oper = {
- .destroy = iconv_destroy,
- .init = iconv_init,
- .getattr = iconv_getattr,
- .fgetattr = iconv_fgetattr,
- .access = iconv_access,
- .readlink = iconv_readlink,
- .opendir = iconv_opendir,
- .readdir = iconv_readdir,
- .releasedir = iconv_releasedir,
- .mknod = iconv_mknod,
- .mkdir = iconv_mkdir,
- .symlink = iconv_symlink,
- .unlink = iconv_unlink,
- .rmdir = iconv_rmdir,
- .rename = iconv_rename,
- .link = iconv_link,
- .chmod = iconv_chmod,
- .chown = iconv_chown,
- .truncate = iconv_truncate,
- .ftruncate = iconv_ftruncate,
- .utimens = iconv_utimens,
- .create = iconv_create,
- .open = iconv_open_file,
- .read = iconv_read,
- .write = iconv_write,
- .statfs = iconv_statfs,
- .flush = iconv_flush,
- .release = iconv_release,
- .fsync = iconv_fsync,
- .fsyncdir = iconv_fsyncdir,
- .setxattr = iconv_setxattr,
- .getxattr = iconv_getxattr,
- .listxattr = iconv_listxattr,
- .removexattr= iconv_removexattr,
- .lock = iconv_lock,
- .bmap = iconv_bmap,
+ .destroy = iconv_destroy,
+ .init = iconv_init,
+ .getattr = iconv_getattr,
+ .fgetattr = iconv_fgetattr,
+ .access = iconv_access,
+ .readlink = iconv_readlink,
+ .opendir = iconv_opendir,
+ .readdir = iconv_readdir,
+ .releasedir = iconv_releasedir,
+ .mknod = iconv_mknod,
+ .mkdir = iconv_mkdir,
+ .symlink = iconv_symlink,
+ .unlink = iconv_unlink,
+ .rmdir = iconv_rmdir,
+ .rename = iconv_rename,
+ .link = iconv_link,
+ .chmod = iconv_chmod,
+ .chown = iconv_chown,
+ .truncate = iconv_truncate,
+ .ftruncate = iconv_ftruncate,
+ .utimens = iconv_utimens,
+ .create = iconv_create,
+ .open = iconv_open_file,
+ .read = iconv_read,
+ .write = iconv_write,
+ .statfs = iconv_statfs,
+ .flush = iconv_flush,
+ .release = iconv_release,
+ .fsync = iconv_fsync,
+ .fsyncdir = iconv_fsyncdir,
+ .setxattr = iconv_setxattr,
+ .getxattr = iconv_getxattr,
+ .listxattr = iconv_listxattr,
+ .removexattr = iconv_removexattr,
+ .lock = iconv_lock,
+ .bmap = iconv_bmap,
};
static struct fuse_opt iconv_opts[] = {
- FUSE_OPT_KEY("-h", 0),
- FUSE_OPT_KEY("--help", 0),
- { "from_code=%s", offsetof(struct iconv, from_code), 0 },
- { "to_code=%s", offsetof(struct iconv, to_code), 1 },
- FUSE_OPT_END
+ FUSE_OPT_KEY("-h", 0),
+ FUSE_OPT_KEY("--help", 0),
+ { "from_code=%s", offsetof(struct iconv, from_code), 0 },
+ { "to_code=%s", offsetof(struct iconv, to_code), 1 },
+ FUSE_OPT_END
};
static void iconv_help(void)
{
- char *old = strdup(setlocale(LC_CTYPE, ""));
- char *charmap = strdup(nl_langinfo(CODESET));
- setlocale(LC_CTYPE, old);
- free(old);
- fprintf(stderr,
+ char *old = strdup(setlocale(LC_CTYPE, ""));
+ char *charmap = strdup(nl_langinfo(CODESET));
+ setlocale(LC_CTYPE, old);
+ free(old);
+ fprintf(stderr,
" -o from_code=CHARSET original encoding of file names (default: UTF-8)\n"
-" -o to_code=CHARSET new encoding of the file names (default: %s)\n",
- charmap);
- free(charmap);
+" -o to_code=CHARSET new encoding of the file names (default: %s)\n",
+ charmap);
+ free(charmap);
}
static int iconv_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- (void) data; (void) arg; (void) outargs;
+ (void) data; (void) arg; (void) outargs;
- if (!key) {
- iconv_help();
- return -1;
- }
+ if (!key) {
+ iconv_help();
+ return -1;
+ }
- return 1;
+ return 1;
}
static struct fuse_fs *iconv_new(struct fuse_args *args,
- struct fuse_fs *next[])
-{
- struct fuse_fs *fs;
- struct iconv *ic;
- char *old = NULL;
- const char *from;
- const char *to;
-
- ic = calloc(1, sizeof(struct iconv));
- if (ic == NULL) {
- fprintf(stderr, "fuse-iconv: memory allocation failed\n");
- return NULL;
- }
-
- if (fuse_opt_parse(args, ic, iconv_opts, iconv_opt_proc) == -1)
- goto out_free;
-
- if (!next[0] || next[1]) {
- fprintf(stderr, "fuse-iconv: exactly one next filesystem required\n");
- goto out_free;
- }
-
- from = ic->from_code ? ic->from_code : "UTF-8";
- to = ic->to_code ? ic->to_code : "";
- /* FIXME: detect charset equivalence? */
- if (!to[0])
- old = strdup(setlocale(LC_CTYPE, ""));
- ic->tofs = iconv_open(from, to);
- if (ic->tofs == (iconv_t) -1) {
- fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
- to, from);
- goto out_free;
- }
- ic->fromfs = iconv_open(to, from);
- if (ic->tofs == (iconv_t) -1) {
- fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
- from, to);
- goto out_iconv_close_to;
- }
- if (old) {
- setlocale(LC_CTYPE, old);
- free(old);
- }
-
- ic->next = next[0];
- fs = fuse_fs_new(&iconv_oper, sizeof(iconv_oper), ic);
- if (!fs)
- goto out_iconv_close_from;
-
- return fs;
-
- out_iconv_close_from:
- iconv_close(ic->fromfs);
- out_iconv_close_to:
- iconv_close(ic->tofs);
- out_free:
- free(ic->from_code);
- free(ic->to_code);
- free(ic);
- return NULL;
+ struct fuse_fs *next[])
+{
+ struct fuse_fs *fs;
+ struct iconv *ic;
+ char *old = NULL;
+ const char *from;
+ const char *to;
+
+ ic = calloc(1, sizeof(struct iconv));
+ if (ic == NULL) {
+ fprintf(stderr, "fuse-iconv: memory allocation failed\n");
+ return NULL;
+ }
+
+ if (fuse_opt_parse(args, ic, iconv_opts, iconv_opt_proc) == -1)
+ goto out_free;
+
+ if (!next[0] || next[1]) {
+ fprintf(stderr, "fuse-iconv: exactly one next filesystem required\n");
+ goto out_free;
+ }
+
+ from = ic->from_code ? ic->from_code : "UTF-8";
+ to = ic->to_code ? ic->to_code : "";
+ /* FIXME: detect charset equivalence? */
+ if (!to[0])
+ old = strdup(setlocale(LC_CTYPE, ""));
+ ic->tofs = iconv_open(from, to);
+ if (ic->tofs == (iconv_t) -1) {
+ fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
+ to, from);
+ goto out_free;
+ }
+ ic->fromfs = iconv_open(to, from);
+ if (ic->tofs == (iconv_t) -1) {
+ fprintf(stderr, "fuse-iconv: cannot convert from %s to %s\n",
+ from, to);
+ goto out_iconv_close_to;
+ }
+ if (old) {
+ setlocale(LC_CTYPE, old);
+ free(old);
+ }
+
+ ic->next = next[0];
+ fs = fuse_fs_new(&iconv_oper, sizeof(iconv_oper), ic);
+ if (!fs)
+ goto out_iconv_close_from;
+
+ return fs;
+
+out_iconv_close_from:
+ iconv_close(ic->fromfs);
+out_iconv_close_to:
+ iconv_close(ic->tofs);
+out_free:
+ free(ic->from_code);
+ free(ic->to_code);
+ free(ic);
+ return NULL;
}
FUSE_REGISTER_MODULE(iconv, iconv_new);
diff --git a/lib/modules/subdir.c b/lib/modules/subdir.c
index f22c023..6f7b187 100644
--- a/lib/modules/subdir.c
+++ b/lib/modules/subdir.c
@@ -1,9 +1,9 @@
/*
- fuse subdir module: offset paths with a base directory
- Copyright (C) 2007 Miklos Szeredi <miklos@szeredi.hu>
+ fuse subdir module: offset paths with a base directory
+ Copyright (C) 2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
#define FUSE_USE_VERSION 26
@@ -16,647 +16,650 @@
#include <errno.h>
struct subdir {
- char *base;
- size_t baselen;
- int rellinks;
- struct fuse_fs *next;
+ char *base;
+ size_t baselen;
+ int rellinks;
+ struct fuse_fs *next;
};
static struct subdir *subdir_get(void)
{
- return fuse_get_context()->private_data;
+ return fuse_get_context()->private_data;
}
static char *subdir_addpath(struct subdir *d, const char *path)
{
- unsigned newlen = d->baselen + strlen(path);
- char *newpath = malloc(newlen + 2);
- if (newpath) {
- if (path[0] == '/')
- path++;
- strcpy(newpath, d->base);
- strcpy(newpath + d->baselen, path);
- if (!newpath[0])
- strcpy(newpath, ".");
- }
- return newpath;
+ unsigned newlen = d->baselen + strlen(path);
+ char *newpath = malloc(newlen + 2);
+ if (newpath) {
+ if (path[0] == '/')
+ path++;
+ strcpy(newpath, d->base);
+ strcpy(newpath + d->baselen, path);
+ if (!newpath[0])
+ strcpy(newpath, ".");
+ }
+ return newpath;
}
static int subdir_getattr(const char *path, struct stat *stbuf)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_getattr(d->next, newpath, stbuf);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_getattr(d->next, newpath, stbuf);
+ free(newpath);
+ }
+ return err;
}
static int subdir_fgetattr(const char *path, struct stat *stbuf,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_fgetattr(d->next, newpath, stbuf, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_fgetattr(d->next, newpath, stbuf, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_access(const char *path, int mask)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_access(d->next, newpath, mask);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_access(d->next, newpath, mask);
+ free(newpath);
+ }
+ return err;
}
static int count_components(const char *p)
{
- int ctr;
+ int ctr;
- for (; *p == '/'; p++);
- for (ctr = 0; *p; ctr++) {
- for (; *p && *p != '/'; p++);
- for (; *p == '/'; p++);
- }
- return ctr;
+ for (; *p == '/'; p++);
+ for (ctr = 0; *p; ctr++) {
+ for (; *p && *p != '/'; p++);
+ for (; *p == '/'; p++);
+ }
+ return ctr;
}
static void strip_common(const char **sp, const char **tp)
{
- const char *s = *sp;
- const char *t = *tp;
- do {
- for (; *s == '/'; s++);
- for (; *t == '/'; t++);
- *tp = t;
- *sp = s;
- for (; *s == *t && *s && *s != '/'; s++, t++);
- } while ((*s == *t && *s) || (!*s && *t == '/') || (*s == '/' && !*t));
+ const char *s = *sp;
+ const char *t = *tp;
+ do {
+ for (; *s == '/'; s++);
+ for (; *t == '/'; t++);
+ *tp = t;
+ *sp = s;
+ for (; *s == *t && *s && *s != '/'; s++, t++);
+ } while ((*s == *t && *s) || (!*s && *t == '/') || (*s == '/' && !*t));
}
static void transform_symlink(struct subdir *d, const char *path,
- char *buf, size_t size)
+ char *buf, size_t size)
{
- const char *l = buf;
- size_t llen;
- char *s;
- int dotdots;
- int i;
+ const char *l = buf;
+ size_t llen;
+ char *s;
+ int dotdots;
+ int i;
- if (l[0] != '/' || d->base[0] != '/')
- return;
+ if (l[0] != '/' || d->base[0] != '/')
+ return;
- strip_common(&l, &path);
- if (l - buf < (long) d->baselen)
- return;
+ strip_common(&l, &path);
+ if (l - buf < (long) d->baselen)
+ return;
- dotdots = count_components(path);
- if (!dotdots)
- return;
- dotdots--;
+ dotdots = count_components(path);
+ if (!dotdots)
+ return;
+ dotdots--;
- llen = strlen(l);
- if (dotdots * 3 + llen + 2 > size)
- return;
+ llen = strlen(l);
+ if (dotdots * 3 + llen + 2 > size)
+ return;
- s = buf + dotdots * 3;
- if (llen)
- memmove(s, l, llen + 1);
- else if (!dotdots)
- strcpy(s, ".");
- else
- *s = '\0';
+ s = buf + dotdots * 3;
+ if (llen)
+ memmove(s, l, llen + 1);
+ else if (!dotdots)
+ strcpy(s, ".");
+ else
+ *s = '\0';
- for (s = buf, i = 0; i < dotdots; i++, s += 3)
- memcpy(s, "../", 3);
+ for (s = buf, i = 0; i < dotdots; i++, s += 3)
+ memcpy(s, "../", 3);
}
static int subdir_readlink(const char *path, char *buf, size_t size)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_readlink(d->next, newpath, buf, size);
- if (!err && d->rellinks)
- transform_symlink(d, newpath, buf, size);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_readlink(d->next, newpath, buf, size);
+ if (!err && d->rellinks)
+ transform_symlink(d, newpath, buf, size);
+ free(newpath);
+ }
+ return err;
}
static int subdir_opendir(const char *path, struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_opendir(d->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_opendir(d->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_readdir(const char *path, void *buf,
- fuse_fill_dir_t filler, off_t offset,
- struct fuse_file_info *fi)
+ fuse_fill_dir_t filler, off_t offset,
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_readdir(d->next, newpath, buf, filler, offset, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_readdir(d->next, newpath, buf, filler, offset,
+ fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_releasedir(const char *path, struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_releasedir(d->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_releasedir(d->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_mknod(const char *path, mode_t mode, dev_t rdev)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_mknod(d->next, newpath, mode, rdev);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_mknod(d->next, newpath, mode, rdev);
+ free(newpath);
+ }
+ return err;
}
static int subdir_mkdir(const char *path, mode_t mode)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_mkdir(d->next, newpath, mode);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_mkdir(d->next, newpath, mode);
+ free(newpath);
+ }
+ return err;
}
static int subdir_unlink(const char *path)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_unlink(d->next, newpath);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_unlink(d->next, newpath);
+ free(newpath);
+ }
+ return err;
}
static int subdir_rmdir(const char *path)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_rmdir(d->next, newpath);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_rmdir(d->next, newpath);
+ free(newpath);
+ }
+ return err;
}
static int subdir_symlink(const char *from, const char *path)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_symlink(d->next, from, newpath);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_symlink(d->next, from, newpath);
+ free(newpath);
+ }
+ return err;
}
static int subdir_rename(const char *from, const char *to)
{
- struct subdir *d = subdir_get();
- char *newfrom = subdir_addpath(d, from);
- char *newto = subdir_addpath(d, to);
- int err = -ENOMEM;
- if (newfrom && newto)
- err = fuse_fs_rename(d->next, newfrom, newto);
- free(newfrom);
- free(newto);
- return err;
+ struct subdir *d = subdir_get();
+ char *newfrom = subdir_addpath(d, from);
+ char *newto = subdir_addpath(d, to);
+ int err = -ENOMEM;
+ if (newfrom && newto)
+ err = fuse_fs_rename(d->next, newfrom, newto);
+ free(newfrom);
+ free(newto);
+ return err;
}
static int subdir_link(const char *from, const char *to)
{
- struct subdir *d = subdir_get();
- char *newfrom = subdir_addpath(d, from);
- char *newto = subdir_addpath(d, to);
- int err = -ENOMEM;
- if (newfrom && newto)
- err = fuse_fs_link(d->next, newfrom, newto);
- free(newfrom);
- free(newto);
- return err;
+ struct subdir *d = subdir_get();
+ char *newfrom = subdir_addpath(d, from);
+ char *newto = subdir_addpath(d, to);
+ int err = -ENOMEM;
+ if (newfrom && newto)
+ err = fuse_fs_link(d->next, newfrom, newto);
+ free(newfrom);
+ free(newto);
+ return err;
}
static int subdir_chmod(const char *path, mode_t mode)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_chmod(d->next, newpath, mode);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_chmod(d->next, newpath, mode);
+ free(newpath);
+ }
+ return err;
}
static int subdir_chown(const char *path, uid_t uid, gid_t gid)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_chown(d->next, newpath, uid, gid);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_chown(d->next, newpath, uid, gid);
+ free(newpath);
+ }
+ return err;
}
static int subdir_truncate(const char *path, off_t size)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_truncate(d->next, newpath, size);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_truncate(d->next, newpath, size);
+ free(newpath);
+ }
+ return err;
}
static int subdir_ftruncate(const char *path, off_t size,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_ftruncate(d->next, newpath, size, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_ftruncate(d->next, newpath, size, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_utimens(const char *path, const struct timespec ts[2])
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_utimens(d->next, newpath, ts);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_utimens(d->next, newpath, ts);
+ free(newpath);
+ }
+ return err;
}
-static int subdir_create(const char *path, mode_t mode, struct fuse_file_info *fi)
+static int subdir_create(const char *path, mode_t mode,
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_create(d->next, newpath, mode, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_create(d->next, newpath, mode, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_open(const char *path, struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_open(d->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_open(d->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_read(const char *path, char *buf, size_t size, off_t offset,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_read(d->next, newpath, buf, size, offset, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_read(d->next, newpath, buf, size, offset, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_write(const char *path, const char *buf, size_t size,
- off_t offset, struct fuse_file_info *fi)
+ off_t offset, struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_write(d->next, newpath, buf, size, offset, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_write(d->next, newpath, buf, size, offset, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_statfs(const char *path, struct statvfs *stbuf)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_statfs(d->next, newpath, stbuf);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_statfs(d->next, newpath, stbuf);
+ free(newpath);
+ }
+ return err;
}
static int subdir_flush(const char *path, struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_flush(d->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_flush(d->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_release(const char *path, struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_release(d->next, newpath, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_release(d->next, newpath, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_fsync(const char *path, int isdatasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_fsync(d->next, newpath, isdatasync, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_fsync(d->next, newpath, isdatasync, fi);
+ free(newpath);
+ }
+ return err;
}
static int subdir_fsyncdir(const char *path, int isdatasync,
- struct fuse_file_info *fi)
+ struct fuse_file_info *fi)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_fsyncdir(d->next, newpath, isdatasync, fi);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_fsyncdir(d->next, newpath, isdatasync, fi);
+ free(newpath);
+ }
+ return err;
}
-static int subdir_setxattr(const char *path, const char *name, const char *value,
- size_t size, int flags)
+static int subdir_setxattr(const char *path, const char *name,
+ const char *value, size_t size, int flags)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_setxattr(d->next, newpath, name, value, size, flags);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_setxattr(d->next, newpath, name, value, size,
+ flags);
+ free(newpath);
+ }
+ return err;
}
static int subdir_getxattr(const char *path, const char *name, char *value,
- size_t size)
+ size_t size)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_getxattr(d->next, newpath, name, value, size);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_getxattr(d->next, newpath, name, value, size);
+ free(newpath);
+ }
+ return err;
}
static int subdir_listxattr(const char *path, char *list, size_t size)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_listxattr(d->next, newpath, list, size);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_listxattr(d->next, newpath, list, size);
+ free(newpath);
+ }
+ return err;
}
static int subdir_removexattr(const char *path, const char *name)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_removexattr(d->next, newpath, name);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_removexattr(d->next, newpath, name);
+ free(newpath);
+ }
+ return err;
}
static int subdir_lock(const char *path, struct fuse_file_info *fi, int cmd,
- struct flock *lock)
+ struct flock *lock)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_lock(d->next, newpath, fi, cmd, lock);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_lock(d->next, newpath, fi, cmd, lock);
+ free(newpath);
+ }
+ return err;
}
static int subdir_bmap(const char *path, size_t blocksize, uint64_t *idx)
{
- struct subdir *d = subdir_get();
- char *newpath = subdir_addpath(d, path);
- int err = -ENOMEM;
- if (newpath) {
- err = fuse_fs_bmap(d->next, newpath, blocksize, idx);
- free(newpath);
- }
- return err;
+ struct subdir *d = subdir_get();
+ char *newpath = subdir_addpath(d, path);
+ int err = -ENOMEM;
+ if (newpath) {
+ err = fuse_fs_bmap(d->next, newpath, blocksize, idx);
+ free(newpath);
+ }
+ return err;
}
static void *subdir_init(struct fuse_conn_info *conn)
{
- struct subdir *d = subdir_get();
- fuse_fs_init(d->next, conn);
- return d;
+ struct subdir *d = subdir_get();
+ fuse_fs_init(d->next, conn);
+ return d;
}
static void subdir_destroy(void *data)
{
- struct subdir *d = data;
- fuse_fs_destroy(d->next);
- free(d->base);
- free(d);
+ struct subdir *d = data;
+ fuse_fs_destroy(d->next);
+ free(d->base);
+ free(d);
}
static struct fuse_operations subdir_oper = {
- .destroy = subdir_destroy,
- .init = subdir_init,
- .getattr = subdir_getattr,
- .fgetattr = subdir_fgetattr,
- .access = subdir_access,
- .readlink = subdir_readlink,
- .opendir = subdir_opendir,
- .readdir = subdir_readdir,
- .releasedir = subdir_releasedir,
- .mknod = subdir_mknod,
- .mkdir = subdir_mkdir,
- .symlink = subdir_symlink,
- .unlink = subdir_unlink,
- .rmdir = subdir_rmdir,
- .rename = subdir_rename,
- .link = subdir_link,
- .chmod = subdir_chmod,
- .chown = subdir_chown,
- .truncate = subdir_truncate,
- .ftruncate = subdir_ftruncate,
- .utimens = subdir_utimens,
- .create = subdir_create,
- .open = subdir_open,
- .read = subdir_read,
- .write = subdir_write,
- .statfs = subdir_statfs,
- .flush = subdir_flush,
- .release = subdir_release,
- .fsync = subdir_fsync,
- .fsyncdir = subdir_fsyncdir,
- .setxattr = subdir_setxattr,
- .getxattr = subdir_getxattr,
- .listxattr = subdir_listxattr,
- .removexattr= subdir_removexattr,
- .lock = subdir_lock,
- .bmap = subdir_bmap,
+ .destroy = subdir_destroy,
+ .init = subdir_init,
+ .getattr = subdir_getattr,
+ .fgetattr = subdir_fgetattr,
+ .access = subdir_access,
+ .readlink = subdir_readlink,
+ .opendir = subdir_opendir,
+ .readdir = subdir_readdir,
+ .releasedir = subdir_releasedir,
+ .mknod = subdir_mknod,
+ .mkdir = subdir_mkdir,
+ .symlink = subdir_symlink,
+ .unlink = subdir_unlink,
+ .rmdir = subdir_rmdir,
+ .rename = subdir_rename,
+ .link = subdir_link,
+ .chmod = subdir_chmod,
+ .chown = subdir_chown,
+ .truncate = subdir_truncate,
+ .ftruncate = subdir_ftruncate,
+ .utimens = subdir_utimens,
+ .create = subdir_create,
+ .open = subdir_open,
+ .read = subdir_read,
+ .write = subdir_write,
+ .statfs = subdir_statfs,
+ .flush = subdir_flush,
+ .release = subdir_release,
+ .fsync = subdir_fsync,
+ .fsyncdir = subdir_fsyncdir,
+ .setxattr = subdir_setxattr,
+ .getxattr = subdir_getxattr,
+ .listxattr = subdir_listxattr,
+ .removexattr = subdir_removexattr,
+ .lock = subdir_lock,
+ .bmap = subdir_bmap,
};
static struct fuse_opt subdir_opts[] = {
- FUSE_OPT_KEY("-h", 0),
- FUSE_OPT_KEY("--help", 0),
- { "subdir=%s", offsetof(struct subdir, base), 0 },
- { "rellinks", offsetof(struct subdir, rellinks), 1 },
- { "norellinks", offsetof(struct subdir, rellinks), 0 },
- FUSE_OPT_END
+ FUSE_OPT_KEY("-h", 0),
+ FUSE_OPT_KEY("--help", 0),
+ { "subdir=%s", offsetof(struct subdir, base), 0 },
+ { "rellinks", offsetof(struct subdir, rellinks), 1 },
+ { "norellinks", offsetof(struct subdir, rellinks), 0 },
+ FUSE_OPT_END
};
static void subdir_help(void)
{
- fprintf(stderr,
-" -o subdir=DIR prepend this directory to all paths (mandatory)\n"
-" -o [no]rellinks transform absolute symlinks to relative\n");
+ fprintf(stderr,
+" -o subdir=DIR prepend this directory to all paths (mandatory)\n"
+" -o [no]rellinks transform absolute symlinks to relative\n");
}
static int subdir_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- (void) data; (void) arg; (void) outargs;
+ (void) data; (void) arg; (void) outargs;
- if (!key) {
- subdir_help();
- return -1;
- }
+ if (!key) {
+ subdir_help();
+ return -1;
+ }
- return 1;
+ return 1;
}
static struct fuse_fs *subdir_new(struct fuse_args *args,
- struct fuse_fs *next[])
-{
- struct fuse_fs *fs;
- struct subdir *d;
-
- d = calloc(1, sizeof(struct subdir));
- if (d == NULL) {
- fprintf(stderr, "fuse-subdir: memory allocation failed\n");
- return NULL;
- }
-
- if (fuse_opt_parse(args, d, subdir_opts, subdir_opt_proc) == -1)
- goto out_free;
-
- if (!next[0] || next[1]) {
- fprintf(stderr, "fuse-subdir: exactly one next filesystem required\n");
- goto out_free;
- }
-
- if (!d->base) {
- fprintf(stderr, "fuse-subdir: missing 'subdir' option\n");
- goto out_free;
- }
-
- if (d->base[0] && d->base[strlen(d->base)-1] != '/') {
- char *tmp = realloc(d->base, strlen(d->base) + 2);
- if (!tmp) {
- fprintf(stderr, "fuse-subdir: memory allocation failed\n");
- goto out_free;
- }
- d->base = tmp;
- strcat(d->base, "/");
- }
- d->baselen = strlen(d->base);
- d->next = next[0];
- fs = fuse_fs_new(&subdir_oper, sizeof(subdir_oper), d);
- if (!fs)
- goto out_free;
- return fs;
-
- out_free:
- free(d->base);
- free(d);
- return NULL;
+ struct fuse_fs *next[])
+{
+ struct fuse_fs *fs;
+ struct subdir *d;
+
+ d = calloc(1, sizeof(struct subdir));
+ if (d == NULL) {
+ fprintf(stderr, "fuse-subdir: memory allocation failed\n");
+ return NULL;
+ }
+
+ if (fuse_opt_parse(args, d, subdir_opts, subdir_opt_proc) == -1)
+ goto out_free;
+
+ if (!next[0] || next[1]) {
+ fprintf(stderr, "fuse-subdir: exactly one next filesystem required\n");
+ goto out_free;
+ }
+
+ if (!d->base) {
+ fprintf(stderr, "fuse-subdir: missing 'subdir' option\n");
+ goto out_free;
+ }
+
+ if (d->base[0] && d->base[strlen(d->base)-1] != '/') {
+ char *tmp = realloc(d->base, strlen(d->base) + 2);
+ if (!tmp) {
+ fprintf(stderr, "fuse-subdir: memory allocation failed\n");
+ goto out_free;
+ }
+ d->base = tmp;
+ strcat(d->base, "/");
+ }
+ d->baselen = strlen(d->base);
+ d->next = next[0];
+ fs = fuse_fs_new(&subdir_oper, sizeof(subdir_oper), d);
+ if (!fs)
+ goto out_free;
+ return fs;
+
+out_free:
+ free(d->base);
+ free(d);
+ return NULL;
}
FUSE_REGISTER_MODULE(subdir, subdir_new);
diff --git a/lib/mount.c b/lib/mount.c
index 8a5c5ab..14fbfb5 100644
--- a/lib/mount.c
+++ b/lib/mount.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "config.h"
@@ -25,8 +25,8 @@
#include <sys/wait.h>
#include <sys/mount.h>
-#define FUSERMOUNT_PROG "fusermount"
-#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
+#define FUSERMOUNT_PROG "fusermount"
+#define FUSE_COMMFD_ENV "_FUSE_COMMFD"
#ifndef HAVE_FORK
#define fork() vfork()
@@ -37,551 +37,555 @@
#endif
enum {
- KEY_KERN_FLAG,
- KEY_KERN_OPT,
- KEY_FUSERMOUNT_OPT,
- KEY_SUBTYPE_OPT,
- KEY_MTAB_OPT,
- KEY_ALLOW_ROOT,
- KEY_RO,
- KEY_HELP,
- KEY_VERSION,
+ KEY_KERN_FLAG,
+ KEY_KERN_OPT,
+ KEY_FUSERMOUNT_OPT,
+ KEY_SUBTYPE_OPT,
+ KEY_MTAB_OPT,
+ KEY_ALLOW_ROOT,
+ KEY_RO,
+ KEY_HELP,
+ KEY_VERSION,
};
struct mount_opts {
- int allow_other;
- int allow_root;
- int ishelp;
- int flags;
- int nonempty;
- int blkdev;
- char *fsname;
- char *subtype;
- char *subtype_opt;
- char *mtab_opts;
- char *fusermount_opts;
- char *kernel_opts;
+ int allow_other;
+ int allow_root;
+ int ishelp;
+ int flags;
+ int nonempty;
+ int blkdev;
+ char *fsname;
+ char *subtype;
+ char *subtype_opt;
+ char *mtab_opts;
+ char *fusermount_opts;
+ char *kernel_opts;
};
#define FUSE_MOUNT_OPT(t, p) { t, offsetof(struct mount_opts, p), 1 }
static const struct fuse_opt fuse_mount_opts[] = {
- FUSE_MOUNT_OPT("allow_other", allow_other),
- FUSE_MOUNT_OPT("allow_root", allow_root),
- FUSE_MOUNT_OPT("nonempty", nonempty),
- FUSE_MOUNT_OPT("blkdev", blkdev),
- FUSE_MOUNT_OPT("fsname=%s", fsname),
- FUSE_MOUNT_OPT("subtype=%s", subtype),
- FUSE_OPT_KEY("allow_other", KEY_KERN_OPT),
- FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
- FUSE_OPT_KEY("nonempty", KEY_FUSERMOUNT_OPT),
- FUSE_OPT_KEY("blkdev", KEY_FUSERMOUNT_OPT),
- FUSE_OPT_KEY("fsname=", KEY_FUSERMOUNT_OPT),
- FUSE_OPT_KEY("subtype=", KEY_SUBTYPE_OPT),
- FUSE_OPT_KEY("large_read", KEY_KERN_OPT),
- FUSE_OPT_KEY("blksize=", KEY_KERN_OPT),
- FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT),
- FUSE_OPT_KEY("max_read=", KEY_KERN_OPT),
- FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
- FUSE_OPT_KEY("user=", KEY_MTAB_OPT),
- FUSE_OPT_KEY("-r", KEY_RO),
- FUSE_OPT_KEY("ro", KEY_KERN_FLAG),
- FUSE_OPT_KEY("rw", KEY_KERN_FLAG),
- FUSE_OPT_KEY("suid", KEY_KERN_FLAG),
- FUSE_OPT_KEY("nosuid", KEY_KERN_FLAG),
- FUSE_OPT_KEY("dev", KEY_KERN_FLAG),
- FUSE_OPT_KEY("nodev", KEY_KERN_FLAG),
- FUSE_OPT_KEY("exec", KEY_KERN_FLAG),
- FUSE_OPT_KEY("noexec", KEY_KERN_FLAG),
- FUSE_OPT_KEY("async", KEY_KERN_FLAG),
- FUSE_OPT_KEY("sync", KEY_KERN_FLAG),
- FUSE_OPT_KEY("dirsync", KEY_KERN_FLAG),
- FUSE_OPT_KEY("atime", KEY_KERN_FLAG),
- FUSE_OPT_KEY("noatime", KEY_KERN_FLAG),
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("-V", KEY_VERSION),
- FUSE_OPT_KEY("--version", KEY_VERSION),
- FUSE_OPT_END
+ FUSE_MOUNT_OPT("allow_other", allow_other),
+ FUSE_MOUNT_OPT("allow_root", allow_root),
+ FUSE_MOUNT_OPT("nonempty", nonempty),
+ FUSE_MOUNT_OPT("blkdev", blkdev),
+ FUSE_MOUNT_OPT("fsname=%s", fsname),
+ FUSE_MOUNT_OPT("subtype=%s", subtype),
+ FUSE_OPT_KEY("allow_other", KEY_KERN_OPT),
+ FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
+ FUSE_OPT_KEY("nonempty", KEY_FUSERMOUNT_OPT),
+ FUSE_OPT_KEY("blkdev", KEY_FUSERMOUNT_OPT),
+ FUSE_OPT_KEY("fsname=", KEY_FUSERMOUNT_OPT),
+ FUSE_OPT_KEY("subtype=", KEY_SUBTYPE_OPT),
+ FUSE_OPT_KEY("large_read", KEY_KERN_OPT),
+ FUSE_OPT_KEY("blksize=", KEY_KERN_OPT),
+ FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT),
+ FUSE_OPT_KEY("max_read=", KEY_KERN_OPT),
+ FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
+ FUSE_OPT_KEY("user=", KEY_MTAB_OPT),
+ FUSE_OPT_KEY("-r", KEY_RO),
+ FUSE_OPT_KEY("ro", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("rw", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("suid", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("nosuid", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("dev", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("nodev", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("exec", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("noexec", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("async", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("sync", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("dirsync", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("atime", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("noatime", KEY_KERN_FLAG),
+ FUSE_OPT_KEY("-h", KEY_HELP),
+ FUSE_OPT_KEY("--help", KEY_HELP),
+ FUSE_OPT_KEY("-V", KEY_VERSION),
+ FUSE_OPT_KEY("--version", KEY_VERSION),
+ FUSE_OPT_END
};
static void mount_help(void)
{
- fprintf(stderr,
- " -o allow_other allow access to other users\n"
- " -o allow_root allow access to root\n"
- " -o nonempty allow mounts over non-empty file/dir\n"
- " -o default_permissions enable permission checking by kernel\n"
- " -o fsname=NAME set filesystem name\n"
- " -o subtype=NAME set filesystem type\n"
- " -o large_read issue large read requests (2.4 only)\n"
- " -o max_read=N set maximum size of read requests\n"
- "\n"
- );
+ fprintf(stderr,
+" -o allow_other allow access to other users\n"
+" -o allow_root allow access to root\n"
+" -o nonempty allow mounts over non-empty file/dir\n"
+" -o default_permissions enable permission checking by kernel\n"
+" -o fsname=NAME set filesystem name\n"
+" -o subtype=NAME set filesystem type\n"
+" -o large_read issue large read requests (2.4 only)\n"
+" -o max_read=N set maximum size of read requests\n"
+"\n");
}
static void exec_fusermount(const char *argv[])
{
- execv(FUSERMOUNT_DIR "/" FUSERMOUNT_PROG, (char **) argv);
- execvp(FUSERMOUNT_PROG, (char **) argv);
+ execv(FUSERMOUNT_DIR "/" FUSERMOUNT_PROG, (char **) argv);
+ execvp(FUSERMOUNT_PROG, (char **) argv);
}
static void mount_version(void)
{
- int pid = fork();
- if (!pid) {
- const char *argv[] = { FUSERMOUNT_PROG, "--version", NULL };
- exec_fusermount(argv);
- _exit(1);
- } else if (pid != -1)
- waitpid(pid, NULL, 0);
+ int pid = fork();
+ if (!pid) {
+ const char *argv[] = { FUSERMOUNT_PROG, "--version", NULL };
+ exec_fusermount(argv);
+ _exit(1);
+ } else if (pid != -1)
+ waitpid(pid, NULL, 0);
}
struct mount_flags {
- const char *opt;
- unsigned long flag;
- int on;
+ const char *opt;
+ unsigned long flag;
+ int on;
};
static struct mount_flags mount_flags[] = {
- {"rw", MS_RDONLY, 0},
- {"ro", MS_RDONLY, 1},
- {"suid", MS_NOSUID, 0},
- {"nosuid", MS_NOSUID, 1},
- {"dev", MS_NODEV, 0},
- {"nodev", MS_NODEV, 1},
- {"exec", MS_NOEXEC, 0},
- {"noexec", MS_NOEXEC, 1},
- {"async", MS_SYNCHRONOUS, 0},
- {"sync", MS_SYNCHRONOUS, 1},
- {"atime", MS_NOATIME, 0},
- {"noatime", MS_NOATIME, 1},
- {"dirsync", MS_DIRSYNC, 1},
- {NULL, 0, 0}
+ {"rw", MS_RDONLY, 0},
+ {"ro", MS_RDONLY, 1},
+ {"suid", MS_NOSUID, 0},
+ {"nosuid", MS_NOSUID, 1},
+ {"dev", MS_NODEV, 0},
+ {"nodev", MS_NODEV, 1},
+ {"exec", MS_NOEXEC, 0},
+ {"noexec", MS_NOEXEC, 1},
+ {"async", MS_SYNCHRONOUS, 0},
+ {"sync", MS_SYNCHRONOUS, 1},
+ {"atime", MS_NOATIME, 0},
+ {"noatime", MS_NOATIME, 1},
+ {"dirsync", MS_DIRSYNC, 1},
+ {NULL, 0, 0}
};
static void set_mount_flag(const char *s, int *flags)
{
- int i;
-
- for (i = 0; mount_flags[i].opt != NULL; i++) {
- const char *opt = mount_flags[i].opt;
- if (strcmp(opt, s) == 0) {
- if (mount_flags[i].on)
- *flags |= mount_flags[i].flag;
- else
- *flags &= ~mount_flags[i].flag;
- return;
- }
- }
- fprintf(stderr, "fuse: internal error, can't find mount flag\n");
- abort();
+ int i;
+
+ for (i = 0; mount_flags[i].opt != NULL; i++) {
+ const char *opt = mount_flags[i].opt;
+ if (strcmp(opt, s) == 0) {
+ if (mount_flags[i].on)
+ *flags |= mount_flags[i].flag;
+ else
+ *flags &= ~mount_flags[i].flag;
+ return;
+ }
+ }
+ fprintf(stderr, "fuse: internal error, can't find mount flag\n");
+ abort();
}
static int fuse_mount_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- struct mount_opts *mo = data;
-
- switch (key) {
- case KEY_ALLOW_ROOT:
- if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
- fuse_opt_add_arg(outargs, "-oallow_root") == -1)
- return -1;
- return 0;
-
- case KEY_RO:
- arg = "ro";
- /* fall through */
- case KEY_KERN_FLAG:
- set_mount_flag(arg, &mo->flags);
- return 0;
-
- case KEY_KERN_OPT:
- return fuse_opt_add_opt(&mo->kernel_opts, arg);
-
- case KEY_FUSERMOUNT_OPT:
- return fuse_opt_add_opt(&mo->fusermount_opts, arg);
-
- case KEY_SUBTYPE_OPT:
- return fuse_opt_add_opt(&mo->subtype_opt, arg);
-
- case KEY_MTAB_OPT:
- return fuse_opt_add_opt(&mo->mtab_opts, arg);
-
- case KEY_HELP:
- mount_help();
- mo->ishelp = 1;
- break;
-
- case KEY_VERSION:
- mount_version();
- mo->ishelp = 1;
- break;
- }
- return 1;
+ struct mount_opts *mo = data;
+
+ switch (key) {
+ case KEY_ALLOW_ROOT:
+ if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
+ fuse_opt_add_arg(outargs, "-oallow_root") == -1)
+ return -1;
+ return 0;
+
+ case KEY_RO:
+ arg = "ro";
+ /* fall through */
+ case KEY_KERN_FLAG:
+ set_mount_flag(arg, &mo->flags);
+ return 0;
+
+ case KEY_KERN_OPT:
+ return fuse_opt_add_opt(&mo->kernel_opts, arg);
+
+ case KEY_FUSERMOUNT_OPT:
+ return fuse_opt_add_opt(&mo->fusermount_opts, arg);
+
+ case KEY_SUBTYPE_OPT:
+ return fuse_opt_add_opt(&mo->subtype_opt, arg);
+
+ case KEY_MTAB_OPT:
+ return fuse_opt_add_opt(&mo->mtab_opts, arg);
+
+ case KEY_HELP:
+ mount_help();
+ mo->ishelp = 1;
+ break;
+
+ case KEY_VERSION:
+ mount_version();
+ mo->ishelp = 1;
+ break;
+ }
+ return 1;
}
/* return value:
- * >= 0 => fd
- * -1 => error
+ * >= 0 => fd
+ * -1 => error
*/
static int receive_fd(int fd)
{
- struct msghdr msg;
- struct iovec iov;
- char buf[1];
- int rv;
- size_t ccmsg[CMSG_SPACE(sizeof(int)) / sizeof(size_t)];
- struct cmsghdr *cmsg;
-
- iov.iov_base = buf;
- iov.iov_len = 1;
-
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- /* old BSD implementations should use msg_accrights instead of
- * msg_control; the interface is different. */
- msg.msg_control = ccmsg;
- msg.msg_controllen = sizeof(ccmsg);
-
- while(((rv = recvmsg(fd, &msg, 0)) == -1) && errno == EINTR);
- if (rv == -1) {
- perror("recvmsg");
- return -1;
- }
- if(!rv) {
- /* EOF */
- return -1;
- }
-
- cmsg = CMSG_FIRSTHDR(&msg);
- if (!cmsg->cmsg_type == SCM_RIGHTS) {
- fprintf(stderr, "got control message of unknown type %d\n",
- cmsg->cmsg_type);
- return -1;
- }
- return *(int*)CMSG_DATA(cmsg);
+ struct msghdr msg;
+ struct iovec iov;
+ char buf[1];
+ int rv;
+ size_t ccmsg[CMSG_SPACE(sizeof(int)) / sizeof(size_t)];
+ struct cmsghdr *cmsg;
+
+ iov.iov_base = buf;
+ iov.iov_len = 1;
+
+ msg.msg_name = 0;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ /* old BSD implementations should use msg_accrights instead of
+ * msg_control; the interface is different. */
+ msg.msg_control = ccmsg;
+ msg.msg_controllen = sizeof(ccmsg);
+
+ while(((rv = recvmsg(fd, &msg, 0)) == -1) && errno == EINTR);
+ if (rv == -1) {
+ perror("recvmsg");
+ return -1;
+ }
+ if(!rv) {
+ /* EOF */
+ return -1;
+ }
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (!cmsg->cmsg_type == SCM_RIGHTS) {
+ fprintf(stderr, "got control message of unknown type %d\n",
+ cmsg->cmsg_type);
+ return -1;
+ }
+ return *(int*)CMSG_DATA(cmsg);
}
void fuse_kern_unmount(const char *mountpoint, int fd)
{
- int res;
- int pid;
-
- if (!mountpoint)
- return;
-
- if (fd != -1) {
- struct pollfd pfd;
-
- pfd.fd = fd;
- pfd.events = 0;
- res = poll(&pfd, 1, 0);
- /* If file poll returns POLLERR on the device file descriptor,
- then the filesystem is already unmounted */
- if (res == 1 && (pfd.revents & POLLERR))
- return;
-
- /* Need to close file descriptor, otherwise synchronous umount
- would recurse into filesystem, and deadlock */
- close(fd);
- }
-
- if (geteuid() == 0) {
- fuse_mnt_umount("fuse", mountpoint, 1);
- return;
- }
-
- res = umount2(mountpoint, 2);
- if (res == 0)
- return;
-
- pid = fork();
- if(pid == -1)
- return;
-
- if(pid == 0) {
- const char *argv[] =
- { FUSERMOUNT_PROG, "-u", "-q", "-z", "--", mountpoint, NULL };
-
- exec_fusermount(argv);
- _exit(1);
- }
- waitpid(pid, NULL, 0);
+ int res;
+ int pid;
+
+ if (!mountpoint)
+ return;
+
+ if (fd != -1) {
+ struct pollfd pfd;
+
+ pfd.fd = fd;
+ pfd.events = 0;
+ res = poll(&pfd, 1, 0);
+ /* If file poll returns POLLERR on the device file descriptor,
+ then the filesystem is already unmounted */
+ if (res == 1 && (pfd.revents & POLLERR))
+ return;
+
+ /* Need to close file descriptor, otherwise synchronous umount
+ would recurse into filesystem, and deadlock */
+ close(fd);
+ }
+
+ if (geteuid() == 0) {
+ fuse_mnt_umount("fuse", mountpoint, 1);
+ return;
+ }
+
+ res = umount2(mountpoint, 2);
+ if (res == 0)
+ return;
+
+ pid = fork();
+ if(pid == -1)
+ return;
+
+ if(pid == 0) {
+ const char *argv[] = { FUSERMOUNT_PROG, "-u", "-q", "-z",
+ "--", mountpoint, NULL };
+
+ exec_fusermount(argv);
+ _exit(1);
+ }
+ waitpid(pid, NULL, 0);
}
void fuse_unmount_compat22(const char *mountpoint)
{
- fuse_kern_unmount(mountpoint, -1);
+ fuse_kern_unmount(mountpoint, -1);
}
static int fuse_mount_fusermount(const char *mountpoint, const char *opts,
- int quiet)
+ int quiet)
{
- int fds[2], pid;
- int res;
- int rv;
-
- if (!mountpoint) {
- fprintf(stderr, "fuse: missing mountpoint\n");
- return -1;
- }
-
- res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds);
- if(res == -1) {
- perror("fuse: socketpair() failed");
- return -1;
- }
-
- pid = fork();
- if(pid == -1) {
- perror("fuse: fork() failed");
- close(fds[0]);
- close(fds[1]);
- return -1;
- }
-
- if(pid == 0) {
- char env[10];
- const char *argv[32];
- int a = 0;
-
- if (quiet) {
- int fd = open("/dev/null", O_RDONLY);
- dup2(fd, 1);
- dup2(fd, 2);
- }
-
- argv[a++] = FUSERMOUNT_PROG;
- 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);
- snprintf(env, sizeof(env), "%i", fds[0]);
- setenv(FUSE_COMMFD_ENV, env, 1);
- exec_fusermount(argv);
- perror("fuse: failed to exec fusermount");
- _exit(1);
- }
-
- close(fds[0]);
- rv = receive_fd(fds[1]);
- close(fds[1]);
- waitpid(pid, NULL, 0); /* bury zombie */
-
- return rv;
+ int fds[2], pid;
+ int res;
+ int rv;
+
+ if (!mountpoint) {
+ fprintf(stderr, "fuse: missing mountpoint\n");
+ return -1;
+ }
+
+ res = socketpair(PF_UNIX, SOCK_STREAM, 0, fds);
+ if(res == -1) {
+ perror("fuse: socketpair() failed");
+ return -1;
+ }
+
+ pid = fork();
+ if(pid == -1) {
+ perror("fuse: fork() failed");
+ close(fds[0]);
+ close(fds[1]);
+ return -1;
+ }
+
+ if(pid == 0) {
+ char env[10];
+ const char *argv[32];
+ int a = 0;
+
+ if (quiet) {
+ int fd = open("/dev/null", O_RDONLY);
+ dup2(fd, 1);
+ dup2(fd, 2);
+ }
+
+ argv[a++] = FUSERMOUNT_PROG;
+ 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);
+ snprintf(env, sizeof(env), "%i", fds[0]);
+ setenv(FUSE_COMMFD_ENV, env, 1);
+ exec_fusermount(argv);
+ perror("fuse: failed to exec fusermount");
+ _exit(1);
+ }
+
+ close(fds[0]);
+ rv = receive_fd(fds[1]);
+ close(fds[1]);
+ waitpid(pid, NULL, 0); /* bury zombie */
+
+ return rv;
}
int fuse_mount_compat22(const char *mountpoint, const char *opts)
{
- return fuse_mount_fusermount(mountpoint, opts, 0);
+ return fuse_mount_fusermount(mountpoint, opts, 0);
}
static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
- const char *mnt_opts)
+ const char *mnt_opts)
{
- char tmp[128];
- const char *devname = "/dev/fuse";
- char *source = NULL;
- char *type = NULL;
- struct stat stbuf;
- int fd;
- int res;
-
- if (!mnt) {
- fprintf(stderr, "fuse: missing mountpoint\n");
- return -1;
- }
-
- res = lstat(mnt, &stbuf);
- if (res == -1) {
- fprintf(stderr ,"fuse: failed to access mountpoint %s: %s\n",
- mnt, strerror(errno));
- return -1;
- }
-
- if (!mo->nonempty) {
- res = fuse_mnt_check_empty("fuse", mnt, stbuf.st_mode, stbuf.st_size);
- if (res == -1)
- return -1;
- }
-
- fd = open(devname, O_RDWR);
- if (fd == -1) {
- if (errno == ENODEV || errno == ENOENT)
- fprintf(stderr,
- "fuse: device not found, try 'modprobe fuse' first\n");
- else
- fprintf(stderr, "fuse: failed to open %s: %s\n", devname,
- strerror(errno));
- return -1;
- }
-
- snprintf(tmp, sizeof(tmp), "fd=%i,rootmode=%o,user_id=%i,group_id=%i", fd,
- stbuf.st_mode & S_IFMT, getuid(), getgid());
-
- res = fuse_opt_add_opt(&mo->kernel_opts, tmp);
- if (res == -1)
- goto out_close;
-
- source = malloc((mo->fsname ? strlen(mo->fsname) : 0) +
- (mo->subtype ? strlen(mo->subtype) : 0) +
- strlen(devname) + 32);
-
- type = malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32);
- if (!type || !source) {
- fprintf(stderr, "fuse: failed to allocate memory\n");
- goto out_close;
- }
-
- strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
- if (mo->subtype) {
- strcat(type, ".");
- strcat(type, mo->subtype);
- }
- strcpy(source,
- mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname));
-
- res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
- if (res == -1 && errno == ENODEV && mo->subtype) {
- /* Probably missing subtype support */
- strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
- if (mo->fsname) {
- if (!mo->blkdev)
- sprintf(source, "%s#%s", mo->subtype, mo->fsname);
- } else {
- strcpy(source, type);
- }
- res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
- }
- if (res == -1) {
- /*
- * Maybe kernel doesn't support unprivileged mounts, in this
- * case try falling back to fusermount
- */
- if (errno == EPERM) {
- res = -2;
- } else {
- int errno_save = errno;
- if (mo->blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
- fprintf(stderr, "fuse: 'fuseblk' support missing\n");
- else
- fprintf(stderr, "fuse: mount failed: %s\n",
- strerror(errno_save));
- }
-
- goto out_close;
- }
-
- if (geteuid() == 0) {
- char *newmnt = fuse_mnt_resolve_path("fuse", mnt);
- res = -1;
- if (!newmnt)
- goto out_umount;
-
- res = fuse_mnt_add_mount("fuse", source, newmnt, type, mnt_opts);
- free(newmnt);
- if (res == -1)
- goto out_umount;
- }
-
- return fd;
-
- out_umount:
- umount2(mnt, 2); /* lazy umount */
- out_close:
- free(type);
- free(source);
- close(fd);
- return res;
+ char tmp[128];
+ const char *devname = "/dev/fuse";
+ char *source = NULL;
+ char *type = NULL;
+ struct stat stbuf;
+ int fd;
+ int res;
+
+ if (!mnt) {
+ fprintf(stderr, "fuse: missing mountpoint\n");
+ return -1;
+ }
+
+ res = lstat(mnt, &stbuf);
+ if (res == -1) {
+ fprintf(stderr ,"fuse: failed to access mountpoint %s: %s\n",
+ mnt, strerror(errno));
+ return -1;
+ }
+
+ if (!mo->nonempty) {
+ res = fuse_mnt_check_empty("fuse", mnt, stbuf.st_mode,
+ stbuf.st_size);
+ if (res == -1)
+ return -1;
+ }
+
+ fd = open(devname, O_RDWR);
+ if (fd == -1) {
+ if (errno == ENODEV || errno == ENOENT)
+ fprintf(stderr, "fuse: device not found, try 'modprobe fuse' first\n");
+ else
+ fprintf(stderr, "fuse: failed to open %s: %s\n",
+ devname, strerror(errno));
+ return -1;
+ }
+
+ snprintf(tmp, sizeof(tmp), "fd=%i,rootmode=%o,user_id=%i,group_id=%i",
+ fd, stbuf.st_mode & S_IFMT, getuid(), getgid());
+
+ res = fuse_opt_add_opt(&mo->kernel_opts, tmp);
+ if (res == -1)
+ goto out_close;
+
+ source = malloc((mo->fsname ? strlen(mo->fsname) : 0) +
+ (mo->subtype ? strlen(mo->subtype) : 0) +
+ strlen(devname) + 32);
+
+ type = malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32);
+ if (!type || !source) {
+ fprintf(stderr, "fuse: failed to allocate memory\n");
+ goto out_close;
+ }
+
+ strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
+ if (mo->subtype) {
+ strcat(type, ".");
+ strcat(type, mo->subtype);
+ }
+ strcpy(source,
+ mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname));
+
+ res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
+ if (res == -1 && errno == ENODEV && mo->subtype) {
+ /* Probably missing subtype support */
+ strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
+ if (mo->fsname) {
+ if (!mo->blkdev)
+ sprintf(source, "%s#%s", mo->subtype,
+ mo->fsname);
+ } else {
+ strcpy(source, type);
+ }
+ res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
+ }
+ if (res == -1) {
+ /*
+ * Maybe kernel doesn't support unprivileged mounts, in this
+ * case try falling back to fusermount
+ */
+ if (errno == EPERM) {
+ res = -2;
+ } else {
+ int errno_save = errno;
+ if (mo->blkdev && errno == ENODEV &&
+ !fuse_mnt_check_fuseblk())
+ fprintf(stderr,
+ "fuse: 'fuseblk' support missing\n");
+ else
+ fprintf(stderr, "fuse: mount failed: %s\n",
+ strerror(errno_save));
+ }
+
+ goto out_close;
+ }
+
+ if (geteuid() == 0) {
+ char *newmnt = fuse_mnt_resolve_path("fuse", mnt);
+ res = -1;
+ if (!newmnt)
+ goto out_umount;
+
+ res = fuse_mnt_add_mount("fuse", source, newmnt, type,
+ mnt_opts);
+ free(newmnt);
+ if (res == -1)
+ goto out_umount;
+ }
+
+ return fd;
+
+out_umount:
+ umount2(mnt, 2); /* lazy umount */
+out_close:
+ free(type);
+ free(source);
+ close(fd);
+ return res;
}
static int get_mnt_flag_opts(char **mnt_optsp, int flags)
{
- int i;
+ int i;
- if (!(flags & MS_RDONLY) && fuse_opt_add_opt(mnt_optsp, "rw") == -1)
- return -1;
+ if (!(flags & MS_RDONLY) && fuse_opt_add_opt(mnt_optsp, "rw") == -1)
+ return -1;
- for (i = 0; mount_flags[i].opt != NULL; i++) {
- if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
- fuse_opt_add_opt(mnt_optsp, mount_flags[i].opt) == -1)
- return -1;
- }
- return 0;
+ for (i = 0; mount_flags[i].opt != NULL; i++) {
+ if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
+ fuse_opt_add_opt(mnt_optsp, mount_flags[i].opt) == -1)
+ return -1;
+ }
+ return 0;
}
int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
{
- struct mount_opts mo;
- int res = -1;
- char *mnt_opts = NULL;
-
- memset(&mo, 0, sizeof(mo));
- mo.flags = MS_NOSUID | MS_NODEV;
-
- if (args &&
- fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
- return -1;
-
- if (mo.allow_other && mo.allow_root) {
- fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
- goto out;
- }
- res = 0;
- if (mo.ishelp)
- goto out;
-
- res = -1;
- if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1)
- goto out;
- if (mo.kernel_opts && fuse_opt_add_opt(&mnt_opts, mo.kernel_opts) == -1)
- goto out;
- if (mo.mtab_opts && fuse_opt_add_opt(&mnt_opts, mo.mtab_opts) == -1)
- goto out;
-
- res = fuse_mount_sys(mountpoint, &mo, mnt_opts);
- if (res == -2) {
- if (mo.fusermount_opts &&
- fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1)
- goto out;
-
- if (mo.subtype) {
- char *tmp_opts = NULL;
-
- res = -1;
- if (fuse_opt_add_opt(&tmp_opts, mnt_opts) == -1 ||
- fuse_opt_add_opt(&tmp_opts, mo.subtype_opt) == -1) {
- free(tmp_opts);
- goto out;
- }
-
- res = fuse_mount_fusermount(mountpoint, tmp_opts, 1);
- free(tmp_opts);
- if (res == -1)
- res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
- } else {
- res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
- }
- }
- out:
- free(mnt_opts);
- free(mo.fsname);
- free(mo.subtype);
- free(mo.fusermount_opts);
- free(mo.subtype_opt);
- free(mo.kernel_opts);
- free(mo.mtab_opts);
- return res;
+ struct mount_opts mo;
+ int res = -1;
+ char *mnt_opts = NULL;
+
+ memset(&mo, 0, sizeof(mo));
+ mo.flags = MS_NOSUID | MS_NODEV;
+
+ if (args &&
+ fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
+ return -1;
+
+ if (mo.allow_other && mo.allow_root) {
+ fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
+ goto out;
+ }
+ res = 0;
+ if (mo.ishelp)
+ goto out;
+
+ res = -1;
+ if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1)
+ goto out;
+ if (mo.kernel_opts && fuse_opt_add_opt(&mnt_opts, mo.kernel_opts) == -1)
+ goto out;
+ if (mo.mtab_opts && fuse_opt_add_opt(&mnt_opts, mo.mtab_opts) == -1)
+ goto out;
+
+ res = fuse_mount_sys(mountpoint, &mo, mnt_opts);
+ if (res == -2) {
+ if (mo.fusermount_opts &&
+ fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1)
+ goto out;
+
+ if (mo.subtype) {
+ char *tmp_opts = NULL;
+
+ res = -1;
+ if (fuse_opt_add_opt(&tmp_opts, mnt_opts) == -1 ||
+ fuse_opt_add_opt(&tmp_opts, mo.subtype_opt) == -1) {
+ free(tmp_opts);
+ goto out;
+ }
+
+ res = fuse_mount_fusermount(mountpoint, tmp_opts, 1);
+ free(tmp_opts);
+ if (res == -1)
+ res = fuse_mount_fusermount(mountpoint,
+ mnt_opts, 0);
+ } else {
+ res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
+ }
+ }
+out:
+ free(mnt_opts);
+ free(mo.fsname);
+ free(mo.subtype);
+ free(mo.fusermount_opts);
+ free(mo.subtype_opt);
+ free(mo.kernel_opts);
+ free(mo.mtab_opts);
+ return res;
}
FUSE_SYMVER(".symver fuse_mount_compat22,fuse_mount@FUSE_2.2");
diff --git a/lib/mount_bsd.c b/lib/mount_bsd.c
index 5197464..fb4f12a 100644
--- a/lib/mount_bsd.c
+++ b/lib/mount_bsd.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2005-2006 Csaba Henk <csaba.henk@creo.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2005-2006 Csaba Henk <csaba.henk@creo.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "fuse_i.h"
@@ -22,343 +22,349 @@
#include <string.h>
#include <paths.h>
-#define FUSERMOUNT_PROG "mount_fusefs"
-#define FUSE_DEV_TRUNK "/dev/fuse"
+#define FUSERMOUNT_PROG "mount_fusefs"
+#define FUSE_DEV_TRUNK "/dev/fuse"
enum {
- KEY_ALLOW_ROOT,
- KEY_RO,
- KEY_HELP,
- KEY_VERSION,
- KEY_KERN
+ KEY_ALLOW_ROOT,
+ KEY_RO,
+ KEY_HELP,
+ KEY_VERSION,
+ KEY_KERN
};
struct mount_opts {
- int allow_other;
- int allow_root;
- int ishelp;
- char *kernel_opts;
+ int allow_other;
+ int allow_root;
+ int ishelp;
+ char *kernel_opts;
};
static const struct fuse_opt fuse_mount_opts[] = {
- { "allow_other", offsetof(struct mount_opts, allow_other), 1 },
- { "allow_root", offsetof(struct mount_opts, allow_root), 1 },
- FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
- FUSE_OPT_KEY("-r", KEY_RO),
- FUSE_OPT_KEY("-h", KEY_HELP),
- FUSE_OPT_KEY("--help", KEY_HELP),
- FUSE_OPT_KEY("-V", KEY_VERSION),
- FUSE_OPT_KEY("--version", KEY_VERSION),
- /* standard FreeBSD mount options */
- FUSE_OPT_KEY("dev", KEY_KERN),
- FUSE_OPT_KEY("async", KEY_KERN),
- FUSE_OPT_KEY("atime", KEY_KERN),
- FUSE_OPT_KEY("dev", KEY_KERN),
- FUSE_OPT_KEY("exec", KEY_KERN),
- FUSE_OPT_KEY("suid", KEY_KERN),
- FUSE_OPT_KEY("symfollow", KEY_KERN),
- FUSE_OPT_KEY("rdonly", KEY_KERN),
- FUSE_OPT_KEY("sync", KEY_KERN),
- FUSE_OPT_KEY("union", KEY_KERN),
- FUSE_OPT_KEY("userquota", KEY_KERN),
- FUSE_OPT_KEY("groupquota", KEY_KERN),
- FUSE_OPT_KEY("clusterr", KEY_KERN),
- FUSE_OPT_KEY("clusterw", KEY_KERN),
- FUSE_OPT_KEY("suiddir", KEY_KERN),
- FUSE_OPT_KEY("snapshot", KEY_KERN),
- FUSE_OPT_KEY("multilabel", KEY_KERN),
- FUSE_OPT_KEY("acls", KEY_KERN),
- FUSE_OPT_KEY("force", KEY_KERN),
- FUSE_OPT_KEY("update", KEY_KERN),
- FUSE_OPT_KEY("ro", KEY_KERN),
- FUSE_OPT_KEY("rw", KEY_KERN),
- FUSE_OPT_KEY("auto", KEY_KERN),
- /* options supported under both Linux and FBSD */
- FUSE_OPT_KEY("allow_other", KEY_KERN),
- FUSE_OPT_KEY("default_permissions", KEY_KERN),
- /* FBSD FUSE specific mount options */
- FUSE_OPT_KEY("private", KEY_KERN),
- FUSE_OPT_KEY("neglect_shares", KEY_KERN),
- FUSE_OPT_KEY("push_symlinks_in", KEY_KERN),
- /* stock FBSD mountopt parsing routine lets anything be negated... */
- FUSE_OPT_KEY("nodev", KEY_KERN),
- FUSE_OPT_KEY("noasync", KEY_KERN),
- FUSE_OPT_KEY("noatime", KEY_KERN),
- FUSE_OPT_KEY("nodev", KEY_KERN),
- FUSE_OPT_KEY("noexec", KEY_KERN),
- FUSE_OPT_KEY("nosuid", KEY_KERN),
- FUSE_OPT_KEY("nosymfollow", KEY_KERN),
- FUSE_OPT_KEY("nordonly", KEY_KERN),
- FUSE_OPT_KEY("nosync", KEY_KERN),
- FUSE_OPT_KEY("nounion", KEY_KERN),
- FUSE_OPT_KEY("nouserquota", KEY_KERN),
- FUSE_OPT_KEY("nogroupquota", KEY_KERN),
- FUSE_OPT_KEY("noclusterr", KEY_KERN),
- FUSE_OPT_KEY("noclusterw", KEY_KERN),
- FUSE_OPT_KEY("nosuiddir", KEY_KERN),
- FUSE_OPT_KEY("nosnapshot", KEY_KERN),
- FUSE_OPT_KEY("nomultilabel", KEY_KERN),
- FUSE_OPT_KEY("noacls", KEY_KERN),
- FUSE_OPT_KEY("noforce", KEY_KERN),
- FUSE_OPT_KEY("noupdate", KEY_KERN),
- FUSE_OPT_KEY("noro", KEY_KERN),
- FUSE_OPT_KEY("norw", KEY_KERN),
- FUSE_OPT_KEY("noauto", KEY_KERN),
- FUSE_OPT_KEY("noallow_other", KEY_KERN),
- FUSE_OPT_KEY("nodefault_permissions", KEY_KERN),
- FUSE_OPT_KEY("noprivate", KEY_KERN),
- FUSE_OPT_KEY("noneglect_shares", KEY_KERN),
- FUSE_OPT_KEY("nopush_symlinks_in", KEY_KERN),
- /* Linux specific mount options, but let just the mount util handle them */
- FUSE_OPT_KEY("fsname=", KEY_KERN),
- FUSE_OPT_KEY("nonempty", KEY_KERN),
- FUSE_OPT_KEY("large_read", KEY_KERN),
- FUSE_OPT_KEY("max_read=", KEY_KERN),
- FUSE_OPT_END
+ { "allow_other", offsetof(struct mount_opts, allow_other), 1 },
+ { "allow_root", offsetof(struct mount_opts, allow_root), 1 },
+ FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
+ FUSE_OPT_KEY("-r", KEY_RO),
+ FUSE_OPT_KEY("-h", KEY_HELP),
+ FUSE_OPT_KEY("--help", KEY_HELP),
+ FUSE_OPT_KEY("-V", KEY_VERSION),
+ FUSE_OPT_KEY("--version", KEY_VERSION),
+ /* standard FreeBSD mount options */
+ FUSE_OPT_KEY("dev", KEY_KERN),
+ FUSE_OPT_KEY("async", KEY_KERN),
+ FUSE_OPT_KEY("atime", KEY_KERN),
+ FUSE_OPT_KEY("dev", KEY_KERN),
+ FUSE_OPT_KEY("exec", KEY_KERN),
+ FUSE_OPT_KEY("suid", KEY_KERN),
+ FUSE_OPT_KEY("symfollow", KEY_KERN),
+ FUSE_OPT_KEY("rdonly", KEY_KERN),
+ FUSE_OPT_KEY("sync", KEY_KERN),
+ FUSE_OPT_KEY("union", KEY_KERN),
+ FUSE_OPT_KEY("userquota", KEY_KERN),
+ FUSE_OPT_KEY("groupquota", KEY_KERN),
+ FUSE_OPT_KEY("clusterr", KEY_KERN),
+ FUSE_OPT_KEY("clusterw", KEY_KERN),
+ FUSE_OPT_KEY("suiddir", KEY_KERN),
+ FUSE_OPT_KEY("snapshot", KEY_KERN),
+ FUSE_OPT_KEY("multilabel", KEY_KERN),
+ FUSE_OPT_KEY("acls", KEY_KERN),
+ FUSE_OPT_KEY("force", KEY_KERN),
+ FUSE_OPT_KEY("update", KEY_KERN),
+ FUSE_OPT_KEY("ro", KEY_KERN),
+ FUSE_OPT_KEY("rw", KEY_KERN),
+ FUSE_OPT_KEY("auto", KEY_KERN),
+ /* options supported under both Linux and FBSD */
+ FUSE_OPT_KEY("allow_other", KEY_KERN),
+ FUSE_OPT_KEY("default_permissions", KEY_KERN),
+ /* FBSD FUSE specific mount options */
+ FUSE_OPT_KEY("private", KEY_KERN),
+ FUSE_OPT_KEY("neglect_shares", KEY_KERN),
+ FUSE_OPT_KEY("push_symlinks_in", KEY_KERN),
+ /* stock FBSD mountopt parsing routine lets anything be negated... */
+ FUSE_OPT_KEY("nodev", KEY_KERN),
+ FUSE_OPT_KEY("noasync", KEY_KERN),
+ FUSE_OPT_KEY("noatime", KEY_KERN),
+ FUSE_OPT_KEY("nodev", KEY_KERN),
+ FUSE_OPT_KEY("noexec", KEY_KERN),
+ FUSE_OPT_KEY("nosuid", KEY_KERN),
+ FUSE_OPT_KEY("nosymfollow", KEY_KERN),
+ FUSE_OPT_KEY("nordonly", KEY_KERN),
+ FUSE_OPT_KEY("nosync", KEY_KERN),
+ FUSE_OPT_KEY("nounion", KEY_KERN),
+ FUSE_OPT_KEY("nouserquota", KEY_KERN),
+ FUSE_OPT_KEY("nogroupquota", KEY_KERN),
+ FUSE_OPT_KEY("noclusterr", KEY_KERN),
+ FUSE_OPT_KEY("noclusterw", KEY_KERN),
+ FUSE_OPT_KEY("nosuiddir", KEY_KERN),
+ FUSE_OPT_KEY("nosnapshot", KEY_KERN),
+ FUSE_OPT_KEY("nomultilabel", KEY_KERN),
+ FUSE_OPT_KEY("noacls", KEY_KERN),
+ FUSE_OPT_KEY("noforce", KEY_KERN),
+ FUSE_OPT_KEY("noupdate", KEY_KERN),
+ FUSE_OPT_KEY("noro", KEY_KERN),
+ FUSE_OPT_KEY("norw", KEY_KERN),
+ FUSE_OPT_KEY("noauto", KEY_KERN),
+ FUSE_OPT_KEY("noallow_other", KEY_KERN),
+ FUSE_OPT_KEY("nodefault_permissions", KEY_KERN),
+ FUSE_OPT_KEY("noprivate", KEY_KERN),
+ FUSE_OPT_KEY("noneglect_shares", KEY_KERN),
+ FUSE_OPT_KEY("nopush_symlinks_in", KEY_KERN),
+ /*
+ * Linux specific mount options, but let just the mount util
+ * handle them
+ */
+ FUSE_OPT_KEY("fsname=", KEY_KERN),
+ FUSE_OPT_KEY("nonempty", KEY_KERN),
+ FUSE_OPT_KEY("large_read", KEY_KERN),
+ FUSE_OPT_KEY("max_read=", KEY_KERN),
+ FUSE_OPT_END
};
static void mount_help(void)
{
- fprintf(stderr,
- " -o allow_root allow access to root\n"
- );
- system(FUSERMOUNT_PROG " --help");
- fputc('\n', stderr);
+ fprintf(stderr,
+ " -o allow_root allow access to root\n"
+ );
+ system(FUSERMOUNT_PROG " --help");
+ fputc('\n', stderr);
}
static void mount_version(void)
{
- system(FUSERMOUNT_PROG " --version");
+ system(FUSERMOUNT_PROG " --version");
}
static int fuse_mount_opt_proc(void *data, const char *arg, int key,
- struct fuse_args *outargs)
+ struct fuse_args *outargs)
{
- struct mount_opts *mo = data;
-
- switch (key) {
- case KEY_ALLOW_ROOT:
- if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
- fuse_opt_add_arg(outargs, "-oallow_root") == -1)
- return -1;
- return 0;
-
- case KEY_RO:
- arg = "ro";
- /* fall through */
-
- case KEY_KERN:
- return fuse_opt_add_opt(&mo->kernel_opts, arg);
-
- case KEY_HELP:
- mount_help();
- mo->ishelp = 1;
- break;
-
- case KEY_VERSION:
- mount_version();
- mo->ishelp = 1;
- break;
- }
- return 1;
+ struct mount_opts *mo = data;
+
+ switch (key) {
+ case KEY_ALLOW_ROOT:
+ if (fuse_opt_add_opt(&mo->kernel_opts, "allow_other") == -1 ||
+ fuse_opt_add_arg(outargs, "-oallow_root") == -1)
+ return -1;
+ return 0;
+
+ case KEY_RO:
+ arg = "ro";
+ /* fall through */
+
+ case KEY_KERN:
+ return fuse_opt_add_opt(&mo->kernel_opts, arg);
+
+ case KEY_HELP:
+ mount_help();
+ mo->ishelp = 1;
+ break;
+
+ case KEY_VERSION:
+ mount_version();
+ mo->ishelp = 1;
+ break;
+ }
+ return 1;
}
void fuse_unmount_compat22(const char *mountpoint)
{
- char dev[128];
- char *ssc, *umount_cmd;
- FILE *sf;
- int rv;
- char *seekscript =
- "exec 2>/dev/null; " /* error message is annoying in help output */
- "/usr/bin/fstat " FUSE_DEV_TRUNK "* | "
- "/usr/bin/awk 'BEGIN{ getline; if (! ($3 == \"PID\" && $10 == \"NAME\")) exit 1; }; "
- " { if ($3 == %d) print $10; }' | "
- "/usr/bin/sort | "
- "/usr/bin/uniq | "
- "/usr/bin/awk '{ i += 1; if (i > 1){ exit 1; }; printf; }; END{ if (i == 0) exit 1; }'";
-
- (void) mountpoint;
-
- /*
- * If we don't know the fd, we have to resort to the scripted solution --
- * iterating over the fd-s is unpractical, as we don't know how many of
- * open files we have. (This could be looked up in procfs -- however,
- * that's optional on FBSD; or read out from the kmem -- however, that's
- * bound to privileges (in fact, that's what happens when we call the
- * setgid kmem fstat(1) utility).
- */
- asprintf(&ssc, seekscript, getpid());
-
- errno = 0;
- sf = popen(ssc, "r");
- if (! sf)
- return;
-
- fgets(dev, sizeof(dev), sf);
- rv = pclose(sf);
- if (rv)
- return;
-
- asprintf(&umount_cmd, "/sbin/umount %s", dev);
- system(umount_cmd);
+ char dev[128];
+ char *ssc, *umount_cmd;
+ FILE *sf;
+ int rv;
+ char *seekscript =
+ /* error message is annoying in help output */
+ "exec 2>/dev/null; "
+ "/usr/bin/fstat " FUSE_DEV_TRUNK "* | "
+ "/usr/bin/awk 'BEGIN{ getline; if (! ($3 == \"PID\" && $10 == \"NAME\")) exit 1; }; "
+ " { if ($3 == %d) print $10; }' | "
+ "/usr/bin/sort | "
+ "/usr/bin/uniq | "
+ "/usr/bin/awk '{ i += 1; if (i > 1){ exit 1; }; printf; }; END{ if (i == 0) exit 1; }'";
+
+ (void) mountpoint;
+
+ /*
+ * If we don't know the fd, we have to resort to the scripted
+ * solution -- iterating over the fd-s is unpractical, as we
+ * don't know how many of open files we have. (This could be
+ * looked up in procfs -- however, that's optional on FBSD; or
+ * read out from the kmem -- however, that's bound to
+ * privileges (in fact, that's what happens when we call the
+ * setgid kmem fstat(1) utility).
+ */
+ asprintf(&ssc, seekscript, getpid());
+
+ errno = 0;
+ sf = popen(ssc, "r");
+ if (! sf)
+ return;
+
+ fgets(dev, sizeof(dev), sf);
+ rv = pclose(sf);
+ if (rv)
+ return;
+
+ asprintf(&umount_cmd, "/sbin/umount %s", dev);
+ system(umount_cmd);
}
void fuse_kern_unmount(const char *mountpoint, int fd)
{
- char *ep, *umount_cmd, dev[128];
- struct stat sbuf;
+ char *ep, *umount_cmd, dev[128];
+ struct stat sbuf;
- (void)mountpoint;
+ (void)mountpoint;
- if (fstat(fd, &sbuf) == -1)
- return;
+ if (fstat(fd, &sbuf) == -1)
+ return;
- devname_r(sbuf.st_rdev, S_IFCHR, dev, 128);
+ devname_r(sbuf.st_rdev, S_IFCHR, dev, 128);
- if (strncmp(dev, "fuse", 4))
- return;
+ if (strncmp(dev, "fuse", 4))
+ return;
- strtol(dev + 4, &ep, 10);
- if (*ep != '\0')
- return;
+ strtol(dev + 4, &ep, 10);
+ if (*ep != '\0')
+ return;
- asprintf(&umount_cmd, "/sbin/umount " _PATH_DEV "%s", dev);
- system(umount_cmd);
+ asprintf(&umount_cmd, "/sbin/umount " _PATH_DEV "%s", dev);
+ system(umount_cmd);
}
/* Check if kernel is doing init in background */
static int init_backgrounded(void)
{
- int ibg, len;
+ int ibg, len;
- len = sizeof(ibg);
+ len = sizeof(ibg);
- if (sysctlbyname("vfs.fuse.init_backgrounded", &ibg, &len, NULL, 0))
- return 0;
+ if (sysctlbyname("vfs.fuse.init_backgrounded", &ibg, &len, NULL, 0))
+ return 0;
- return ibg;
+ return ibg;
}
static int fuse_mount_core(const char *mountpoint, const char *opts)
{
- const char *mountprog = FUSERMOUNT_PROG;
- int fd;
- char *fdnam, *dev;
- int pid;
+ const char *mountprog = FUSERMOUNT_PROG;
+ int fd;
+ char *fdnam, *dev;
+ int pid;
- fdnam = getenv("FUSE_DEV_FD");
+ fdnam = getenv("FUSE_DEV_FD");
- if (fdnam) {
- char *ep;
+ if (fdnam) {
+ char *ep;
- fd = strtol(fdnam, &ep, 10);
+ fd = strtol(fdnam, &ep, 10);
- if (*ep != '\0') {
- fprintf(stderr, "invalid value given in FUSE_DEV_FD\n");
- return -1;
- }
+ if (*ep != '\0') {
+ fprintf(stderr, "invalid value given in FUSE_DEV_FD\n");
+ return -1;
+ }
- if (fd < 0)
- return -1;
+ if (fd < 0)
+ return -1;
- goto mount;
- }
+ goto mount;
+ }
- dev = getenv("FUSE_DEV_NAME");
+ dev = getenv("FUSE_DEV_NAME");
- if (! dev)
- dev = FUSE_DEV_TRUNK;
+ if (! dev)
+ dev = FUSE_DEV_TRUNK;
- if ((fd = open(dev, O_RDWR)) < 0) {
- perror("fuse: failed to open fuse device");
- return -1;
- }
+ if ((fd = open(dev, O_RDWR)) < 0) {
+ perror("fuse: failed to open fuse device");
+ return -1;
+ }
mount:
- if (getenv("FUSE_NO_MOUNT") || ! mountpoint)
- goto out;
-
- pid = fork();
-
- if (pid == -1) {
- perror("fuse: fork() failed");
- close(fd);
- return -1;
- }
-
- if (pid == 0) {
- if (! init_backgrounded()) {
- /*
- * If init is not backgrounded, we have to call the mount util
- * backgrounded, to avoid deadlock.
- */
-
- pid = fork();
-
- if (pid == -1) {
- perror("fuse: fork() failed");
- close(fd);
- exit(1);
- }
- }
-
- if (pid == 0) {
- const char *argv[32];
- int a = 0;
-
- if (! fdnam)
- asprintf(&fdnam, "%d", fd);
-
- argv[a++] = mountprog;
- if (opts) {
- argv[a++] = "-o";
- argv[a++] = opts;
- }
- argv[a++] = fdnam;
- argv[a++] = mountpoint;
- argv[a++] = NULL;
- execvp(mountprog, (char **) argv);
- perror("fuse: failed to exec mount program");
- exit(1);
- }
-
- exit(0);
- }
-
- waitpid(pid, NULL, 0);
+ if (getenv("FUSE_NO_MOUNT") || ! mountpoint)
+ goto out;
+
+ pid = fork();
+
+ if (pid == -1) {
+ perror("fuse: fork() failed");
+ close(fd);
+ return -1;
+ }
+
+ if (pid == 0) {
+ if (! init_backgrounded()) {
+ /*
+ * If init is not backgrounded, we have to
+ * call the mount util backgrounded, to avoid
+ * deadlock.
+ */
+
+ pid = fork();
+
+ if (pid == -1) {
+ perror("fuse: fork() failed");
+ close(fd);
+ exit(1);
+ }
+ }
+
+ if (pid == 0) {
+ const char *argv[32];
+ int a = 0;
+
+ if (! fdnam)
+ asprintf(&fdnam, "%d", fd);
+
+ argv[a++] = mountprog;
+ if (opts) {
+ argv[a++] = "-o";
+ argv[a++] = opts;
+ }
+ argv[a++] = fdnam;
+ argv[a++] = mountpoint;
+ argv[a++] = NULL;
+ execvp(mountprog, (char **) argv);
+ perror("fuse: failed to exec mount program");
+ exit(1);
+ }
+
+ exit(0);
+ }
+
+ waitpid(pid, NULL, 0);
out:
- return fd;
+ return fd;
}
int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
{
- struct mount_opts mo;
- int res = -1;
-
- memset(&mo, 0, sizeof(mo));
- /* mount util should not try to spawn the daemon */
- setenv("MOUNT_FUSEFS_SAFE", "1", 1);
- /* to notify the mount util it's called from lib */
- setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1);
-
- if (args &&
- fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
- return -1;
-
- if (mo.allow_other && mo.allow_root) {
- fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
- goto out;
- }
- if (mo.ishelp)
- return 0;
-
- res = fuse_mount_core(mountpoint, mo.kernel_opts);
- out:
- free(mo.kernel_opts);
- return res;
+ struct mount_opts mo;
+ int res = -1;
+
+ memset(&mo, 0, sizeof(mo));
+ /* mount util should not try to spawn the daemon */
+ setenv("MOUNT_FUSEFS_SAFE", "1", 1);
+ /* to notify the mount util it's called from lib */
+ setenv("MOUNT_FUSEFS_CALL_BY_LIB", "1", 1);
+
+ if (args &&
+ fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
+ return -1;
+
+ if (mo.allow_other && mo.allow_root) {
+ fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
+ goto out;
+ }
+ if (mo.ishelp)
+ return 0;
+
+ res = fuse_mount_core(mountpoint, mo.kernel_opts);
+out:
+ free(mo.kernel_opts);
+ return res;
}
FUSE_SYMVER(".symver fuse_unmount_compat22,fuse_unmount@FUSE_2.2");
diff --git a/lib/mount_util.c b/lib/mount_util.c
index 9ce431a..39a1e6f 100644
--- a/lib/mount_util.c
+++ b/lib/mount_util.c
@@ -1,9 +1,9 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include "mount_util.h"
@@ -21,220 +21,223 @@
static int mtab_needs_update(const char *mnt)
{
- struct stat stbuf;
+ struct stat stbuf;
- /* If mtab is within new mount, don't touch it */
- if (strncmp(mnt, _PATH_MOUNTED, strlen(mnt)) == 0 &&
- _PATH_MOUNTED[strlen(mnt)] == '/')
- return 0;
+ /* If mtab is within new mount, don't touch it */
+ if (strncmp(mnt, _PATH_MOUNTED, strlen(mnt)) == 0 &&
+ _PATH_MOUNTED[strlen(mnt)] == '/')
+ return 0;
- if (lstat(_PATH_MOUNTED, &stbuf) != -1 && S_ISLNK(stbuf.st_mode))
- return 0;
+ if (lstat(_PATH_MOUNTED, &stbuf) != -1 && S_ISLNK(stbuf.st_mode))
+ return 0;
- return 1;
+ return 1;
}
int fuse_mnt_add_mount(const char *progname, const char *fsname,
- const char *mnt, const char *type, const char *opts)
+ const char *mnt, const char *type, const char *opts)
{
- int res;
- int status;
-
- if (!mtab_needs_update(mnt))
- return 0;
-
- res = fork();
- if (res == -1) {
- fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
- return -1;
- }
- if (res == 0) {
- char templ[] = "/tmp/fusermountXXXXXX";
- char *tmp;
-
- setuid(geteuid());
-
- /*
- * hide in a directory, where mount isn't able to resolve
- * fsname as a valid path
- */
- tmp = mkdtemp(templ);
- if (!tmp) {
- fprintf(stderr, "%s: failed to create temporary directory\n",
- progname);
- exit(1);
- }
- if (chdir(tmp)) {
- fprintf(stderr, "%s: failed to chdir to %s: %s\n",
- progname, tmp, strerror(errno));
- exit(1);
- }
- rmdir(tmp);
- execl("/bin/mount", "/bin/mount", "-i", "-f", "-t", type, "-o", opts,
- fsname, mnt, NULL);
- fprintf(stderr, "%s: failed to execute /bin/mount: %s\n", progname,
- strerror(errno));
- exit(1);
- }
- res = waitpid(res, &status, 0);
- if (res == -1) {
- fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
- return -1;
- }
- if (status != 0)
- return -1;
-
- return 0;
+ int res;
+ int status;
+
+ if (!mtab_needs_update(mnt))
+ return 0;
+
+ res = fork();
+ if (res == -1) {
+ fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
+ return -1;
+ }
+ if (res == 0) {
+ char templ[] = "/tmp/fusermountXXXXXX";
+ char *tmp;
+
+ setuid(geteuid());
+
+ /*
+ * hide in a directory, where mount isn't able to resolve
+ * fsname as a valid path
+ */
+ tmp = mkdtemp(templ);
+ if (!tmp) {
+ fprintf(stderr,
+ "%s: failed to create temporary directory\n",
+ progname);
+ exit(1);
+ }
+ if (chdir(tmp)) {
+ fprintf(stderr, "%s: failed to chdir to %s: %s\n",
+ progname, tmp, strerror(errno));
+ exit(1);
+ }
+ rmdir(tmp);
+ execl("/bin/mount", "/bin/mount", "-i", "-f", "-t", type,
+ "-o", opts, fsname, mnt, NULL);
+ fprintf(stderr, "%s: failed to execute /bin/mount: %s\n",
+ progname, strerror(errno));
+ exit(1);
+ }
+ res = waitpid(res, &status, 0);
+ if (res == -1) {
+ fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
+ return -1;
+ }
+ if (status != 0)
+ return -1;
+
+ return 0;
}
int fuse_mnt_umount(const char *progname, const char *mnt, int lazy)
{
- int res;
- int status;
-
- if (!mtab_needs_update(mnt)) {
- res = umount2(mnt, lazy ? 2 : 0);
- if (res == -1)
- fprintf(stderr, "%s: failed to unmount %s: %s\n", progname,
- mnt, strerror(errno));
- return res;
- }
-
- res = fork();
- if (res == -1) {
- fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
- return -1;
- }
- if (res == 0) {
- setuid(geteuid());
- execl("/bin/umount", "/bin/umount", "-i", mnt, lazy ? "-l" : NULL,
- NULL);
- fprintf(stderr, "%s: failed to execute /bin/umount: %s\n", progname,
- strerror(errno));
- exit(1);
- }
- res = waitpid(res, &status, 0);
- if (res == -1) {
- fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
- return -1;
- }
- if (status != 0)
- return -1;
-
- return 0;
+ int res;
+ int status;
+
+ if (!mtab_needs_update(mnt)) {
+ res = umount2(mnt, lazy ? 2 : 0);
+ if (res == -1)
+ fprintf(stderr, "%s: failed to unmount %s: %s\n",
+ progname, mnt, strerror(errno));
+ return res;
+ }
+
+ res = fork();
+ if (res == -1) {
+ fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno));
+ return -1;
+ }
+ if (res == 0) {
+ setuid(geteuid());
+ execl("/bin/umount", "/bin/umount", "-i", mnt,
+ lazy ? "-l" : NULL, NULL);
+ fprintf(stderr, "%s: failed to execute /bin/umount: %s\n",
+ progname, strerror(errno));
+ exit(1);
+ }
+ res = waitpid(res, &status, 0);
+ if (res == -1) {
+ fprintf(stderr, "%s: waitpid: %s\n", progname, strerror(errno));
+ return -1;
+ }
+ if (status != 0)
+ return -1;
+
+ return 0;
}
char *fuse_mnt_resolve_path(const char *progname, const char *orig)
{
- char buf[PATH_MAX];
- char *copy;
- char *dst;
- char *end;
- char *lastcomp;
- const char *toresolv;
-
- if (!orig[0]) {
- fprintf(stderr, "%s: invalid mountpoint '%s'\n", progname, orig);
- return NULL;
- }
-
- copy = strdup(orig);
- if (copy == NULL) {
- fprintf(stderr, "%s: failed to allocate memory\n", progname);
- return NULL;
- }
-
- toresolv = copy;
- lastcomp = NULL;
- for (end = copy + strlen(copy) - 1; end > copy && *end == '/'; end --);
- if (end[0] != '/') {
- char *tmp;
- end[1] = '\0';
- tmp = strrchr(copy, '/');
- if (tmp == NULL) {
- lastcomp = copy;
- toresolv = ".";
- } else {
- lastcomp = tmp + 1;
- if (tmp == copy)
- toresolv = "/";
- }
- if (strcmp(lastcomp, ".") == 0 || strcmp(lastcomp, "..") == 0) {
- lastcomp = NULL;
- toresolv = copy;
- }
- else if (tmp)
- tmp[0] = '\0';
- }
- if (realpath(toresolv, buf) == NULL) {
- fprintf(stderr, "%s: bad mount point %s: %s\n", progname, orig,
- strerror(errno));
- free(copy);
- return NULL;
- }
- if (lastcomp == NULL)
- dst = strdup(buf);
- else {
- dst = (char *) malloc(strlen(buf) + 1 + strlen(lastcomp) + 1);
- if (dst) {
- unsigned buflen = strlen(buf);
- if (buflen && buf[buflen-1] == '/')
- sprintf(dst, "%s%s", buf, lastcomp);
- else
- sprintf(dst, "%s/%s", buf, lastcomp);
- }
- }
- free(copy);
- if (dst == NULL)
- fprintf(stderr, "%s: failed to allocate memory\n", progname);
- return dst;
+ char buf[PATH_MAX];
+ char *copy;
+ char *dst;
+ char *end;
+ char *lastcomp;
+ const char *toresolv;
+
+ if (!orig[0]) {
+ fprintf(stderr, "%s: invalid mountpoint '%s'\n", progname,
+ orig);
+ return NULL;
+ }
+
+ copy = strdup(orig);
+ if (copy == NULL) {
+ fprintf(stderr, "%s: failed to allocate memory\n", progname);
+ return NULL;
+ }
+
+ toresolv = copy;
+ lastcomp = NULL;
+ for (end = copy + strlen(copy) - 1; end > copy && *end == '/'; end --);
+ if (end[0] != '/') {
+ char *tmp;
+ end[1] = '\0';
+ tmp = strrchr(copy, '/');
+ if (tmp == NULL) {
+ lastcomp = copy;
+ toresolv = ".";
+ } else {
+ lastcomp = tmp + 1;
+ if (tmp == copy)
+ toresolv = "/";
+ }
+ if (strcmp(lastcomp, ".") == 0 || strcmp(lastcomp, "..") == 0) {
+ lastcomp = NULL;
+ toresolv = copy;
+ }
+ else if (tmp)
+ tmp[0] = '\0';
+ }
+ if (realpath(toresolv, buf) == NULL) {
+ fprintf(stderr, "%s: bad mount point %s: %s\n", progname, orig,
+ strerror(errno));
+ free(copy);
+ return NULL;
+ }
+ if (lastcomp == NULL)
+ dst = strdup(buf);
+ else {
+ dst = (char *) malloc(strlen(buf) + 1 + strlen(lastcomp) + 1);
+ if (dst) {
+ unsigned buflen = strlen(buf);
+ if (buflen && buf[buflen-1] == '/')
+ sprintf(dst, "%s%s", buf, lastcomp);
+ else
+ sprintf(dst, "%s/%s", buf, lastcomp);
+ }
+ }
+ free(copy);
+ if (dst == NULL)
+ fprintf(stderr, "%s: failed to allocate memory\n", progname);
+ return dst;
}
int fuse_mnt_check_empty(const char *progname, const char *mnt,
- mode_t rootmode, off_t rootsize)
+ mode_t rootmode, off_t rootsize)
{
- int isempty = 1;
-
- if (S_ISDIR(rootmode)) {
- struct dirent *ent;
- DIR *dp = opendir(mnt);
- if (dp == NULL) {
- fprintf(stderr, "%s: failed to open mountpoint for reading: %s\n",
- progname, strerror(errno));
- return -1;
- }
- while ((ent = readdir(dp)) != NULL) {
- if (strcmp(ent->d_name, ".") != 0 &&
- strcmp(ent->d_name, "..") != 0) {
- isempty = 0;
- break;
- }
- }
- closedir(dp);
- } else if (rootsize)
- isempty = 0;
-
- if (!isempty) {
- fprintf(stderr, "%s: mountpoint is not empty\n", progname);
- fprintf(stderr, "%s: if you are sure this is safe, use the 'nonempty' mount option\n", progname);
- return -1;
- }
- return 0;
+ int isempty = 1;
+
+ if (S_ISDIR(rootmode)) {
+ struct dirent *ent;
+ DIR *dp = opendir(mnt);
+ if (dp == NULL) {
+ fprintf(stderr,
+ "%s: failed to open mountpoint for reading: %s\n",
+ progname, strerror(errno));
+ return -1;
+ }
+ while ((ent = readdir(dp)) != NULL) {
+ if (strcmp(ent->d_name, ".") != 0 &&
+ strcmp(ent->d_name, "..") != 0) {
+ isempty = 0;
+ break;
+ }
+ }
+ closedir(dp);
+ } else if (rootsize)
+ isempty = 0;
+
+ if (!isempty) {
+ fprintf(stderr, "%s: mountpoint is not empty\n", progname);
+ fprintf(stderr, "%s: if you are sure this is safe, use the 'nonempty' mount option\n", progname);
+ return -1;
+ }
+ return 0;
}
int fuse_mnt_check_fuseblk(void)
{
- char buf[256];
- FILE *f = fopen("/proc/filesystems", "r");
- if (!f)
- return 1;
-
- while (fgets(buf, sizeof(buf), f))
- if (strstr(buf, "fuseblk\n")) {
- fclose(f);
- return 1;
- }
-
- fclose(f);
- return 0;
+ char buf[256];
+ FILE *f = fopen("/proc/filesystems", "r");
+ if (!f)
+ return 1;
+
+ while (fgets(buf, sizeof(buf), f))
+ if (strstr(buf, "fuseblk\n")) {
+ fclose(f);
+ return 1;
+ }
+
+ fclose(f);
+ return 0;
}
diff --git a/lib/mount_util.h b/lib/mount_util.h
index 29de2be..cf54d9d 100644
--- a/lib/mount_util.h
+++ b/lib/mount_util.h
@@ -1,17 +1,17 @@
/*
- FUSE: Filesystem in Userspace
- Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
+ FUSE: Filesystem in Userspace
+ Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB.
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB.
*/
#include <sys/types.h>
int fuse_mnt_add_mount(const char *progname, const char *fsname,
- const char *mnt, const char *type, const char *opts);
+ const char *mnt, const char *type, const char *opts);
int fuse_mnt_umount(const char *progname, const char *mnt, int lazy);
char *fuse_mnt_resolve_path(const char *progname, const char *orig);
int fuse_mnt_check_empty(const char *progname, const char *mnt,
- mode_t rootmode, off_t rootsize);
+ mode_t rootmode, off_t rootsize);
int fuse_mnt_check_fuseblk(void);
diff --git a/lib/ulockmgr.c b/lib/ulockmgr.c
index e38fdc5..6703cd0 100644
--- a/lib/ulockmgr.c
+++ b/lib/ulockmgr.c
@@ -1,9 +1,9 @@
/*
- libulockmgr: Userspace Lock Manager Library
- Copyright (C) 2006 Miklos Szeredi <miklos@szeredi.hu>
+ libulockmgr: Userspace Lock Manager Library
+ Copyright (C) 2006 Miklos Szeredi <miklos@szeredi.hu>
- This program can be distributed under the terms of the GNU LGPLv2.
- See the file COPYING.LIB
+ This program can be distributed under the terms of the GNU LGPLv2.
+ See the file COPYING.LIB
*/
/* #define DEBUG 1 */
@@ -22,28 +22,28 @@
#include <sys/wait.h>
struct message {
- unsigned intr : 1;
- unsigned nofd : 1;
- pthread_t thr;
- int cmd;
- int fd;
- struct flock lock;
- int error;
+ unsigned intr : 1;
+ unsigned nofd : 1;
+ pthread_t thr;
+ int cmd;
+ int fd;
+ struct flock lock;
+ int error;
};
struct fd_store {
- struct fd_store *next;
- int fd;
- int inuse;
+ struct fd_store *next;
+ int fd;
+ int inuse;
};
struct owner {
- struct owner *next;
- struct owner *prev;
- struct fd_store *fds;
- void *id;
- size_t id_len;
- int cfd;
+ struct owner *next;
+ struct owner *prev;
+ struct fd_store *fds;
+ void *id;
+ size_t id_len;
+ int cfd;
};
static pthread_mutex_t ulockmgr_lock;
@@ -54,19 +54,19 @@ static struct owner owner_list = { .next = &owner_list, .prev = &owner_list };
static void list_del_owner(struct owner *owner)
{
- struct owner *prev = owner->prev;
- struct owner *next = owner->next;
- prev->next = next;
- next->prev = prev;
+ struct owner *prev = owner->prev;
+ struct owner *next = owner->next;
+ prev->next = next;
+ next->prev = prev;
}
static void list_add_owner(struct owner *owner, struct owner *next)
{
- struct owner *prev = next->prev;
- owner->next = next;
- owner->prev = prev;
- prev->next = owner;
- next->prev = owner;
+ struct owner *prev = next->prev;
+ owner->next = next;
+ owner->prev = prev;
+ prev->next = owner;
+ next->prev = owner;
}
/*
@@ -74,365 +74,367 @@ static void list_add_owner(struct owner *owner, struct owner *next)
* on AF_UNIX, SOCK_STREAM sockets, that could cause it to return
* zero, even if data was available. Retrying the recv will return
* the data in this case.
-*/
+ */
static int do_recv(int sock, void *buf, size_t len, int flags)
{
- int res = recv(sock, buf, len, flags);
- if (res == 0)
- res = recv(sock, buf, len, flags);
+ int res = recv(sock, buf, len, flags);
+ if (res == 0)
+ res = recv(sock, buf, len, flags);
- return res;
+ return res;
}
static int ulockmgr_send_message(int sock, void *buf, size_t buflen,
- int *fdp, int numfds)
+ int *fdp, int numfds)
{
- struct msghdr msg;
- struct cmsghdr *p_cmsg;
- struct iovec vec;
- size_t cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_SEND_FDS) / sizeof(size_t)];
- int res;
-
- assert(numfds <= MAX_SEND_FDS);
- msg.msg_control = cmsgbuf;
- msg.msg_controllen = sizeof(cmsgbuf);
- p_cmsg = CMSG_FIRSTHDR(&msg);
- p_cmsg->cmsg_level = SOL_SOCKET;
- p_cmsg->cmsg_type = SCM_RIGHTS;
- p_cmsg->cmsg_len = CMSG_LEN(sizeof(int) * numfds);
- memcpy(CMSG_DATA(p_cmsg), fdp, sizeof(int) * numfds);
- msg.msg_controllen = p_cmsg->cmsg_len;
- msg.msg_name = NULL;
- msg.msg_namelen = 0;
- msg.msg_iov = &vec;
- msg.msg_iovlen = 1;
- msg.msg_flags = 0;
- vec.iov_base = buf;
- vec.iov_len = buflen;
- res = sendmsg(sock, &msg, MSG_NOSIGNAL);
- if (res == -1) {
- perror("libulockmgr: sendmsg");
- return -1;
- }
- if ((size_t) res != buflen) {
- fprintf(stderr, "libulockmgr: sendmsg short\n");
- return -1;
- }
- return 0;
+ struct msghdr msg;
+ struct cmsghdr *p_cmsg;
+ struct iovec vec;
+ size_t cmsgbuf[CMSG_SPACE(sizeof(int) * MAX_SEND_FDS) / sizeof(size_t)];
+ int res;
+
+ assert(numfds <= MAX_SEND_FDS);
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ p_cmsg = CMSG_FIRSTHDR(&msg);
+ p_cmsg->cmsg_level = SOL_SOCKET;
+ p_cmsg->cmsg_type = SCM_RIGHTS;
+ p_cmsg->cmsg_len = CMSG_LEN(sizeof(int) * numfds);
+ memcpy(CMSG_DATA(p_cmsg), fdp, sizeof(int) * numfds);
+ msg.msg_controllen = p_cmsg->cmsg_len;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+ vec.iov_base = buf;
+ vec.iov_len = buflen;
+ res = sendmsg(sock, &msg, MSG_NOSIGNAL);
+ if (res == -1) {
+ perror("libulockmgr: sendmsg");
+ return -1;
+ }
+ if ((size_t) res != buflen) {
+ fprintf(stderr, "libulockmgr: sendmsg short\n");
+ return -1;
+ }
+ return 0;
}
static int ulockmgr_start_daemon(void)
{
- int sv[2];
- int res;
- char tmp[64];
-
- res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
- if (res == -1) {
- perror("libulockmgr: socketpair");
- return -1;
- }
- snprintf(tmp, sizeof(tmp), "exec ulockmgr_server %i", sv[0]);
- res = system(tmp);
- close(sv[0]);
- if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) {
- close(sv[1]);
- return -1;
- }
- ulockmgr_cfd = sv[1];
- return 0;
+ int sv[2];
+ int res;
+ char tmp[64];
+
+ res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
+ if (res == -1) {
+ perror("libulockmgr: socketpair");
+ return -1;
+ }
+ snprintf(tmp, sizeof(tmp), "exec ulockmgr_server %i", sv[0]);
+ res = system(tmp);
+ close(sv[0]);
+ if (res == -1 || !WIFEXITED(res) || WEXITSTATUS(res) != 0) {
+ close(sv[1]);
+ return -1;
+ }
+ ulockmgr_cfd = sv[1];
+ return 0;
}
static struct owner *ulockmgr_new_owner(const void *id, size_t id_len)
{
- int sv[2];
- int res;
- char c = 'm';
- struct owner *o;
-
- if (ulockmgr_cfd == -1 && ulockmgr_start_daemon() == -1)
- return NULL;
-
- o = calloc(1, sizeof(struct owner) + id_len);
- if (!o) {
- fprintf(stderr, "libulockmgr: failed to allocate memory\n");
- return NULL;
- }
- o->id = o + 1;
- o->id_len = id_len;
- res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
- if (res == -1) {
- perror("libulockmgr: socketpair");
- goto out_free;
- }
- res = ulockmgr_send_message(ulockmgr_cfd, &c, sizeof(c), &sv[0], 1);
- close(sv[0]);
- if (res == -1) {
- close(ulockmgr_cfd);
- ulockmgr_cfd = -1;
- goto out_close;
- }
-
- o->cfd = sv[1];
- memcpy(o->id, id, id_len);
- list_add_owner(o, &owner_list);
-
- return o;
-
- out_close:
- close(sv[1]);
- out_free:
- free(o);
- return NULL;
+ int sv[2];
+ int res;
+ char c = 'm';
+ struct owner *o;
+
+ if (ulockmgr_cfd == -1 && ulockmgr_start_daemon() == -1)
+ return NULL;
+
+ o = calloc(1, sizeof(struct owner) + id_len);
+ if (!o) {
+ fprintf(stderr, "libulockmgr: failed to allocate memory\n");
+ return NULL;
+ }
+ o->id = o + 1;
+ o->id_len = id_len;
+ res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
+ if (res == -1) {
+ perror("libulockmgr: socketpair");
+ goto out_free;
+ }
+ res = ulockmgr_send_message(ulockmgr_cfd, &c, sizeof(c), &sv[0], 1);
+ close(sv[0]);
+ if (res == -1) {
+ close(ulockmgr_cfd);
+ ulockmgr_cfd = -1;
+ goto out_close;
+ }
+
+ o->cfd = sv[1];
+ memcpy(o->id, id, id_len);
+ list_add_owner(o, &owner_list);
+
+ return o;
+
+out_close:
+ close(sv[1]);
+out_free:
+ free(o);
+ return NULL;
}
static int ulockmgr_send_request(struct message *msg, const void *id,
- size_t id_len)
+ size_t id_len)
{
- int sv[2];
- int cfd;
- struct owner *o;
- struct fd_store *f = NULL;
- struct fd_store *newf = NULL;
- struct fd_store **fp;
- int fd = msg->fd;
- int cmd = msg->cmd;
- int res;
- int unlockall = (cmd == F_SETLK && msg->lock.l_type == F_UNLCK &&
- msg->lock.l_start == 0 && msg->lock.l_len == 0);
-
- for (o = owner_list.next; o != &owner_list; o = o->next)
- if (o->id_len == id_len && memcmp(o->id, id, id_len) == 0)
- break;
-
- if (o == &owner_list)
- o = NULL;
-
- if (!o && cmd != F_GETLK && msg->lock.l_type != F_UNLCK)
- o = ulockmgr_new_owner(id, id_len);
-
- if (!o) {
- if (cmd == F_GETLK) {
- res = fcntl(msg->fd, F_GETLK, &msg->lock);
- return (res == -1) ? -errno : 0;
- } else if (msg->lock.l_type == F_UNLCK)
- return 0;
- else
- return -ENOLCK;
- }
-
- if (unlockall)
- msg->nofd = 1;
- else {
- for (fp = &o->fds; *fp; fp = &(*fp)->next) {
- f = *fp;
- if (f->fd == fd) {
- msg->nofd = 1;
- break;
- }
- }
- }
-
- if (!msg->nofd) {
- newf = f = calloc(1, sizeof(struct fd_store));
- if (!f) {
- fprintf(stderr, "libulockmgr: failed to allocate memory\n");
- return -ENOLCK;
- }
- }
-
- res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
- if (res == -1) {
- perror("libulockmgr: socketpair");
- free(newf);
- return -ENOLCK;
- }
-
- cfd = sv[1];
- sv[1] = msg->fd;
- res = ulockmgr_send_message(o->cfd, msg, sizeof(struct message), sv,
- msg->nofd ? 1 : 2);
- close(sv[0]);
- if (res == -1) {
- free(newf);
- close(cfd);
- return -EIO;
- }
-
- if (newf) {
- newf->fd = msg->fd;
- newf->next = o->fds;
- o->fds = newf;
- }
- if (f)
- f->inuse++;
-
- res = do_recv(cfd, msg, sizeof(struct message), MSG_WAITALL);
- if (res == -1) {
- perror("libulockmgr: recv");
- msg->error = EIO;
- } else if (res != sizeof(struct message)) {
- fprintf(stderr, "libulockmgr: recv short\n");
- msg->error = EIO;
- } else if (cmd == F_SETLKW && msg->error == EAGAIN) {
- pthread_mutex_unlock(&ulockmgr_lock);
- while (1) {
- sigset_t old;
- sigset_t unblock;
- int errno_save;
-
- sigemptyset(&unblock);
- sigaddset(&unblock, SIGUSR1);
- pthread_sigmask(SIG_UNBLOCK, &unblock, &old);
- res = do_recv(cfd, msg, sizeof(struct message), MSG_WAITALL);
- errno_save = errno;
- pthread_sigmask(SIG_SETMASK, &old, NULL);
- if (res == sizeof(struct message))
- break;
- else if (res >= 0) {
- fprintf(stderr, "libulockmgr: recv short\n");
- msg->error = EIO;
- break;
- } else if (errno_save != EINTR) {
- errno = errno_save;
- perror("libulockmgr: recv");
- msg->error = EIO;
- break;
- }
- msg->intr = 1;
- res = send(o->cfd, msg, sizeof(struct message), MSG_NOSIGNAL);
- if (res == -1) {
- perror("libulockmgr: send");
- msg->error = EIO;
- break;
- }
- if (res != sizeof(struct message)) {
- fprintf(stderr, "libulockmgr: send short\n");
- msg->error = EIO;
- break;
- }
- }
- pthread_mutex_lock(&ulockmgr_lock);
-
- }
- if (f)
- f->inuse--;
- close(cfd);
- if (unlockall) {
- for (fp = &o->fds; *fp;) {
- f = *fp;
- if (f->fd == fd && !f->inuse) {
- *fp = f->next;
- free(f);
- } else
- fp = &f->next;
- }
- if (!o->fds) {
- list_del_owner(o);
- close(o->cfd);
- free(o);
- }
- /* Force OK on unlock-all, since it _will_ succeed once the
- owner is deleted */
- msg->error = 0;
- }
-
- return -msg->error;
+ int sv[2];
+ int cfd;
+ struct owner *o;
+ struct fd_store *f = NULL;
+ struct fd_store *newf = NULL;
+ struct fd_store **fp;
+ int fd = msg->fd;
+ int cmd = msg->cmd;
+ int res;
+ int unlockall = (cmd == F_SETLK && msg->lock.l_type == F_UNLCK &&
+ msg->lock.l_start == 0 && msg->lock.l_len == 0);
+
+ for (o = owner_list.next; o != &owner_list; o = o->next)
+ if (o->id_len == id_len && memcmp(o->id, id, id_len) == 0)
+ break;
+
+ if (o == &owner_list)
+ o = NULL;
+
+ if (!o && cmd != F_GETLK && msg->lock.l_type != F_UNLCK)
+ o = ulockmgr_new_owner(id, id_len);
+
+ if (!o) {
+ if (cmd == F_GETLK) {
+ res = fcntl(msg->fd, F_GETLK, &msg->lock);
+ return (res == -1) ? -errno : 0;
+ } else if (msg->lock.l_type == F_UNLCK)
+ return 0;
+ else
+ return -ENOLCK;
+ }
+
+ if (unlockall)
+ msg->nofd = 1;
+ else {
+ for (fp = &o->fds; *fp; fp = &(*fp)->next) {
+ f = *fp;
+ if (f->fd == fd) {
+ msg->nofd = 1;
+ break;
+ }
+ }
+ }
+
+ if (!msg->nofd) {
+ newf = f = calloc(1, sizeof(struct fd_store));
+ if (!f) {
+ fprintf(stderr, "libulockmgr: failed to allocate memory\n");
+ return -ENOLCK;
+ }
+ }
+
+ res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
+ if (res == -1) {
+ perror("libulockmgr: socketpair");
+ free(newf);
+ return -ENOLCK;
+ }
+
+ cfd = sv[1];
+ sv[1] = msg->fd;
+ res = ulockmgr_send_message(o->cfd, msg, sizeof(struct message), sv,
+ msg->nofd ? 1 : 2);
+ close(sv[0]);
+ if (res == -1) {
+ free(newf);
+ close(cfd);
+ return -EIO;
+ }
+
+ if (newf) {
+ newf->fd = msg->fd;
+ newf->next = o->fds;
+ o->fds = newf;
+ }
+ if (f)
+ f->inuse++;
+
+ res = do_recv(cfd, msg, sizeof(struct message), MSG_WAITALL);
+ if (res == -1) {
+ perror("libulockmgr: recv");
+ msg->error = EIO;
+ } else if (res != sizeof(struct message)) {
+ fprintf(stderr, "libulockmgr: recv short\n");
+ msg->error = EIO;
+ } else if (cmd == F_SETLKW && msg->error == EAGAIN) {
+ pthread_mutex_unlock(&ulockmgr_lock);
+ while (1) {
+ sigset_t old;
+ sigset_t unblock;
+ int errno_save;
+
+ sigemptyset(&unblock);
+ sigaddset(&unblock, SIGUSR1);
+ pthread_sigmask(SIG_UNBLOCK, &unblock, &old);
+ res = do_recv(cfd, msg, sizeof(struct message),
+ MSG_WAITALL);
+ errno_save = errno;
+ pthread_sigmask(SIG_SETMASK, &old, NULL);
+ if (res == sizeof(struct message))
+ break;
+ else if (res >= 0) {
+ fprintf(stderr, "libulockmgr: recv short\n");
+ msg->error = EIO;
+ break;
+ } else if (errno_save != EINTR) {
+ errno = errno_save;
+ perror("libulockmgr: recv");
+ msg->error = EIO;
+ break;
+ }
+ msg->intr = 1;
+ res = send(o->cfd, msg, sizeof(struct message),
+ MSG_NOSIGNAL);
+ if (res == -1) {
+ perror("libulockmgr: send");
+ msg->error = EIO;
+ break;
+ }
+ if (res != sizeof(struct message)) {
+ fprintf(stderr, "libulockmgr: send short\n");
+ msg->error = EIO;
+ break;
+ }
+ }
+ pthread_mutex_lock(&ulockmgr_lock);
+
+ }
+ if (f)
+ f->inuse--;
+ close(cfd);
+ if (unlockall) {
+ for (fp = &o->fds; *fp;) {
+ f = *fp;
+ if (f->fd == fd && !f->inuse) {
+ *fp = f->next;
+ free(f);
+ } else
+ fp = &f->next;
+ }
+ if (!o->fds) {
+ list_del_owner(o);
+ close(o->cfd);
+ free(o);
+ }
+ /* Force OK on unlock-all, since it _will_ succeed once the
+ owner is deleted */
+ msg->error = 0;
+ }
+
+ return -msg->error;
}
#ifdef DEBUG
static uint32_t owner_hash(const unsigned char *id, size_t id_len)
{
- uint32_t h = 0;
- size_t i;
- for (i = 0; i < id_len; i++)
- h = ((h << 8) | (h >> 24)) ^ id[i];
+ uint32_t h = 0;
+ size_t i;
+ for (i = 0; i < id_len; i++)
+ h = ((h << 8) | (h >> 24)) ^ id[i];
- return h;
+ return h;
}
#endif
static int ulockmgr_canonicalize(int fd, struct flock *lock)
{
- off_t offset;
- if (lock->l_whence == SEEK_CUR) {
- offset = lseek(fd, 0, SEEK_CUR);
- if (offset == (off_t) -1)
- return -errno;
- } else if (lock->l_whence == SEEK_END) {
- struct stat stbuf;
- int res = fstat(fd, &stbuf);
- if (res == -1)
- return -errno;
-
- offset = stbuf.st_size;
- } else
- offset = 0;
-
- lock->l_whence = SEEK_SET;
- lock->l_start += offset;
-
- if (lock->l_start < 0)
- return -EINVAL;
-
- if (lock->l_len < 0) {
- lock->l_start += lock->l_len;
- if (lock->l_start < 0)
- return -EINVAL;
- lock->l_len = -lock->l_len;
- }
- if (lock->l_len && lock->l_start + lock->l_len - 1 < 0)
- return -EINVAL;
-
- return 0;
+ off_t offset;
+ if (lock->l_whence == SEEK_CUR) {
+ offset = lseek(fd, 0, SEEK_CUR);
+ if (offset == (off_t) -1)
+ return -errno;
+ } else if (lock->l_whence == SEEK_END) {
+ struct stat stbuf;
+ int res = fstat(fd, &stbuf);
+ if (res == -1)
+ return -errno;
+
+ offset = stbuf.st_size;
+ } else
+ offset = 0;
+
+ lock->l_whence = SEEK_SET;
+ lock->l_start += offset;
+
+ if (lock->l_start < 0)
+ return -EINVAL;
+
+ if (lock->l_len < 0) {
+ lock->l_start += lock->l_len;
+ if (lock->l_start < 0)
+ return -EINVAL;
+ lock->l_len = -lock->l_len;
+ }
+ if (lock->l_len && lock->l_start + lock->l_len - 1 < 0)
+ return -EINVAL;
+
+ return 0;
}
int ulockmgr_op(int fd, int cmd, struct flock *lock, const void *owner,
- size_t owner_len)
+ size_t owner_len)
{
- int err;
- struct message msg;
- sigset_t old;
- sigset_t block;
+ int err;
+ struct message msg;
+ sigset_t old;
+ sigset_t block;
- if (cmd != F_GETLK && cmd != F_SETLK && cmd != F_SETLKW)
- return -EINVAL;
+ if (cmd != F_GETLK && cmd != F_SETLK && cmd != F_SETLKW)
+ return -EINVAL;
- if (lock->l_whence != SEEK_SET && lock->l_whence != SEEK_CUR &&
- lock->l_whence != SEEK_END)
- return -EINVAL;
+ if (lock->l_whence != SEEK_SET && lock->l_whence != SEEK_CUR &&
+ lock->l_whence != SEEK_END)
+ return -EINVAL;
#ifdef DEBUG
- fprintf(stderr, "libulockmgr: %i %i %i %lli %lli own: 0x%08x\n",
- cmd, lock->l_type, lock->l_whence, lock->l_start, lock->l_len,
- owner_hash(owner, owner_len));
+ fprintf(stderr, "libulockmgr: %i %i %i %lli %lli own: 0x%08x\n",
+ cmd, lock->l_type, lock->l_whence, lock->l_start, lock->l_len,
+ owner_hash(owner, owner_len));
#endif
- /* Unlock should never block anyway */
- if (cmd == F_SETLKW && lock->l_type == F_UNLCK)
- cmd = F_SETLK;
-
- memset(&msg, 0, sizeof(struct message));
- msg.cmd = cmd;
- msg.fd = fd;
- msg.lock = *lock;
- err = ulockmgr_canonicalize(fd, &msg.lock);
- if (err)
- return err;
-
- sigemptyset(&block);
- sigaddset(&block, SIGUSR1);
- pthread_sigmask(SIG_BLOCK, &block, &old);
- pthread_mutex_lock(&ulockmgr_lock);
- err = ulockmgr_send_request(&msg, owner, owner_len);
- pthread_mutex_unlock(&ulockmgr_lock);
- pthread_sigmask(SIG_SETMASK, &old, NULL);
- if (!err && cmd == F_GETLK) {
- if (msg.lock.l_type == F_UNLCK)
- lock->l_type = F_UNLCK;
- else
- *lock = msg.lock;
- }
-
- return err;
+ /* Unlock should never block anyway */
+ if (cmd == F_SETLKW && lock->l_type == F_UNLCK)
+ cmd = F_SETLK;
+
+ memset(&msg, 0, sizeof(struct message));
+ msg.cmd = cmd;
+ msg.fd = fd;
+ msg.lock = *lock;
+ err = ulockmgr_canonicalize(fd, &msg.lock);
+ if (err)
+ return err;
+
+ sigemptyset(&block);
+ sigaddset(&block, SIGUSR1);
+ pthread_sigmask(SIG_BLOCK, &block, &old);
+ pthread_mutex_lock(&ulockmgr_lock);
+ err = ulockmgr_send_request(&msg, owner, owner_len);
+ pthread_mutex_unlock(&ulockmgr_lock);
+ pthread_sigmask(SIG_SETMASK, &old, NULL);
+ if (!err && cmd == F_GETLK) {
+ if (msg.lock.l_type == F_UNLCK)
+ lock->l_type = F_UNLCK;
+ else
+ *lock = msg.lock;
+ }
+
+ return err;
}