summaryrefslogtreecommitdiffstats
path: root/xlators/mount
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mount')
-rw-r--r--xlators/mount/fuse/src/Makefile.am2
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c582
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h28
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c31
-rw-r--r--xlators/mount/fuse/src/fuse-resolve.c30
-rwxr-xr-xxlators/mount/fuse/utils/mount.glusterfs.in200
6 files changed, 655 insertions, 218 deletions
diff --git a/xlators/mount/fuse/src/Makefile.am b/xlators/mount/fuse/src/Makefile.am
index 4e9287067..653121d18 100644
--- a/xlators/mount/fuse/src/Makefile.am
+++ b/xlators/mount/fuse/src/Makefile.am
@@ -24,7 +24,7 @@ endif
fuse_la_SOURCES = fuse-helpers.c fuse-resolve.c fuse-bridge.c \
$(CONTRIBDIR)/fuse-lib/misc.c $(mount_source)
-fuse_la_LDFLAGS = -module -avoidversion
+fuse_la_LDFLAGS = -module -avoid-version
fuse_la_LIBADD = @GF_FUSE_LDADD@
AM_CPPFLAGS = $(GF_CPPFLAGS) \
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 68f9e7541..6a5587c2d 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -10,6 +10,13 @@
#include <sys/wait.h>
#include "fuse-bridge.h"
+#include "mount-gluster-compat.h"
+#include "glusterfs.h"
+#include "glusterfs-acl.h"
+
+#ifdef __NetBSD__
+#undef open /* in perfuse.h, pulled from mount-gluster-compat.h */
+#endif
static int gf_fuse_conn_err_log;
static int gf_fuse_xattr_enotsup_log;
@@ -46,6 +53,46 @@ fuse_invalidate(xlator_t *this, inode_t *inode)
return 0;
}
+static int32_t
+fuse_forget_cbk (xlator_t *this, inode_t *inode)
+{
+ //Nothing to free in inode ctx, hence return.
+ return 0;
+}
+
+void
+fuse_inode_set_need_lookup (inode_t *inode, xlator_t *this)
+{
+ uint64_t need_lookup = 1;
+
+ if (!inode || !this)
+ return;
+
+ inode_ctx_set (inode, this, &need_lookup);
+
+ return;
+}
+
+
+gf_boolean_t
+fuse_inode_needs_lookup (inode_t *inode, xlator_t *this)
+{
+ uint64_t need_lookup = 0;
+ gf_boolean_t ret = _gf_false;
+
+ if (!inode || !this)
+ return ret;
+
+ inode_ctx_get (inode, this, &need_lookup);
+ if (need_lookup)
+ ret = _gf_true;
+ need_lookup = 0;
+ inode_ctx_set (inode, this, &need_lookup);
+
+ return ret;
+}
+
+
fuse_fd_ctx_t *
__fuse_fd_ctx_check_n_create (xlator_t *this, fd_t *fd)
{
@@ -366,7 +413,7 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s() %s => %"PRId64,
+ "%"PRIu64": %s() %s => %"PRIu64,
frame->root->unique, gf_fop_list[frame->root->op],
state->loc.path, buf->ia_ino);
@@ -458,6 +505,13 @@ fuse_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == -1 && state->is_revalidate == 1) {
itable = state->itable;
+ /*
+ * A stale mapping might exist for a dentry/inode that has been
+ * removed from another client.
+ */
+ if (op_errno == ENOENT)
+ inode_unlink(state->loc.inode, state->loc.parent,
+ state->loc.name);
inode_unref (state->loc.inode);
state->loc.inode = inode_new (itable);
state->is_revalidate = 2;
@@ -517,8 +571,8 @@ fuse_lookup_resume (fuse_state_t *state)
static void
fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- char *name = msg;
- fuse_state_t *state = NULL;
+ char *name = msg;
+ fuse_state_t *state = NULL;
GET_STATE (this, finh, state);
@@ -526,15 +580,27 @@ fuse_lookup (xlator_t *this, fuse_in_header_t *finh, void *msg)
finh->nodeid, name);
fuse_resolve_and_resume (state, fuse_lookup_resume);
+
+ return;
+}
+
+static inline void
+do_forget(xlator_t *this, uint64_t unique, uint64_t nodeid, uint64_t nlookup)
+{
+ inode_t *fuse_inode = fuse_ino_to_inode(nodeid, this);
+
+ fuse_log_eh(this, "%"PRIu64": FORGET %"PRIu64"/%"PRIu64" gfid: (%s)",
+ unique, nodeid, nlookup, uuid_utoa(fuse_inode->gfid));
+
+ inode_forget(fuse_inode, nlookup);
+ inode_unref(fuse_inode);
}
static void
fuse_forget (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- struct fuse_forget_in *ffi = msg;
-
- inode_t *fuse_inode;
+ struct fuse_forget_in *ffi = msg;
if (finh->nodeid == 1) {
GF_FREE (finh);
@@ -545,16 +611,29 @@ fuse_forget (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"PRIu64": FORGET %"PRIu64"/%"PRIu64,
finh->unique, finh->nodeid, ffi->nlookup);
- fuse_inode = fuse_ino_to_inode (finh->nodeid, this);
+ do_forget(this, finh->unique, finh->nodeid, ffi->nlookup);
- fuse_log_eh (this, "%"PRIu64": FORGET %"PRIu64"/%"PRIu64" gfid: (%s)",
- finh->unique, finh->nodeid, ffi->nlookup,
- uuid_utoa (fuse_inode->gfid));
+ GF_FREE (finh);
+}
- inode_forget (fuse_inode, ffi->nlookup);
- inode_unref (fuse_inode);
+static void
+fuse_batch_forget(xlator_t *this, fuse_in_header_t *finh, void *msg)
+{
+ struct fuse_batch_forget_in *fbfi = msg;
+ struct fuse_forget_one *ffo = (struct fuse_forget_one *) (fbfi + 1);
+ int i;
- GF_FREE (finh);
+ gf_log("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": BATCH_FORGET %"PRIu64"/%"PRIu32,
+ finh->unique, finh->nodeid, fbfi->count);
+
+ for (i = 0; i < fbfi->count; i++) {
+ if (ffo[i].nodeid == 1)
+ continue;
+ do_forget(this, finh->unique, ffo[i].nodeid, ffo[i].nlookup);
+ }
+
+ GF_FREE(finh);
}
static int
@@ -575,7 +654,7 @@ fuse_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s() %s => %"PRId64, frame->root->unique,
+ "%"PRIu64": %s() %s => %"PRIu64, frame->root->unique,
gf_fop_list[frame->root->op],
state->loc.path ? state->loc.path : "ERR",
prebuf->ia_ino);
@@ -627,10 +706,10 @@ fuse_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fuse_log_eh (this, "op_ret: %d, op_errno: %d, %"PRIu64": %s() %s => "
"gfid: %s", op_ret, op_errno, frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path,
- uuid_utoa (state->loc.inode->gfid));
+ state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : "");
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s() %s => %"PRId64, frame->root->unique,
+ "%"PRIu64": %s() %s => %"PRIu64, frame->root->unique,
gf_fop_list[frame->root->op],
state->loc.path ? state->loc.path : "ERR",
buf->ia_ino);
@@ -911,11 +990,11 @@ fuse_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fuse_log_eh(this, "op_ret: %d, op_errno: %d, %"PRIu64", %s() %s => "
"gfid: %s", op_ret, op_errno, frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path,
- uuid_utoa (state->loc.inode->gfid));
+ state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : "");
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s() %s => %"PRId64, frame->root->unique,
+ "%"PRIu64": %s() %s => %"PRIu64, frame->root->unique,
gf_fop_list[frame->root->op],
state->loc.path ? state->loc.path : "ERR",
statpost->ia_ino);
@@ -1170,7 +1249,7 @@ fuse_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
fuse_log_eh (this, "op_ret: %d, op_errno: %d, %"PRIu64": %s() %s => "
"gfid: %s", op_ret, op_errno, frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path,
- uuid_utoa (state->loc.inode->gfid));
+ state->loc.inode ? uuid_utoa (state->loc.inode->gfid) : "");
if (op_ret == 0) {
inode_unlink (state->loc.inode, state->loc.parent,
@@ -1313,7 +1392,7 @@ fuse_mknod_resume (fuse_state_t *state)
{
if (!state->loc.parent) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "MKNOD %"PRId64"/%s (%s/%s) resolution failed",
+ "MKNOD %"PRIu64"/%s (%s/%s) resolution failed",
state->finh->nodeid, state->resolve.bname,
uuid_utoa (state->resolve.gfid), state->resolve.bname);
send_fuse_err (state->this, state->finh, ENOENT);
@@ -1383,7 +1462,7 @@ fuse_mkdir_resume (fuse_state_t *state)
{
if (!state->loc.parent) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "MKDIR %"PRId64" (%s/%s) resolution failed",
+ "MKDIR %"PRIu64" (%s/%s) resolution failed",
state->finh->nodeid, uuid_utoa (state->resolve.gfid),
state->resolve.bname);
send_fuse_err (state->this, state->finh, ENOENT);
@@ -1445,7 +1524,7 @@ fuse_unlink_resume (fuse_state_t *state)
{
if (!state->loc.parent || !state->loc.inode) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "UNLINK %"PRId64" (%s/%s) resolution failed",
+ "UNLINK %"PRIu64" (%s/%s) resolution failed",
state->finh->nodeid, uuid_utoa (state->resolve.gfid),
state->resolve.bname);
send_fuse_err (state->this, state->finh, ENOENT);
@@ -1481,7 +1560,7 @@ fuse_rmdir_resume (fuse_state_t *state)
{
if (!state->loc.parent || !state->loc.inode) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "RMDIR %"PRId64" (%s/%s) resolution failed",
+ "RMDIR %"PRIu64" (%s/%s) resolution failed",
state->finh->nodeid, uuid_utoa (state->resolve.gfid),
state->resolve.bname);
send_fuse_err (state->this, state->finh, ENOENT);
@@ -1517,7 +1596,7 @@ fuse_symlink_resume (fuse_state_t *state)
{
if (!state->loc.parent) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "SYMLINK %"PRId64" (%s/%s) -> %s resolution failed",
+ "SYMLINK %"PRIu64" (%s/%s) -> %s resolution failed",
state->finh->nodeid, uuid_utoa (state->resolve.gfid),
state->resolve.bname, state->name);
send_fuse_err (state->this, state->finh, ENOENT);
@@ -1583,14 +1662,14 @@ fuse_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
"path: %s parent: %s ==> path: %s parent: %s"
"gfid: %s", op_ret, op_errno, frame->root->unique,
gf_fop_list[frame->root->op], state->loc.path,
- uuid_utoa (state->loc.parent->gfid),
+ state->loc.parent?uuid_utoa (state->loc.parent->gfid):"",
state->loc2.path,
- uuid_utoa (state->loc2.parent->gfid),
- uuid_utoa (state->loc.inode->gfid));
+ state->loc2.parent?uuid_utoa (state->loc2.parent->gfid):"",
+ state->loc.inode?uuid_utoa (state->loc.inode->gfid):"");
if (op_ret == 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s -> %s => 0 (buf->ia_ino=%"PRId64")",
+ "%"PRIu64": %s -> %s => 0 (buf->ia_ino=%"PRIu64")",
frame->root->unique, state->loc.path, state->loc2.path,
buf->ia_ino);
@@ -1765,7 +1844,7 @@ fuse_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
foo.open_flags |= FOPEN_DIRECT_IO;
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": %s() %s => %p (ino=%"PRId64")",
+ "%"PRIu64": %s() %s => %p (ino=%"PRIu64")",
frame->root->unique, gf_fop_list[frame->root->op],
state->loc.path, fd, buf->ia_ino);
@@ -2024,7 +2103,7 @@ fuse_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret >= 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": READ => %d/%"GF_PRI_SIZET",%"PRId64"/%"PRId64,
+ "%"PRIu64": READ => %d/%"GF_PRI_SIZET",%"PRId64"/%"PRIu64,
frame->root->unique,
op_ret, state->size, state->off, stbuf->ia_size);
@@ -2110,7 +2189,7 @@ fuse_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (op_ret >= 0) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": WRITE => %d/%"GF_PRI_SIZET",%"PRId64"/%"PRId64,
+ "%"PRIu64": WRITE => %d/%"GF_PRI_SIZET",%"PRId64"/%"PRIu64,
frame->root->unique,
op_ret, state->size, state->off, stbuf->ia_size);
@@ -2152,7 +2231,7 @@ fuse_write_resume (fuse_state_t *state)
iobref_add (iobref, iobuf);
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": WRITE (%p, size=%"PRId64", offset=%"PRId64")",
+ "%"PRIu64": WRITE (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
state->finh->unique, state->fd, state->size, state->off);
FUSE_FOP (state, fuse_writev_cbk, GF_FOP_WRITE, writev, state->fd,
@@ -2452,6 +2531,11 @@ fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
strlen (entry->d_name));
}
+ if (size <= 0) {
+ send_fuse_data (this, finh, 0, 0);
+ goto out;
+ }
+
buf = GF_CALLOC (1, size, gf_fuse_mt_char);
if (!buf) {
gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
@@ -2485,7 +2569,7 @@ void
fuse_readdir_resume (fuse_state_t *state)
{
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
- "%"PRIu64": READDIR (%p, size=%zu, offset=%"PRId64")",
+ "%"PRIu64": READDIR (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
state->finh->unique, state->fd, state->size, state->off);
FUSE_FOP (state, fuse_readdir_cbk, GF_FOP_READDIR,
@@ -2511,6 +2595,182 @@ fuse_readdir (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_resolve_and_resume (state, fuse_readdir_resume);
}
+
+static int
+fuse_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+ dict_t *xdata)
+{
+ fuse_state_t *state = NULL;
+ fuse_in_header_t *finh = NULL;
+ int size = 0;
+ char *buf = NULL;
+ gf_dirent_t *entry = NULL;
+ struct fuse_direntplus *fde = NULL;
+ struct fuse_entry_out *feo = NULL;
+ fuse_private_t *priv = NULL;
+
+ state = frame->root->state;
+ finh = state->finh;
+ priv = this->private;
+
+ if (op_ret < 0) {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING,
+ "%"PRIu64": READDIRP => -1 (%s)", frame->root->unique,
+ strerror (op_errno));
+
+ send_fuse_err (this, finh, op_errno);
+ goto out;
+ }
+
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": READDIRP => %d/%"GF_PRI_SIZET",%"PRId64,
+ frame->root->unique, op_ret, state->size, state->off);
+
+ list_for_each_entry (entry, &entries->list, list) {
+ size += FUSE_DIRENT_ALIGN (FUSE_NAME_OFFSET_DIRENTPLUS +
+ strlen (entry->d_name));
+ }
+
+ if (size <= 0) {
+ send_fuse_data (this, finh, 0, 0);
+ goto out;
+ }
+
+ buf = GF_CALLOC (1, size, gf_fuse_mt_char);
+ if (!buf) {
+ gf_log ("glusterfs-fuse", GF_LOG_DEBUG,
+ "%"PRIu64": READDIRP => -1 (%s)", frame->root->unique,
+ strerror (ENOMEM));
+ send_fuse_err (this, finh, ENOMEM);
+ goto out;
+ }
+
+ size = 0;
+ list_for_each_entry (entry, &entries->list, list) {
+ inode_t *linked_inode;
+
+ fde = (struct fuse_direntplus *)(buf + size);
+ feo = &fde->entry_out;
+ fde->dirent.ino = entry->d_ino;
+ fde->dirent.off = entry->d_off;
+ fde->dirent.type = entry->d_type;
+ fde->dirent.namelen = strlen (entry->d_name);
+ strncpy (fde->dirent.name, entry->d_name, fde->dirent.namelen);
+ size += FUSE_DIRENTPLUS_SIZE (fde);
+
+ if (!entry->inode)
+ continue;
+
+ entry->d_stat.ia_blksize = this->ctx->page_size;
+ gf_fuse_stat2attr (&entry->d_stat, &feo->attr, priv->enable_ino32);
+
+ linked_inode = inode_link (entry->inode, state->fd->inode,
+ entry->d_name, &entry->d_stat);
+ if (!linked_inode)
+ continue;
+
+ inode_lookup (linked_inode);
+
+ feo->nodeid = inode_to_fuse_nodeid (linked_inode);
+
+ fuse_inode_set_need_lookup (linked_inode, this);
+
+ inode_unref (linked_inode);
+
+ feo->entry_valid =
+ calc_timeout_sec (priv->entry_timeout);
+ feo->entry_valid_nsec =
+ calc_timeout_nsec (priv->entry_timeout);
+ feo->attr_valid =
+ calc_timeout_sec (priv->attribute_timeout);
+ feo->attr_valid_nsec =
+ calc_timeout_nsec (priv->attribute_timeout);
+ }
+
+ send_fuse_data (this, finh, buf, size);
+out:
+ free_fuse_state (state);
+ STACK_DESTROY (frame->root);
+ GF_FREE (buf);
+ return 0;
+
+}
+
+
+void
+fuse_readdirp_resume (fuse_state_t *state)
+{
+ gf_log ("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": READDIRP (%p, size=%"GF_PRI_SIZET", offset=%"PRId64")",
+ state->finh->unique, state->fd, state->size, state->off);
+
+ FUSE_FOP (state, fuse_readdirp_cbk, GF_FOP_READDIRP,
+ readdirp, state->fd, state->size, state->off, state->xdata);
+}
+
+
+static void
+fuse_readdirp (xlator_t *this, fuse_in_header_t *finh, void *msg)
+{
+ struct fuse_read_in *fri = msg;
+
+ fuse_state_t *state = NULL;
+ fd_t *fd = NULL;
+
+ GET_STATE (this, finh, state);
+ state->size = fri->size;
+ state->off = fri->offset;
+ fd = FH_TO_FD (fri->fh);
+ state->fd = fd;
+
+ fuse_resolve_fd_init (state, &state->resolve, fd);
+
+ fuse_resolve_and_resume (state, fuse_readdirp_resume);
+}
+
+static int
+fuse_fallocate_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
+ struct iatt *postbuf, dict_t *xdata)
+{
+ return fuse_err_cbk(frame, cookie, this, op_ret, op_errno, xdata);
+}
+
+static void
+fuse_fallocate_resume(fuse_state_t *state)
+{
+ gf_log("glusterfs-fuse", GF_LOG_TRACE,
+ "%"PRIu64": FALLOCATE (%p, flags=%d, size=%zu, offset=%"PRId64")",
+ state->finh->unique, state->fd, state->flags, state->size,
+ state->off);
+
+ if (state->flags & FALLOC_FL_PUNCH_HOLE)
+ FUSE_FOP(state, fuse_fallocate_cbk, GF_FOP_DISCARD, discard,
+ state->fd, state->off, state->size, state->xdata);
+ else
+ FUSE_FOP(state, fuse_fallocate_cbk, GF_FOP_FALLOCATE, fallocate,
+ state->fd, (state->flags & FALLOC_FL_KEEP_SIZE),
+ state->off, state->size, state->xdata);
+}
+
+static void
+fuse_fallocate(xlator_t *this, fuse_in_header_t *finh, void *msg)
+{
+ struct fuse_fallocate_in *ffi = msg;
+ fuse_state_t *state = NULL;
+
+ GET_STATE(this, finh, state);
+ state->off = ffi->offset;
+ state->size = ffi->length;
+ state->flags = ffi->mode;
+ state->fd = FH_TO_FD(ffi->fh);
+
+ fuse_resolve_fd_init(state, &state->resolve, state->fd);
+ fuse_resolve_and_resume(state, fuse_fallocate_resume);
+}
+
+
static void
fuse_releasedir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
@@ -2752,8 +3012,8 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
}
if (!priv->acl) {
- if ((strcmp (name, "system.posix_acl_access") == 0) ||
- (strcmp (name, "system.posix_acl_default") == 0)) {
+ if ((strcmp (name, POSIX_ACL_ACCESS_XATTR) == 0) ||
+ (strcmp (name, POSIX_ACL_DEFAULT_XATTR) == 0)) {
send_fuse_err (this, finh, EOPNOTSUPP);
GF_FREE (finh);
return;
@@ -2863,10 +3123,10 @@ send_fuse_xattr (xlator_t *this, fuse_in_header_t *finh, const char *value,
* when it tries to setxattr() for selinux xattrs
*/
static int
-fuse_filter_xattr(xlator_t *this, char *key)
+fuse_filter_xattr(char *key)
{
int need_filter = 0;
- struct fuse_private *priv = this->private;
+ struct fuse_private *priv = THIS->private;
if ((priv->client_pid == GF_CLIENT_PID_GSYNCD)
&& fnmatch ("*.selinux*", key, FNM_PERIOD) == 0)
@@ -2887,6 +3147,7 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
data_t *value_data = NULL;
int ret = -1;
int32_t len = 0;
+ int32_t len_next = 0;
state = frame->root->state;
finh = state->finh;
@@ -2917,32 +3178,20 @@ fuse_xattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
/* we need to invoke fuse_filter_xattr() twice. Once
* while counting size and then while filling buffer
*/
- int _get_total_len (dict_t *d, char *k, data_t *v,
- void *tmp)
- {
- if (!fuse_filter_xattr (this, k))
- len += strlen (k) + 1;
- return 0;
- }
- dict_foreach (dict, _get_total_len, NULL);
+ len = dict_keys_join (NULL, 0, dict, fuse_filter_xattr);
+ if (len < 0)
+ goto out;
value = alloca (len + 1);
if (!value)
goto out;
- len = 0;
-
- int _set_listxattr_keys (dict_t *d, char *k, data_t *v,
- void *tmp)
- {
- if (!fuse_filter_xattr (this, k)) {
- strcpy (value + len, k);
- value[len + strlen (k)] = '\0';
- len += strlen (k) + 1;
- }
- return 0;
- }
- dict_foreach (dict, _set_listxattr_keys, NULL);
+ len_next = dict_keys_join (value, len, dict,
+ fuse_filter_xattr);
+ if (len_next != len)
+ gf_log (THIS->name, GF_LOG_ERROR,
+ "sizes not equal %d != %d",
+ len, len_next);
send_fuse_xattr (this, finh, value, len, state->size);
} /* if(state->name)...else */
@@ -2988,6 +3237,8 @@ out:
void
fuse_getxattr_resume (fuse_state_t *state)
{
+ char *value = NULL;
+
if (!state->loc.inode) {
gf_log ("glusterfs-fuse", GF_LOG_WARNING,
"%"PRIu64": GETXATTR %s/%"PRIu64" (%s) "
@@ -3005,6 +3256,46 @@ fuse_getxattr_resume (fuse_state_t *state)
state->fd = fd_lookup (state->loc.inode, state->finh->pid);
#endif /* GF_TEST_FFOP */
+ if (state->name &&
+ (strcmp (state->name, VIRTUAL_GFID_XATTR_KEY) == 0)) {
+ /* send glusterfs gfid in binary form */
+
+ value = GF_CALLOC (16 + 1, sizeof(char),
+ gf_common_mt_char);
+ if (!value) {
+ send_fuse_err (state->this, state->finh, ENOMEM);
+ goto internal_out;
+ }
+ memcpy (value, state->loc.inode->gfid, 16);
+
+ send_fuse_xattr (THIS, state->finh, value, 16, state->size);
+ GF_FREE (value);
+ internal_out:
+ free_fuse_state (state);
+ return;
+ }
+
+ if (state->name &&
+ (strcmp (state->name, VIRTUAL_GFID_XATTR_KEY_STR) == 0)) {
+ /* transform binary gfid to canonical form */
+
+ value = GF_CALLOC (UUID_CANONICAL_FORM_LEN + 1, sizeof(char),
+ gf_common_mt_char);
+ if (!value) {
+ send_fuse_err (state->this, state->finh, ENOMEM);
+ goto internal_out1;
+ }
+ uuid_utoa_r (state->loc.inode->gfid, value);
+
+ send_fuse_xattr (THIS, state->finh, value,
+ UUID_CANONICAL_FORM_LEN, state->size);
+ GF_FREE (value);
+ internal_out1:
+ free_fuse_state (state);
+ return;
+ }
+
+
if (state->fd) {
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": GETXATTR %p/%"PRIu64" (%s)", state->finh->unique,
@@ -3026,15 +3317,16 @@ fuse_getxattr_resume (fuse_state_t *state)
static void
fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
- struct fuse_getxattr_in *fgxi = msg;
- char *name = (char *)(fgxi + 1);
-
- fuse_state_t *state = NULL;
- struct fuse_private *priv = NULL;
- int rv = 0;
- char *newkey = NULL;
+ struct fuse_getxattr_in *fgxi = msg;
+ char *name = (char *)(fgxi + 1);
+ fuse_state_t *state = NULL;
+ struct fuse_private *priv = NULL;
+ int rv = 0;
+ int op_errno = EINVAL;
+ char *newkey = NULL;
priv = this->private;
+ GET_STATE (this, finh, state);
#ifdef GF_DARWIN_HOST_OS
if (fgxi->position) {
@@ -3050,26 +3342,23 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
"%"PRIu64": GETXATTR %s/%"PRIu64" (%s):"
"refusing positioned getxattr",
finh->unique, state->loc.path, finh->nodeid, name);
- send_fuse_err (this, finh, EINVAL);
- FREE (finh);
- return;
+ op_errno = EINVAL;
+ goto err;
}
#endif
if (!priv->acl) {
- if ((strcmp (name, "system.posix_acl_access") == 0) ||
- (strcmp (name, "system.posix_acl_default") == 0)) {
- send_fuse_err (this, finh, ENOTSUP);
- GF_FREE (finh);
- return;
+ if ((strcmp (name, POSIX_ACL_ACCESS_XATTR) == 0) ||
+ (strcmp (name, POSIX_ACL_DEFAULT_XATTR) == 0)) {
+ op_errno = ENOTSUP;
+ goto err;
}
}
if (!priv->selinux) {
if (strncmp (name, "security.", 9) == 0) {
- send_fuse_err (this, finh, ENODATA);
- GF_FREE (finh);
- return;
+ op_errno = ENODATA;
+ goto err;
}
}
@@ -3079,16 +3368,19 @@ fuse_getxattr (xlator_t *this, fuse_in_header_t *finh, void *msg)
rv = fuse_flip_xattr_ns (priv, name, &newkey);
if (rv) {
- send_fuse_err (this, finh, ENOMEM);
- free_fuse_state (state);
- goto out;
+ op_errno = ENOMEM;
+ goto err;
}
state->size = fgxi->size;
state->name = newkey;
fuse_resolve_and_resume (state, fuse_getxattr_resume);
- out:
+
+ return;
+ err:
+ send_fuse_err (this, finh, op_errno);
+ free_fuse_state (state);
return;
}
@@ -3475,6 +3767,10 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
fino.max_readahead = 1 << 17;
fino.max_write = 1 << 17;
fino.flags = FUSE_ASYNC_READ | FUSE_POSIX_LOCKS;
+#if FUSE_KERNEL_MINOR_VERSION >= 17
+ if (fini->minor >= 17)
+ fino.flags |= FUSE_FLOCK_LOCKS;
+#endif
#if FUSE_KERNEL_MINOR_VERSION >= 12
if (fini->minor >= 12) {
/* let fuse leave the umask processing to us, so that it does not
@@ -3503,8 +3799,8 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
}
priv->revchan_in = pfd[0];
priv->revchan_out = pfd[1];
- ret = pthread_create (&messenger, NULL, notify_kernel_loop,
- this);
+ ret = gf_thread_create (&messenger, NULL, notify_kernel_loop,
+ this);
if (ret != 0) {
gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"failed to start messenger daemon (%s)",
@@ -3536,6 +3832,48 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
if (fini->minor < 9)
*priv->msg0_len_p = sizeof(*finh) + FUSE_COMPAT_WRITE_IN_SIZE;
#endif
+ if (priv->use_readdirp) {
+ if (fini->flags & FUSE_DO_READDIRPLUS)
+ fino.flags |= FUSE_DO_READDIRPLUS;
+ }
+
+ if (priv->fopen_keep_cache == 2) {
+ /* If user did not explicitly set --fopen-keep-cache[=off],
+ then check if kernel support FUSE_AUTO_INVAL_DATA and ...
+ */
+ if (fini->flags & FUSE_AUTO_INVAL_DATA) {
+ /* ... enable fopen_keep_cache mode if supported.
+ */
+ gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "Detected "
+ "support for FUSE_AUTO_INVAL_DATA. Enabling "
+ "fopen_keep_cache automatically.");
+ fino.flags |= FUSE_AUTO_INVAL_DATA;
+ priv->fopen_keep_cache = 1;
+ } else {
+ gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "No support "
+ "for FUSE_AUTO_INVAL_DATA. Disabling "
+ "fopen_keep_cache.");
+ /* ... else disable. */
+ priv->fopen_keep_cache = 0;
+ }
+ } else if (priv->fopen_keep_cache == 1) {
+ /* If user explicitly set --fopen-keep-cache[=on],
+ then enable FUSE_AUTO_INVAL_DATA if possible.
+ */
+ if (fini->flags & FUSE_AUTO_INVAL_DATA) {
+ gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "fopen_keep_cache "
+ "is explicitly set. Enabling FUSE_AUTO_INVAL_DATA");
+ fino.flags |= FUSE_AUTO_INVAL_DATA;
+ } else {
+ gf_log ("glusterfs-fuse", GF_LOG_WARNING, "fopen_keep_cache "
+ "is explicitly set. Support for "
+ "FUSE_AUTO_INVAL_DATA is missing");
+ }
+ }
+
+ if (fini->flags & FUSE_ASYNC_DIO)
+ fino.flags |= FUSE_ASYNC_DIO;
+
ret = send_fuse_obj (this, finh, &fino);
if (ret == 0)
gf_log ("glusterfs-fuse", GF_LOG_INFO,
@@ -3716,8 +4054,7 @@ out:
int
fuse_migrate_fd_open (xlator_t *this, fd_t *basefd, fd_t *oldfd,
- xlator_t *old_subvol, xlator_t *new_subvol,
- fd_t **newfdptr)
+ xlator_t *old_subvol, xlator_t *new_subvol)
{
loc_t loc = {0, };
fd_t *newfd = NULL, *old_activefd = NULL;
@@ -3771,6 +4108,10 @@ fuse_migrate_fd_open (xlator_t *this, fd_t *basefd, fd_t *oldfd,
goto out;
}
+ newfd->flags = basefd->flags;
+ if (newfd->lk_ctx)
+ fd_lk_ctx_unref (newfd->lk_ctx);
+
newfd->lk_ctx = fd_lk_ctx_ref (oldfd->lk_ctx);
newfd_ctx = fuse_fd_ctx_check_n_create (this, newfd);
@@ -3816,26 +4157,36 @@ fuse_migrate_fd_open (xlator_t *this, fd_t *basefd, fd_t *oldfd,
old_subvol->name, old_subvol->graph->id,
new_subvol->name, new_subvol->graph->id);
- if (newfdptr != NULL) {
- *newfdptr = newfd;
- }
-
ret = 0;
out:
loc_wipe (&loc);
- fd_unref (newfd);
return ret;
}
int
-fuse_migrate_locks (xlator_t *this, fd_t *oldfd, fd_t *newfd,
+fuse_migrate_locks (xlator_t *this, fd_t *basefd, fd_t *oldfd,
xlator_t *old_subvol, xlator_t *new_subvol)
{
int ret = -1;
dict_t *lockinfo = NULL;
void *ptr = NULL;
+ fd_t *newfd = NULL;
+ fuse_fd_ctx_t *basefd_ctx = NULL;
+
+
+ if (!oldfd->lk_ctx || fd_lk_ctx_empty (oldfd->lk_ctx))
+ return 0;
+
+ basefd_ctx = fuse_fd_ctx_get (this, basefd);
+ GF_VALIDATE_OR_GOTO ("glusterfs-fuse", basefd_ctx, out);
+
+ LOCK (&basefd->lock);
+ {
+ newfd = fd_ref (basefd_ctx->activefd);
+ }
+ UNLOCK (&basefd->lock);
ret = syncop_fgetxattr (old_subvol, oldfd, &lockinfo,
GF_XATTR_LOCKINFO_KEY);
@@ -3876,6 +4227,9 @@ fuse_migrate_locks (xlator_t *this, fd_t *oldfd, fd_t *newfd,
}
out:
+ if (newfd)
+ fd_unref (newfd);
+
if (lockinfo != NULL) {
dict_unref (lockinfo);
}
@@ -3891,7 +4245,7 @@ fuse_migrate_fd (xlator_t *this, fd_t *basefd, xlator_t *old_subvol,
int ret = -1;
char create_in_progress = 0;
fuse_fd_ctx_t *basefd_ctx = NULL;
- fd_t *oldfd = NULL, *newfdptr = NULL;
+ fd_t *oldfd = NULL;
basefd_ctx = fuse_fd_ctx_get (this, basefd);
GF_VALIDATE_OR_GOTO ("glusterfs-fuse", basefd_ctx, out);
@@ -3952,7 +4306,7 @@ fuse_migrate_fd (xlator_t *this, fd_t *basefd, xlator_t *old_subvol,
}
ret = fuse_migrate_fd_open (this, basefd, oldfd, old_subvol,
- new_subvol, &newfdptr);
+ new_subvol);
if (ret < 0) {
gf_log (this->name, GF_LOG_WARNING, "open corresponding to "
"basefd (ptr:%p inode-gfid:%s) in new graph failed "
@@ -3963,15 +4317,15 @@ fuse_migrate_fd (xlator_t *this, fd_t *basefd, xlator_t *old_subvol,
goto out;
}
- ret = fuse_migrate_locks (this, oldfd, newfdptr, old_subvol,
+ ret = fuse_migrate_locks (this, basefd, oldfd, old_subvol,
new_subvol);
if (ret < 0) {
gf_log (this->name, GF_LOG_WARNING,
"migrating locks from old-subvolume (%s-%d) to "
"new-subvolume (%s-%d) failed (inode-gfid:%s oldfd:%p "
- "newfd:%p)", old_subvol->name, old_subvol->graph->id,
+ "basefd:%p)", old_subvol->name, old_subvol->graph->id,
new_subvol->name, new_subvol->graph->id,
- uuid_utoa (basefd->inode->gfid), oldfd, newfdptr);
+ uuid_utoa (basefd->inode->gfid), oldfd, basefd);
}
out:
@@ -4491,6 +4845,7 @@ fuse_priv_dump (xlator_t *this)
(int)private->strict_volfile_check);
gf_proc_dump_write("reverse_thread_started", "%d",
(int)private->reverse_fuse_thread_started);
+ gf_proc_dump_write("use_readdirp", "%d", private->use_readdirp);
return 0;
}
@@ -4619,8 +4974,8 @@ notify (xlator_t *this, int32_t event, void *data, ...)
if (!private->fuse_thread_started) {
private->fuse_thread_started = 1;
- ret = pthread_create (&private->fuse_thread, NULL,
- fuse_thread_proc, this);
+ ret = gf_thread_create (&private->fuse_thread, NULL,
+ fuse_thread_proc, this);
if (ret != 0) {
gf_log (this->name, GF_LOG_DEBUG,
"pthread_create() failed (%s)",
@@ -4707,13 +5062,13 @@ static fuse_handler_t *fuse_std_ops[FUSE_OP_HIGH] = {
/* [FUSE_IOCTL] */
/* [FUSE_POLL] */
/* [FUSE_NOTIFY_REPLY] */
- /* [FUSE_BATCH_FORGET] */
- /* [FUSE_FALLOCATE] */
+ [FUSE_BATCH_FORGET]= fuse_batch_forget,
+ [FUSE_FALLOCATE] = fuse_fallocate,
+ [FUSE_READDIRPLUS] = fuse_readdirp,
};
-static fuse_handler_t *fuse_dump_ops[FUSE_OP_HIGH] = {
-};
+static fuse_handler_t *fuse_dump_ops[FUSE_OP_HIGH];
static void
@@ -4741,7 +5096,7 @@ fuse_dumper (xlator_t *this, fuse_in_header_t *finh, void *msg)
"failed to dump fuse message (R): %s",
strerror (errno));
- return priv->fuse_ops0[finh->opcode] (this, finh, msg);
+ priv->fuse_ops0[finh->opcode] (this, finh, msg);
}
@@ -4760,6 +5115,7 @@ init (xlator_t *this_xl)
int fsname_allocated = 0;
glusterfs_ctx_t *ctx = NULL;
gf_boolean_t sync_to_mount = _gf_false;
+ gf_boolean_t fopen_keep_cache = _gf_false;
unsigned long mntflags = 0;
char *mnt_args = NULL;
eh_t *event = NULL;
@@ -4878,6 +5234,8 @@ init (xlator_t *this_xl)
GF_OPTION_INIT ("enable-ino32", priv->enable_ino32, bool, cleanup_exit);
+ GF_OPTION_INIT ("use-readdirp", priv->use_readdirp, bool, cleanup_exit);
+
priv->fuse_dump_fd = -1;
ret = dict_get_str (options, "dump-fuse", &value_string);
if (ret == 0) {
@@ -4903,8 +5261,12 @@ init (xlator_t *this_xl)
GF_ASSERT (ret == 0);
}
- GF_OPTION_INIT("fopen-keep-cache", priv->fopen_keep_cache, bool,
- cleanup_exit);
+ priv->fopen_keep_cache = 2;
+ if (dict_get (options, "fopen-keep-cache")) {
+ GF_OPTION_INIT("fopen-keep-cache", fopen_keep_cache, bool,
+ cleanup_exit);
+ priv->fopen_keep_cache = fopen_keep_cache;
+ }
GF_OPTION_INIT("gid-timeout", priv->gid_cache_timeout, int32,
cleanup_exit);
@@ -4993,7 +5355,7 @@ init (xlator_t *this_xl)
if (priv->fd == -1)
goto cleanup_exit;
- event = eh_new (FUSE_EVENT_HISTORY_SIZE, _gf_false);
+ event = eh_new (FUSE_EVENT_HISTORY_SIZE, _gf_false, NULL);
if (!event) {
gf_log (this_xl->name, GF_LOG_ERROR,
"could not create a new event history");
@@ -5071,11 +5433,11 @@ fini (xlator_t *this_xl)
kill (getpid (), SIGTERM);
}
-struct xlator_fops fops = {
-};
+struct xlator_fops fops;
struct xlator_cbks cbks = {
.invalidate = fuse_invalidate,
+ .forget = fuse_forget_cbk,
};
@@ -5129,7 +5491,7 @@ struct volume_options options[] = {
},
{ .key = {"gid-timeout"},
.type = GF_OPTION_TYPE_INT,
- .default_value = "0"
+ .default_value = "2"
},
{ .key = {"acl"},
.type = GF_OPTION_TYPE_BOOL,
@@ -5158,5 +5520,9 @@ struct volume_options options[] = {
{ .key = {"fuse-mountopts"},
.type = GF_OPTION_TYPE_STR
},
+ { .key = {"use-readdirp"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "yes"
+ },
{ .key = {NULL} },
};
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
index 37d29df6b..34794b6ea 100644
--- a/xlators/mount/fuse/src/fuse-bridge.h
+++ b/xlators/mount/fuse/src/fuse-bridge.h
@@ -48,7 +48,7 @@
#include "gidcache.h"
#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
-#define FUSE_OP_HIGH (FUSE_POLL + 1)
+#define FUSE_OP_HIGH (FUSE_READDIRPLUS + 1)
#endif
#ifdef GF_DARWIN_HOST_OS
#define FUSE_OP_HIGH (FUSE_DESTROY + 1)
@@ -101,7 +101,7 @@ struct fuse_private {
gf_boolean_t acl;
gf_boolean_t selinux;
gf_boolean_t read_only;
- gf_boolean_t fopen_keep_cache;
+ int32_t fopen_keep_cache;
int32_t gid_cache_timeout;
gf_boolean_t enable_ino32;
fdtable_t *fdtable;
@@ -119,6 +119,9 @@ struct fuse_private {
/* for fuse queue length and congestion threshold */
int background_qlen;
int congestion_threshold;
+
+ /* for using fuse-kernel readdirp*/
+ gf_boolean_t use_readdirp;
};
typedef struct fuse_private fuse_private_t;
@@ -142,9 +145,10 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t;
#define FUSE_FOP(state, ret, op_num, fop, args ...) \
do { \
- call_frame_t *frame = NULL; \
- xlator_t *xl = NULL; \
- int32_t op_ret = 0, op_errno = 0; \
+ call_frame_t *frame = NULL; \
+ xlator_t *xl = NULL; \
+ int32_t op_ret = 0, op_errno = 0; \
+ fuse_resolve_t *resolve = NULL; \
\
frame = get_call_frame_for_req (state); \
if (!frame) { \
@@ -171,14 +175,20 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t;
frame->root->op = op_num; \
frame->op = op_num; \
\
+ if ( state->resolve_now ) { \
+ resolve = state->resolve_now; \
+ } else { \
+ resolve = &(state->resolve); \
+ } \
+ \
xl = state->active_subvol; \
if (!xl) { \
gf_log_callingfn ("glusterfs-fuse", GF_LOG_ERROR, \
"xl is NULL"); \
op_errno = ENOENT; \
op_ret = -1; \
- } else if (state->resolve.op_ret < 0) { \
- op_errno = state->resolve.op_errno; \
+ } else if (resolve->op_ret < 0) { \
+ op_errno = resolve->op_errno; \
op_ret = -1; \
if (op_num == GF_FOP_LOOKUP) { \
gf_log ("glusterfs-fuse", \
@@ -187,7 +197,7 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t;
"%"PRIu64": %s() %s => -1 (%s)", \
frame->root->unique, \
gf_fop_list[frame->root->op], \
- state->resolve.resolve_loc.path, \
+ resolve->resolve_loc.path, \
strerror (op_errno)); \
} else { \
gf_log ("glusterfs-fuse", \
@@ -196,7 +206,7 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t;
"migration of %s failed (%s)", \
frame->root->unique, \
gf_fop_list[frame->root->op], \
- state->resolve.resolve_loc.path, \
+ resolve->resolve_loc.path, \
strerror (op_errno)); \
} \
} else if (state->resolve2.op_ret < 0) { \
diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c
index e72669a9e..4d478b919 100644
--- a/xlators/mount/fuse/src/fuse-helpers.c
+++ b/xlators/mount/fuse/src/fuse-helpers.c
@@ -7,6 +7,10 @@
later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation.
*/
+#ifdef __NetBSD__
+#define _KMEMUSER
+#endif
+
#include "fuse-bridge.h"
#if defined(GF_SOLARIS_HOST_OS)
#include <sys/procfs.h>
@@ -14,9 +18,6 @@
#include <sys/sysctl.h>
#endif
-#ifndef GF_REQUEST_MAXGROUPS
-#define GF_REQUEST_MAXGROUPS 16
-#endif /* GF_REQUEST_MAXGROUPS */
static void
fuse_resolve_wipe (fuse_resolve_t *resolve)
@@ -138,6 +139,7 @@ get_fuse_state (xlator_t *this, fuse_in_header_t *finh)
}
+#define FUSE_MAX_AUX_GROUPS 32 /* We can get only up to 32 aux groups from /proc */
void
frame_fill_groups (call_frame_t *frame)
{
@@ -160,6 +162,9 @@ frame_fill_groups (call_frame_t *frame)
if (!fp)
goto out;
+ if (call_stack_alloc_groups (frame->root, FUSE_MAX_AUX_GROUPS) != 0)
+ goto out;
+
while ((ptr = fgets (line, sizeof line, fp))) {
if (strncmp (ptr, "Groups:", 7) != 0)
continue;
@@ -176,7 +181,7 @@ frame_fill_groups (call_frame_t *frame)
if (!endptr || *endptr)
break;
frame->root->groups[idx++] = id;
- if (idx == GF_MAX_AUX_GROUPS)
+ if (idx == FUSE_MAX_AUX_GROUPS)
break;
}
@@ -192,6 +197,7 @@ out:
prcred_t *prcred = (prcred_t *) scratch;
FILE *fp = NULL;
int ret = 0;
+ int ngrps;
ret = snprintf (filename, sizeof filename,
"/proc/%d/cred", frame->root->pid);
@@ -200,8 +206,11 @@ out:
fp = fopen (filename, "r");
if (fp != NULL) {
if (fgets (scratch, sizeof scratch, fp) != NULL) {
- frame->root->ngrps = MIN(prcred->pr_ngroups,
- GF_REQUEST_MAXGROUPS);
+ ngrps = MIN(prcred->pr_ngroups,
+ GF_MAX_AUX_GROUPS);
+ if (call_stack_alloc_groups (frame->root,
+ ngrps) != 0)
+ return;
}
fclose (fp);
}
@@ -226,7 +235,9 @@ out:
if (sysctl(name, namelen, &kp, &kplen, NULL, 0) != 0)
return;
- ngroups = MIN(kp.kp_eproc.e_ucred.cr_ngroups, GF_REQUEST_MAXGROUPS);
+ ngroups = MIN(kp.kp_eproc.e_ucred.cr_ngroups, GF_MAX_AUX_GROUPS);
+ if (call_stack_alloc_groups (frame->root, ngroups) != 0)
+ return;
for (i = 0; i < ngroups; i++)
frame->root->groups[i] = kp.kp_eproc.e_ucred.cr_groups[i];
frame->root->ngrps = ngroups;
@@ -257,6 +268,8 @@ static void get_groups(fuse_private_t *priv, call_frame_t *frame)
gl = gid_cache_lookup(&priv->gid_cache, frame->root->pid);
if (gl) {
+ if (call_stack_alloc_groups (frame->root, gl->gl_count) != 0)
+ return;
frame->root->ngrps = gl->gl_count;
for (i = 0; i < gl->gl_count; i++)
frame->root->groups[i] = gl->gl_list[i];
@@ -339,7 +352,9 @@ fuse_ino_to_inode (uint64_t ino, xlator_t *fuse)
uint64_t
inode_to_fuse_nodeid (inode_t *inode)
{
- if (!inode || __is_root_gfid (inode->gfid))
+ if (!inode)
+ return 0;
+ if (__is_root_gfid (inode->gfid))
return 1;
return (unsigned long) inode;
diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c
index 88ce32ab9..8565ce0e4 100644
--- a/xlators/mount/fuse/src/fuse-resolve.c
+++ b/xlators/mount/fuse/src/fuse-resolve.c
@@ -26,6 +26,8 @@ int fuse_migrate_fd (xlator_t *this, fd_t *fd, xlator_t *old_subvol,
fuse_fd_ctx_t *
fuse_fd_ctx_get (xlator_t *this, fd_t *fd);
+gf_boolean_t fuse_inode_needs_lookup (inode_t *inode, xlator_t *this);
+
static int
fuse_resolve_loc_touchup (fuse_state_t *state)
{
@@ -201,7 +203,11 @@ fuse_resolve_gfid (fuse_state_t *state)
uuid_copy (resolve_loc->gfid, resolve->gfid);
}
- resolve_loc->inode = inode_new (state->itable);
+ /* inode may already exist in case we are looking up an inode which was
+ linked through readdirplus */
+ resolve_loc->inode = inode_find (state->itable, resolve_loc->gfid);
+ if (!resolve_loc->inode)
+ resolve_loc->inode = inode_new (state->itable);
ret = loc_path (resolve_loc, NULL);
if (ret <= 0) {
@@ -239,6 +245,9 @@ fuse_resolve_parent_simple (fuse_state_t *state)
parent = resolve->parhint;
if (parent->table == state->itable) {
+ if (fuse_inode_needs_lookup (parent, THIS))
+ return 1;
+
/* no graph switches since */
loc->parent = inode_ref (parent);
uuid_copy (loc->pargfid, parent->gfid);
@@ -265,6 +274,10 @@ fuse_resolve_parent_simple (fuse_state_t *state)
/* non decisive result - parent missing */
return 1;
}
+ if (fuse_inode_needs_lookup (parent, THIS)) {
+ inode_unref (parent);
+ return 1;
+ }
loc->parent = parent;
uuid_copy (loc->pargfid, resolve->pargfid);
@@ -314,15 +327,18 @@ fuse_resolve_inode_simple (fuse_state_t *state)
loc = state->loc_now;
inode = resolve->hint;
- if (inode->table == state->itable) {
+ if (inode->table == state->itable)
inode_ref (inode);
- goto found;
+ else
+ inode = inode_find (state->itable, resolve->gfid);
+
+ if (inode) {
+ if (!fuse_inode_needs_lookup (inode, THIS))
+ goto found;
+ /* inode was linked through readdirplus */
+ inode_unref (inode);
}
- inode = inode_find (state->itable, resolve->gfid);
- if (inode)
- goto found;
-
return 1;
found:
loc->inode = inode;
diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in
index 0d92bfbd5..a192d6059 100755
--- a/xlators/mount/fuse/utils/mount.glusterfs.in
+++ b/xlators/mount/fuse/utils/mount.glusterfs.in
@@ -27,6 +27,8 @@ _init ()
LOG_DEBUG=DEBUG;
LOG_TRACE=TRACE;
+ HOST_NAME_MAX=64;
+
prefix="@prefix@";
exec_prefix=@exec_prefix@;
cmd_line=$(echo "@sbindir@/glusterfs");
@@ -51,8 +53,24 @@ _init ()
esac
UPDATEDBCONF=/etc/updatedb.conf
- LD_LIBRARY_PATH=@libdir@:${LD_LIBRARY_PATH}
- export LD_LIBRARY_PATH
+}
+
+parse_backup_volfile_servers ()
+{
+ local server_list=$1
+ local servers=""
+ local new_servers=""
+
+ servers=$(echo ${server_list} | sed 's/\:/ /g')
+ for server in ${servers}; do
+ length=$(echo $server | wc -c)
+ if [ ${length} -gt ${HOST_NAME_MAX} ]; then
+ echo "Hostname:${server} provided is too long.. skipping"
+ continue
+ fi
+ new_servers=$(echo "$new_servers $server")
+ done
+ echo ${new_servers}
}
start_glusterfs ()
@@ -60,48 +78,46 @@ start_glusterfs ()
# lets the comparsion be case insensitive for all strings
if [ -n "$log_level_str" ]; then
- case "$( echo $log_level_str | tr '[a-z]' '[A-Z]')" in
- "ERROR")
- log_level=$LOG_ERROR;
- ;;
+ case "$( echo $log_level_str | tr '[a-z]' '[A-Z]')" in
+ "ERROR")
+ log_level=$LOG_ERROR;
+ ;;
"INFO")
log_level=$LOG_INFO
;;
- "DEBUG")
- log_level=$LOG_DEBUG;
- ;;
- "CRITICAL")
- log_level=$LOG_CRITICAL;
- ;;
- "WARNING")
- log_level=$LOG_WARNING;
- ;;
- "TRACE")
- log_level=$LOG_TRACE;
- ;;
- "NONE")
- log_level=$LOG_NONE;
- ;;
- *)
- echo "invalid log level $log_level_str, using INFO";
- log_level=$LOG_INFO;
- ;;
- esac
- fi
- if [ -n "$log_level" ]; then
- cmd_line=$(echo "$cmd_line --log-level=$log_level");
+ "DEBUG")
+ log_level=$LOG_DEBUG;
+ ;;
+ "CRITICAL")
+ log_level=$LOG_CRITICAL;
+ ;;
+ "WARNING")
+ log_level=$LOG_WARNING;
+ ;;
+ "TRACE")
+ log_level=$LOG_TRACE;
+ ;;
+ "NONE")
+ log_level=$LOG_NONE;
+ ;;
+ *)
+ echo "invalid log level $log_level_str, using INFO";
+ log_level=$LOG_INFO;
+ ;;
+ esac
fi
+#options without values start here
if [ -n "$read_only" ]; then
- cmd_line=$(echo "$cmd_line --read-only");
+ cmd_line=$(echo "$cmd_line --read-only");
fi
if [ -n "$acl" ]; then
- cmd_line=$(echo "$cmd_line --acl");
+ cmd_line=$(echo "$cmd_line --acl");
fi
if [ -n "$selinux" ]; then
- cmd_line=$(echo "$cmd_line --selinux");
+ cmd_line=$(echo "$cmd_line --selinux");
fi
if [ -n "$enable_ino32" ]; then
@@ -112,16 +128,37 @@ start_glusterfs ()
cmd_line=$(echo "$cmd_line --worm");
fi
- if [ -n "$log_file" ]; then
- cmd_line=$(echo "$cmd_line --log-file=$log_file");
+ if [ -n "$fopen_keep_cache" ]; then
+ cmd_line=$(echo "$cmd_line --fopen-keep-cache");
fi
if [ -n "$volfile_check" ]; then
- cmd_line=$(echo "$cmd_line --volfile-check");
+ cmd_line=$(echo "$cmd_line --volfile-check");
+ fi
+
+ if [ -n "$mem_accounting" ]; then
+ cmd_line=$(echo "$cmd_line --mem-accounting");
+ fi
+
+ if [ -n "$aux_gfid_mount" ]; then
+ cmd_line=$(echo "$cmd_line --aux-gfid-mount");
+ fi
+
+#options with values start here
+ if [ -n "$log_level" ]; then
+ cmd_line=$(echo "$cmd_line --log-level=$log_level");
+ fi
+
+ if [ -n "$log_file" ]; then
+ cmd_line=$(echo "$cmd_line --log-file=$log_file");
fi
if [ -n "$direct_io_mode" ]; then
- cmd_line=$(echo "$cmd_line --direct-io-mode=$direct_io_mode");
+ cmd_line=$(echo "$cmd_line --direct-io-mode=$direct_io_mode");
+ fi
+
+ if [ -n "$use_readdirp" ]; then
+ cmd_line=$(echo "$cmd_line --use-readdirp=$use_readdirp");
fi
if [ -n "$volume_name" ]; then
@@ -141,23 +178,24 @@ start_glusterfs ()
fi
if [ -n "$gid_timeout" ]; then
- cmd_line=$(echo "$cmd_line --gid-timeout=$gid_timeout");
- fi
-
- if [ -n "$fopen_keep_cache" ]; then
- cmd_line=$(echo "$cmd_line --fopen-keep-cache");
+ cmd_line=$(echo "$cmd_line --gid-timeout=$gid_timeout");
fi
if [ -n "$bg_qlen" ]; then
- cmd_line=$(echo "$cmd_line --background-qlen=$bg_qlen");
+ cmd_line=$(echo "$cmd_line --background-qlen=$bg_qlen");
fi
if [ -n "$cong_threshold" ]; then
- cmd_line=$(echo "$cmd_line --congestion-threshold=$cong_threshold");
+ cmd_line=$(echo "$cmd_line --congestion-threshold=$cong_threshold");
fi
if [ -n "$fuse_mountopts" ]; then
- cmd_line=$(echo "$cmd_line --fuse-mountopts=$fuse_mountopts");
+ cmd_line=$(echo "$cmd_line --fuse-mountopts=$fuse_mountopts");
+ fi
+
+ if [ -n "$xlator_option" ]; then
+ xlator_option=$(echo $xlator_option | sed s/"xlator-option="/"--xlator-option "/g)
+ cmd_line=$(echo "$cmd_line $xlator_option");
fi
# for rdma volume, we have to fetch volfile with '.rdma' added
@@ -166,36 +204,40 @@ start_glusterfs ()
if [ -z "$volfile_loc" ]; then
if [ -n "$server_ip" ]; then
+
+ cmd_line=$(echo "$cmd_line --volfile-server=$server_ip");
+
+ if [ -n "$backup_volfile_servers" ]; then
+ servers=$(parse_backup_volfile_servers ${backup_volfile_servers})
+ for i in $(echo ${servers}); do
+ cmd_line=$(echo "$cmd_line --volfile-server=$i");
+ done
+ fi
+
if [ -n "$server_port" ]; then
cmd_line=$(echo "$cmd_line --volfile-server-port=$server_port");
fi
- if [ -n "$transport" ]; then
+
+ if [ -n "$transport" ]; then
cmd_line=$(echo "$cmd_line --volfile-server-transport=$transport");
if [ "$transport" = "rdma" ]; then
volume_id_rdma=".rdma";
fi
fi
+
if [ -n "$volume_id" ]; then
if [ -n "$volume_id_rdma" ]; then
volume_id="$volume_id$volume_id_rdma";
fi
cmd_line=$(echo "$cmd_line --volfile-id=$volume_id");
fi
-
- if [ -n "$backupvolfile_server" ]; then
- cmd_line1=$(echo "$cmd_line --volfile-server=$backupvolfile_server");
- fi
- if [ -n "$volfile_max_fetch_attempts" ]; then
- cmd_line=$(echo "$cmd_line --volfile-max-fetch-attempts=$volfile_max_fetch_attempts");
- fi
- cmd_line=$(echo "$cmd_line --volfile-server=$server_ip");
fi
else
cmd_line=$(echo "$cmd_line --volfile=$volfile_loc");
fi
if [ -n "$fuse_mountopts" ]; then
- cmd_line=$(echo "$cmd_line --fuse-mountopts=$fuse_mountopts");
+ cmd_line=$(echo "$cmd_line --fuse-mountopts=$fuse_mountopts");
fi
cmd_line=$(echo "$cmd_line $mount_point");
@@ -210,24 +252,8 @@ start_glusterfs ()
inode="0";
fi
- # retry the failover
- # if [ $? != "0" ]; then # <--- TODO: Once glusterfs returns proper error code, change it.
if [ $inode -ne 1 ]; then
err=1;
- if [ -n "$cmd_line1" ]; then
- cmd_line1=$(echo "$cmd_line1 $mount_point");
- $cmd_line1;
- err=0;
-
- inode=$( ${getinode} $mount_point 2>/dev/null);
- # this is required if the stat returns error
- if [ -z "$inode" ]; then
- inode="0";
- fi
- if [ $inode -ne 1 ]; then
- err=1;
- fi
- fi
fi
if [ $err -eq "1" ]; then
@@ -252,13 +278,13 @@ mount.glusterfs --version"
# check for recursive mounts. i.e, mounting over an existing brick
check_recursive_mount ()
{
- if [ $2 = "/" ]; then
+ if [ $1 = "/" ]; then
echo Cannot mount over root;
exit 2;
fi
# GFID check first
# remove trailing / from mount point
- mnt_dir=${2%/};
+ mnt_dir=${1%/};
export PATH;
# check whether getfattr exists
@@ -317,7 +343,6 @@ check_recursive_mount ()
main ()
{
helper=$(echo "$@" | sed -n 's/.*\--[ ]*\([^ ]*\).*/\1/p');
-
in_opt="no"
pos_args=0
for opt in "$@"; do
@@ -329,8 +354,14 @@ main ()
"acl") acl=1 ;;
"selinux") selinux=1 ;;
"worm") worm=1 ;;
- "fopen-keep-cache") fopen_keep_cache=1 ;;
+ "fopen-keep-cache") fopen_keep_cache=1 ;;
"enable-ino32") enable_ino32=1 ;;
+ "mem-accounting") mem_accounting=1;;
+ "aux-gfid-mount")
+ if [ `uname -s` = "Linux" ]; then
+ aux_gfid_mount=1
+ fi
+ ;;
# "mount -t glusterfs" sends this, but it's useless.
"rw") ;;
# these ones are interpreted during system initialization
@@ -350,18 +381,17 @@ main ()
"volume-id") volume_id=$value ;;
"volfile-check") volfile_check=$value ;;
"server-port") server_port=$value ;;
- "fetch-attempts")
- volfile_max_fetch_attempts=$value ;;
- "backupvolfile-server")
- backupvolfile_server=$value ;;
"attribute-timeout")
attribute_timeout=$value ;;
"entry-timeout") entry_timeout=$value ;;
"negative-timeout") negative_timeout=$value ;;
- "gid-timeout") gid_timeout=$value ;;
- "background-qlen") bg_qlen=$value ;;
- "congestion-threshold") cong_threshold=$value ;;
- "fuse-mountopts") fuse_mountopts=$value ;;
+ "gid-timeout") gid_timeout=$value ;;
+ "background-qlen") bg_qlen=$value ;;
+ "backup-volfile-servers") backup_volfile_servers=$value ;;
+ "congestion-threshold") cong_threshold=$value ;;
+ "xlator-option") xlator_option=$xlator_option" "$pair ;;
+ "fuse-mountopts") fuse_mountopts=$value ;;
+ "use-readdirp") use_readdirp=$value ;;
*)
# Passthru
[ -z "$fuse_mountopts" ] || fuse_mountopts="$fuse_mountopts,"
@@ -393,7 +423,7 @@ main ()
[ -n "$test_str" ] && {
volume_id="$test_str";
}
- volfile_loc="";
+ volfile_loc="";
}
#
@@ -412,13 +442,13 @@ main ()
}
# Simple check to avoid multiple identical mounts
- if grep -q " ${mount_point}.*fuse" $mounttab; then
+ if grep -q "[[:space:]+]${mount_point}[[:space:]+]fuse" $mounttab; then
echo -n "$0: according to mtab, GlusterFS is already mounted on "
echo "$mount_point"
exit 0;
fi
- check_recursive_mount "$@";
+ check_recursive_mount "$mount_point";
# Append fuse.glusterfs to PRUNEFS variable in updatedb.conf(5). updatedb(8)
# should not index files under GlusterFS, indexing will slow down GlusteFS