summaryrefslogtreecommitdiff
Diffstat
-rwxr-xr-xAndroid.mk138
-rwxr-xr-xAndroid.mk.bak89
-rwxr-xr-xCREDITS20
-rwxr-xr-xINSTALL200
-rwxr-xr-xMakefile715
-rwxr-xr-xMakefile.am106
-rwxr-xr-xMakefile.in955
-rwxr-xr-xNEWS4
-rwxr-xr-xREADME80
-rwxr-xr-xTODO.ntfsprogs126
-rwxr-xr-xaclocal.m47091
-rwxr-xr-xcompile21
-rwxr-xr-xconfig.guess292
-rw-r--r--[-rwxr-xr-x]config.h165
-rwxr-xr-xconfig.h.in110
-rwxr-xr-xconfig.log3290
-rwxr-xr-xconfig.status1220
-rwxr-xr-xconfig.sub104
-rwxr-xr-xconfigure26448
-rwxr-xr-xconfigure.ac291
-rwxr-xr-xdepcomp87
-rwxr-xr-xinclude/Makefile.in181
-rwxr-xr-xinclude/fuse-lite/Makefile.in112
-rwxr-xr-xinclude/fuse-lite/fuse.h61
-rwxr-xr-xinclude/fuse-lite/fuse_common.h49
-rwxr-xr-xinclude/fuse-lite/fuse_kernel.h6
-rwxr-xr-xinclude/fuse-lite/fuse_lowlevel.h20
-rwxr-xr-xinclude/ntfs-3g/Makefile.am4
-rwxr-xr-xinclude/ntfs-3g/Makefile.in163
-rwxr-xr-xinclude/ntfs-3g/acls.h3
-rwxr-xr-xinclude/ntfs-3g/attrib.h50
-rwxr-xr-xinclude/ntfs-3g/cache.h7
-rwxr-xr-xinclude/ntfs-3g/compat.h6
-rwxr-xr-xinclude/ntfs-3g/compress.h6
-rwxr-xr-xinclude/ntfs-3g/debug.h4
-rwxr-xr-xinclude/ntfs-3g/device.h18
-rwxr-xr-xinclude/ntfs-3g/device_io.h21
-rwxr-xr-xinclude/ntfs-3g/dir.h11
-rwxr-xr-xinclude/ntfs-3g/layout.h32
-rwxr-xr-xinclude/ntfs-3g/lcnalloc.h1
-rwxr-xr-xinclude/ntfs-3g/logging.h3
-rwxr-xr-xinclude/ntfs-3g/mst.h3
-rwxr-xr-xinclude/ntfs-3g/ntfstime.h12
-rwxr-xr-xinclude/ntfs-3g/param.h72
-rwxr-xr-xinclude/ntfs-3g/realpath.h24
-rwxr-xr-xinclude/ntfs-3g/runlist.h3
-rwxr-xr-xinclude/ntfs-3g/security.h20
-rwxr-xr-xinclude/ntfs-3g/types.h8
-rwxr-xr-xinclude/ntfs-3g/unistr.h13
-rwxr-xr-xinclude/ntfs-3g/volume.h78
-rwxr-xr-xinclude/ntfs-3g/xattrs.h75
-rwxr-xr-xinstall-sh5
-rwxr-xr-xlibfuse-lite/Makefile.am3
-rwxr-xr-xlibfuse-lite/Makefile.in188
-rwxr-xr-xlibfuse-lite/fuse.c418
-rwxr-xr-xlibfuse-lite/fuse_kern_chan.c2
-rwxr-xr-xlibfuse-lite/fuse_lowlevel.c53
-rwxr-xr-xlibfuse-lite/fuse_opt.c20
-rwxr-xr-xlibfuse-lite/fuse_session.c12
-rwxr-xr-xlibfuse-lite/fusermount.c97
-rwxr-xr-xlibfuse-lite/helper.c21
-rwxr-xr-xlibfuse-lite/mount.c486
-rwxr-xr-xlibfuse-lite/mount_util.c246
-rwxr-xr-xlibfuse-lite/mount_util.h11
-rwxr-xr-xlibntfs-3g/Makefile.am15
-rwxr-xr-xlibntfs-3g/Makefile.in420
-rwxr-xr-xlibntfs-3g/acls.c219
-rwxr-xr-xlibntfs-3g/attrib.c1205
-rwxr-xr-xlibntfs-3g/bootsect.c4
-rwxr-xr-xlibntfs-3g/cache.c7
-rwxr-xr-xlibntfs-3g/compress.c962
-rwxr-xr-xlibntfs-3g/device.c252
-rwxr-xr-xlibntfs-3g/dir.c374
-rwxr-xr-xlibntfs-3g/efs.c217
-rwxr-xr-xlibntfs-3g/index.c30
-rwxr-xr-xlibntfs-3g/inode.c46
-rwxr-xr-xlibntfs-3g/lcnalloc.c36
-rw-r--r--libntfs-3g/libntfs-3g.pc10
-rw-r--r--libntfs-3g/libntfs-3g.script.so2
-rwxr-xr-xlibntfs-3g/logfile.c23
-rwxr-xr-xlibntfs-3g/logging.c24
-rwxr-xr-xlibntfs-3g/mft.c12
-rwxr-xr-xlibntfs-3g/mst.c24
-rwxr-xr-xlibntfs-3g/object_id.c9
-rwxr-xr-xlibntfs-3g/realpath.c103
-rwxr-xr-xlibntfs-3g/reparse.c67
-rwxr-xr-xlibntfs-3g/runlist.c62
-rwxr-xr-xlibntfs-3g/security.c345
-rwxr-xr-xlibntfs-3g/unistr.c244
-rwxr-xr-xlibntfs-3g/unix_io.c19
-rwxr-xr-xlibntfs-3g/volume.c365
-rwxr-xr-xlibntfs-3g/win32_io.c708
-rwxr-xr-xlibntfs-3g/xattrs.c791
-rwxr-xr-xlibtool9301
-rwxr-xr-xltmain.sh8439
-rwxr-xr-xm4/libtool.m47377
-rwxr-xr-xm4/ltoptions.m4368
-rwxr-xr-xm4/ltsugar.m4123
-rwxr-xr-xm4/ltversion.m423
-rwxr-xr-xm4/lt~obsolete.m492
-rwxr-xr-xmissing49
-rwxr-xr-xntfsprogs/Makefile.am154
-rwxr-xr-xntfsprogs/Makefile.in1199
-rwxr-xr-xntfsprogs/attrdef.c168
-rwxr-xr-xntfsprogs/attrdef.h7
-rwxr-xr-xntfsprogs/boot.c268
-rwxr-xr-xntfsprogs/boot.h7
-rwxr-xr-xntfsprogs/cluster.c118
-rwxr-xr-xntfsprogs/cluster.h39
-rwxr-xr-xntfsprogs/list.h194
-rw-r--r--ntfsprogs/mkntfs.8290
-rwxr-xr-xntfsprogs/mkntfs.8.in290
-rwxr-xr-xntfsprogs/mkntfs.c5177
-rw-r--r--ntfsprogs/ntfscat.8136
-rwxr-xr-xntfsprogs/ntfscat.8.in136
-rwxr-xr-xntfsprogs/ntfscat.c440
-rwxr-xr-xntfsprogs/ntfscat.h46
-rwxr-xr-xntfsprogs/ntfsck.c883
-rw-r--r--ntfsprogs/ntfsclone.8391
-rwxr-xr-xntfsprogs/ntfsclone.8.in391
-rwxr-xr-xntfsprogs/ntfsclone.c2701
-rw-r--r--ntfsprogs/ntfscluster.8124
-rwxr-xr-xntfsprogs/ntfscluster.8.in124
-rwxr-xr-xntfsprogs/ntfscluster.c563
-rwxr-xr-xntfsprogs/ntfscluster.h63
-rw-r--r--ntfsprogs/ntfscmp.877
-rwxr-xr-xntfsprogs/ntfscmp.8.in77
-rwxr-xr-xntfsprogs/ntfscmp.c1012
-rw-r--r--ntfsprogs/ntfscp.8111
-rwxr-xr-xntfsprogs/ntfscp.8.in111
-rwxr-xr-xntfsprogs/ntfscp.c590
-rwxr-xr-xntfsprogs/ntfsdecrypt.c1436
-rwxr-xr-xntfsprogs/ntfsdump_logfile.c779
-rw-r--r--ntfsprogs/ntfsfix.881
-rwxr-xr-xntfsprogs/ntfsfix.8.in81
-rwxr-xr-xntfsprogs/ntfsfix.c1657
-rw-r--r--ntfsprogs/ntfsinfo.889
-rwxr-xr-xntfsprogs/ntfsinfo.8.in89
-rwxr-xr-xntfsprogs/ntfsinfo.c2384
-rw-r--r--ntfsprogs/ntfslabel.8118
-rwxr-xr-xntfsprogs/ntfslabel.8.in118
-rwxr-xr-xntfsprogs/ntfslabel.c458
-rw-r--r--ntfsprogs/ntfsls.8172
-rwxr-xr-xntfsprogs/ntfsls.8.in172
-rwxr-xr-xntfsprogs/ntfsls.c717
-rwxr-xr-xntfsprogs/ntfsmftalloc.c368
-rwxr-xr-xntfsprogs/ntfsmove.c923
-rwxr-xr-xntfsprogs/ntfsmove.h46
-rw-r--r--ntfsprogs/ntfsprogs.869
-rwxr-xr-xntfsprogs/ntfsprogs.8.in69
-rw-r--r--ntfsprogs/ntfsresize.8326
-rwxr-xr-xntfsprogs/ntfsresize.8.in326
-rwxr-xr-xntfsprogs/ntfsresize.c4497
-rwxr-xr-xntfsprogs/ntfstruncate.c809
-rw-r--r--ntfsprogs/ntfsundelete.8324
-rwxr-xr-xntfsprogs/ntfsundelete.8.in324
-rwxr-xr-xntfsprogs/ntfsundelete.c2490
-rwxr-xr-xntfsprogs/ntfsundelete.h112
-rwxr-xr-xntfsprogs/ntfswipe.c2131
-rwxr-xr-xntfsprogs/ntfswipe.h54
-rwxr-xr-xntfsprogs/sd.c607
-rwxr-xr-xntfsprogs/sd.h11
-rwxr-xr-xntfsprogs/utils.c1184
-rwxr-xr-xntfsprogs/utils.h137
-rwxr-xr-xprog.IAB1071
-rwxr-xr-xprog.IAD5
-rwxr-xr-xprog.IMB466
-rwxr-xr-xprog.IMD2
-rwxr-xr-xprog.PFI2
-rwxr-xr-xprog.PO1
-rwxr-xr-xprog.PR14
-rwxr-xr-xprog.PRI219
-rwxr-xr-xprog.PS979
-rwxr-xr-xprog.SearchResults3
-rwxr-xr-xprog.WK39
-rwxr-xr-xsrc/Makefile.am86
-rwxr-xr-xsrc/Makefile.in938
-rwxr-xr-xsrc/lowntfs-3g.c1538
-rw-r--r--src/ntfs-3g.8448
-rwxr-xr-xsrc/ntfs-3g.8.in217
-rwxr-xr-xsrc/ntfs-3g.c1357
-rw-r--r--src/ntfs-3g.probe.881
-rwxr-xr-xsrc/ntfs-3g.probe.8.in4
-rwxr-xr-xsrc/ntfs-3g.probe.c9
-rw-r--r--src/ntfs-3g.secaudit.8184
-rwxr-xr-xsrc/ntfs-3g.secaudit.8.in15
-rw-r--r--src/ntfs-3g.usermap.896
-rwxr-xr-xsrc/ntfs-3g_common.c745
-rwxr-xr-xsrc/ntfs-3g_common.h185
-rwxr-xr-xsrc/secaudit.c673
-rwxr-xr-xsrc/secaudit.h32
-rwxr-xr-xsrc/usermap.c3
-rw-r--r--[-rwxr-xr-x]stamp-h10
193 files changed, 80411 insertions, 44563 deletions
diff --git a/libfuse-lite/fuse.c b/libfuse-lite/fuse.c
index a60717b..a5bf6bd 100755
--- a/libfuse-lite/fuse.c
+++ b/libfuse-lite/fuse.c
@@ -6,6 +6,11 @@
See the file COPYING.LIB
*/
+#ifdef __SOLARIS__
+/* For pthread_rwlock_t */
+#define _GNU_SOURCE
+#endif /* __SOLARIS__ */
+
#include "config.h"
#include "fuse_i.h"
#include "fuse_lowlevel.h"
@@ -28,6 +33,10 @@
#include <sys/uio.h>
#include <sys/time.h>
+#ifdef __SOLARIS__
+#define FUSE_MAX_PATH 4096
+#endif /* __SOLARIS__ */
+
#define FUSE_DEFAULT_INTR_SIGNAL SIGUSR1
#define FUSE_UNKNOWN_INO 0xffffffff
@@ -54,13 +63,27 @@ struct fuse_config {
int intr;
int intr_signal;
int help;
+#ifdef __SOLARIS__
+ int auto_cache;
+ char *modules;
+#endif /* __SOLARIS__ */
};
struct fuse_fs {
struct fuse_operations op;
void *user_data;
+#ifdef __SOLARIS__
+ struct fuse_module *m;
+#endif /* __SOLARIS__ */
};
+#ifdef __SOLARIS__
+struct fusemod_so {
+ void *handle;
+ int ctr;
+};
+#endif /* __SOLARIS__ */
+
struct fuse {
struct fuse_session *se;
struct node **name_table;
@@ -75,7 +98,6 @@ struct fuse {
struct fuse_config conf;
int intr_installed;
struct fuse_fs *fs;
- int utime_omit_ok;
};
struct lock {
@@ -98,6 +120,12 @@ struct node {
uint64_t nlookup;
int open_count;
int is_hidden;
+#ifdef __SOLARIS__
+ struct timespec stat_updated;
+ struct timespec mtime;
+ off_t size;
+ int cache_valid;
+#endif /* __SOLARIS__ */
struct lock *locks;
};
@@ -125,6 +153,107 @@ static pthread_key_t fuse_context_key;
static pthread_mutex_t fuse_context_lock = PTHREAD_MUTEX_INITIALIZER;
static int fuse_context_ref;
+#ifdef __SOLARIS__
+
+static struct fusemod_so *fuse_current_so;
+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;
+}
+
+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;
+}
+
+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;
+}
+
+static struct fuse_module *fuse_get_module(const char *module)
+{
+ 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;
+}
+
+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);
+}
+#endif /* __SOLARIS__ */
+
static struct node *get_node_nocheck(struct fuse *f, fuse_ino_t nodeid)
{
size_t hash = nodeid % f->id_table_size;
@@ -297,10 +426,15 @@ static struct node *find_node(struct fuse *f, fuse_ino_t parent,
return node;
}
+#ifndef __SOLARIS__
static char *add_name(char **buf, unsigned *bufsize, char *s, const char *name)
+#else /* __SOLARIS__ */
+static char *add_name(char *buf, char *s, const char *name)
+#endif /* __SOLARIS__ */
{
size_t len = strlen(name);
+#ifndef __SOLARIS__
if (s - len <= *buf) {
unsigned pathlen = *bufsize - (s - *buf);
unsigned newbufsize = *bufsize;
@@ -323,6 +457,13 @@ static char *add_name(char **buf, unsigned *bufsize, char *s, const char *name)
*bufsize = newbufsize;
}
s -= len;
+#else /* ! __SOLARIS__ */
+ s -= len;
+ if (s <= buf) {
+ fprintf(stderr, "fuse: path too long: ...%s\n", s + len);
+ return NULL;
+ }
+#endif /* __SOLARIS__ */
strncpy(s, name, len);
s--;
*s = '/';
@@ -332,6 +473,42 @@ static char *add_name(char **buf, unsigned *bufsize, char *s, const char *name)
static char *get_path_name(struct fuse *f, fuse_ino_t nodeid, const char *name)
{
+#ifdef __SOLARIS__
+ char buf[FUSE_MAX_PATH];
+ char *s = buf + FUSE_MAX_PATH - 1;
+ struct node *node;
+
+ *s = '\0';
+
+ 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;
+ }
+
+ 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);
+
+#else /* __SOLARIS__ */
+
unsigned bufsize = 256;
char *buf;
char *s;
@@ -376,6 +553,7 @@ static char *get_path_name(struct fuse *f, fuse_ino_t nodeid, const char *name)
out_free:
free(buf);
return NULL;
+#endif /* __SOLARIS__ */
}
static char *get_path(struct fuse *f, fuse_ino_t nodeid)
@@ -678,13 +856,13 @@ int fuse_fs_flush(struct fuse_fs *fs, const char *path,
}
#if HAVE_SYS_STATVFS_H
-int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statfs *buf)
+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 fs->op.statfs(path, buf);
else {
- buf->f_namelen = 255;
+ buf->f_namemax = 255;
buf->f_bsize = 512;
return 0;
}
@@ -932,6 +1110,44 @@ static int hide_node(struct fuse *f, const char *oldpath,
return err;
}
+#ifdef __SOLARIS__
+
+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;
+}
+
+#ifndef CLOCK_MONOTONIC
+#define CLOCK_MONOTONIC CLOCK_REALTIME
+#endif
+
+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 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);
+}
+
+#endif /* __SOLARIS__ */
+
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)
@@ -954,6 +1170,13 @@ static int lookup_path(struct fuse *f, fuse_ino_t nodeid,
e->generation = node->generation;
e->entry_timeout = f->conf.entry_timeout;
e->attr_timeout = f->conf.attr_timeout;
+#ifdef __SOLARIS__
+ if (f->conf.auto_cache) {
+ pthread_mutex_lock(&f->lock);
+ update_stat(node, &e->attr);
+ pthread_mutex_unlock(&f->lock);
+ }
+#endif /* __SOLARIS__ */
set_stat(f, e->ino, &e->attr);
if (f->conf.debug)
fprintf(stderr, " NODEID: %lu\n", (unsigned long) e->ino);
@@ -1030,7 +1253,11 @@ static struct fuse *req_fuse_prepare(fuse_req_t req)
return c->ctx.fuse;
}
+#ifndef __SOLARIS__
static void reply_err(fuse_req_t req, int err)
+#else /* __SOLARIS__ */
+static inline void reply_err(fuse_req_t req, int err)
+#endif /* __SOLARIS__ */
{
/* fuse_reply_err() uses non-negated errno values */
fuse_reply_err(req, -err);
@@ -1069,6 +1296,10 @@ 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);
+#ifdef __SOLARIS__
+ if (fs->m)
+ fuse_put_module(fs->m);
+#endif /* __SOLARIS__ */
free(fs);
}
@@ -1145,6 +1376,13 @@ static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino,
}
pthread_rwlock_unlock(&f->tree_lock);
if (!err) {
+#ifdef __SOLARIS__
+ if (f->conf.auto_cache) {
+ pthread_mutex_lock(&f->lock);
+ update_stat(get_node(f, ino), &buf);
+ pthread_mutex_unlock(&f->lock);
+ }
+#endif /* __SOLARIS__ */
set_stat(f, ino, &buf);
fuse_reply_attr(req, &buf, f->conf.attr_timeout);
} else
@@ -1191,7 +1429,7 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
err = fuse_fs_truncate(f->fs, path, attr->st_size);
}
#ifdef HAVE_UTIMENSAT
- if (!err && f->utime_omit_ok &&
+ if (!err &&
(valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) {
struct timespec tv[2];
@@ -1229,6 +1467,13 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
}
pthread_rwlock_unlock(&f->tree_lock);
if (!err) {
+#ifdef __SOLARIS__
+ if (f->conf.auto_cache) {
+ pthread_mutex_lock(&f->lock);
+ update_stat(get_node(f, ino), &buf);
+ pthread_mutex_unlock(&f->lock);
+ }
+#endif /* __SOLARIS__ */
set_stat(f, ino, &buf);
fuse_reply_attr(req, &buf, f->conf.attr_timeout);
} else
@@ -1573,6 +1818,47 @@ static void fuse_lib_create(fuse_req_t req, fuse_ino_t parent,
pthread_rwlock_unlock(&f->tree_lock);
}
+#ifdef __SOLARIS__
+
+static double diff_timespec(const struct timespec *t1,
+ const struct timespec *t2)
+{
+ 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);
+}
+
+#endif /* __SOLARIS__ */
+
static void fuse_lib_open(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi)
{
@@ -1592,6 +1878,11 @@ static void fuse_lib_open(fuse_req_t req, fuse_ino_t ino,
fi->direct_io = 1;
if (f->conf.kernel_cache)
fi->keep_cache = 1;
+#ifdef __SOLARIS__
+
+ if (f->conf.auto_cache)
+ open_auto_cache(f, ino, path, fi);
+#endif /* __SOLARIS__ */
}
fuse_finish_interrupt(f, req, &d);
}
@@ -1777,7 +2068,9 @@ static void fuse_lib_opendir(fuse_req_t req, fuse_ino_t ino,
}
} else {
reply_err(req, err);
+#ifndef __SOLARIS__
pthread_mutex_destroy(&dh->lock);
+#endif /* ! __SOLARIS__ */
free(dh);
}
free(path);
@@ -1791,12 +2084,17 @@ static int extend_contents(struct fuse_dh *dh, unsigned minsize)
unsigned newsize = dh->size;
if (!newsize)
newsize = 1024;
+#ifndef __SOLARIS__
while (newsize < minsize) {
if (newsize >= 0x80000000)
newsize = 0xffffffff;
else
newsize *= 2;
}
+#else /* __SOLARIS__ */
+ while (newsize < minsize)
+ newsize *= 2;
+#endif /* __SOLARIS__ */
newptr = (char *) realloc(dh->contents, newsize);
if (!newptr) {
@@ -1971,12 +2269,11 @@ static void fuse_lib_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync,
reply_err(req, err);
}
+#if HAVE_SYS_STATVFS_H
static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino)
{
struct fuse *f = req_fuse_prepare(req);
-
-#if HAVE_SYS_STATVFS_H
- struct statfs buf;
+ struct statvfs buf;
char *path;
int err;
@@ -2002,8 +2299,8 @@ static void fuse_lib_statfs(fuse_req_t req, fuse_ino_t ino)
fuse_reply_statfs(req, &buf);
else
reply_err(req, err);
-#endif
}
+#endif
static void fuse_lib_setxattr(fuse_req_t req, fuse_ino_t ino, const char *name,
const char *value, size_t size, int flags)
@@ -2450,7 +2747,9 @@ static struct fuse_lowlevel_ops fuse_path_ops = {
.readdir = fuse_lib_readdir,
.releasedir = fuse_lib_releasedir,
.fsyncdir = fuse_lib_fsyncdir,
+#if HAVE_SYS_STATVFS_H
.statfs = fuse_lib_statfs,
+#endif
.setxattr = fuse_lib_setxattr,
.getxattr = fuse_lib_getxattr,
.listxattr = fuse_lib_listxattr,
@@ -2506,6 +2805,10 @@ static const struct fuse_opt fuse_lib_opts[] = {
FUSE_LIB_OPT("readdir_ino", readdir_ino, 1),
FUSE_LIB_OPT("direct_io", direct_io, 1),
FUSE_LIB_OPT("kernel_cache", kernel_cache, 1),
+#ifdef __SOLARIS__
+ FUSE_LIB_OPT("auto_cache", auto_cache, 1),
+ FUSE_LIB_OPT("noauto_cache", auto_cache, 0),
+#endif /* __SOLARIS__ */
FUSE_LIB_OPT("umask=", set_mode, 1),
FUSE_LIB_OPT("umask=%o", umask, 0),
FUSE_LIB_OPT("uid=", set_uid, 1),
@@ -2519,6 +2822,9 @@ static const struct fuse_opt fuse_lib_opts[] = {
FUSE_LIB_OPT("negative_timeout=%lf", negative_timeout, 0),
FUSE_LIB_OPT("intr", intr, 1),
FUSE_LIB_OPT("intr_signal=%d", intr_signal, 0),
+#ifdef __SOLARIS__
+ FUSE_LIB_OPT("modules=%s", modules, 0),
+#endif /* __SOLARIS__ */
FUSE_OPT_END
};
@@ -2530,6 +2836,9 @@ static void fuse_lib_help(void)
" -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"
+#ifdef __SOLARIS__
+" -o [no]auto_cache enable caching based on modification times\n"
+#endif /* __SOLARIS__ */
" -o umask=M set file permissions (octal)\n"
" -o uid=N set file owner\n"
" -o gid=N set file group\n"
@@ -2539,9 +2848,42 @@ static void fuse_lib_help(void)
" -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"
+#ifdef __SOLARIS__
+" -o modules=M1[:M2...] names of modules to push onto filesystem stack\n"
+#endif /* __SOLARIS__ */
"\n", FUSE_DEFAULT_INTR_SIGNAL);
}
+#ifdef __SOLARIS__
+
+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);
+}
+
+int fuse_is_lib_option(const char *opt)
+{
+ return fuse_lowlevel_is_lib_option(opt) ||
+ fuse_opt_match(fuse_lib_opts, opt);
+}
+
+#endif /* __SOLARIS__ */
+
static int fuse_lib_opt_proc(void *data, const char *arg, int key,
struct fuse_args *outargs)
{
@@ -2590,6 +2932,32 @@ static void fuse_restore_intr_signal(int signum)
sigaction(signum, &sa, NULL);
}
+#ifdef __SOLARIS__
+
+static int fuse_push_module(struct fuse *f, const char *module,
+ struct fuse_args *args)
+{
+ struct fuse_fs *newfs;
+ struct fuse_module *m = fuse_get_module(module);
+ struct fuse_fs *fs[2];
+
+ fs[0] = f->fs;
+ fs[1] = NULL;
+ 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;
+}
+
+#endif /* __SOLARIS__ */
+
struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
void *user_data)
{
@@ -2635,7 +3003,6 @@ struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
goto out_free;
f->fs = fs;
- f->utime_omit_ok = fs->op.flag_utime_omit_ok;
/* Oh f**k, this is ugly! */
if (!fs->op.lock) {
@@ -2643,7 +3010,6 @@ struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
llop.setlk = NULL;
}
-// f->conf.direct_io = 1;
f->conf.entry_timeout = 1.0;
f->conf.attr_timeout = 1.0;
f->conf.negative_timeout = 0.0;
@@ -2652,10 +3018,26 @@ struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
if (fuse_opt_parse(args, &f->conf, fuse_lib_opts, fuse_lib_opt_proc) == -1)
goto out_free_fs;
+#ifdef __SOLARIS__
+ 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;
+ }
+ }
+#endif /* __SOLARIS__ */
+
if (!f->conf.ac_attr_timeout_set)
f->conf.ac_attr_timeout = f->conf.attr_timeout;
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
/*
* In FreeBSD, we always use these settings as inode numbers are needed to
* make getcwd(3) work.
@@ -2664,14 +3046,17 @@ struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
#endif
f->se = fuse_lowlevel_new(args, &llop, sizeof(llop), f);
+
if (f->se == NULL) {
+#ifdef __SOLARIS__
+ if (f->conf.help)
+ fuse_lib_help_modules();
+#endif /* __SOLARIS__ */
goto out_free_fs;
}
fuse_session_add_chan(f->se, ch);
- if (f->conf.debug)
- fprintf(stderr, "utime_omit_ok: %i\n", f->utime_omit_ok);
f->ctr = 0;
f->generation = 0;
/* FIXME: Dynamic hash table */
@@ -2734,6 +3119,9 @@ struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
called on the filesystem without init being called first */
fs->op.destroy = NULL;
fuse_fs_destroy(f->fs);
+#ifdef __SOLARIS__
+ free(f->conf.modules);
+#endif /* __SOLARIS__ */
out_free:
free(f);
out_delete_context_key:
@@ -2783,7 +3171,9 @@ void fuse_destroy(struct fuse *f)
pthread_mutex_destroy(&f->lock);
pthread_rwlock_destroy(&f->tree_lock);
fuse_session_destroy(f->se);
+#ifdef __SOLARIS__
+ free(f->conf.modules);
+#endif /* __SOLARIS__ */
free(f);
fuse_delete_context_key();
}
-