summaryrefslogtreecommitdiffstats
path: root/libglusterfs
diff options
context:
space:
mode:
authorRaghavendra G <raghavendra@gluster.com>2012-02-08 15:06:30 +0530
committerVijay Bellur <vijay@gluster.com>2012-02-21 01:05:14 -0800
commit7197111677619da96c80572a09331d6e28c1015b (patch)
tree4ebe916f4aa9b4bd34ab23a1c6ec145fd60c3b27 /libglusterfs
parent6d19136de7af9135dd23662f18c3ee544a2888da (diff)
fuse-bridge: Handle graph-switch.
The purpose of this patch is to let protocol/client know when its transports can be disconnected, without application running on gluster mount noticing any effects of graph switch. In order to do this, we migrate all fds and blocked locks to new graph. Once this migration is complete and there are no in-transit frames as viewed by fuse-bridge, we send a PARENT_DOWN event to its children. protocol/client on receiving this event, can disconnect up its transports. Change-Id: Idcea4bc43e23fb077ac16538b61335ebad84ba16 BUG: 767862 Reviewed-on: http://review.gluster.com/2734 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Vijay Bellur <vijay@gluster.com>
Diffstat (limited to 'libglusterfs')
-rw-r--r--libglusterfs/src/fd.c97
-rw-r--r--libglusterfs/src/fd.h11
-rw-r--r--libglusterfs/src/glusterfs.h1
-rw-r--r--libglusterfs/src/xlator.h2
4 files changed, 109 insertions, 2 deletions
diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c
index ff956ec2cff..60add299dd7 100644
--- a/libglusterfs/src/fd.c
+++ b/libglusterfs/src/fd.c
@@ -168,6 +168,50 @@ gf_fd_fdtable_get_all_fds (fdtable_t *fdtable, uint32_t *count)
}
+fdentry_t *
+__gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count)
+{
+ fdentry_t *fdentries = NULL;
+ size_t cpy = 0;
+
+ if (count == NULL) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING, "!count");
+ goto out;
+ }
+
+ fdentries = GF_CALLOC (fdtable->max_fds, sizeof (fdentry_t),
+ gf_common_mt_fdentry_t);
+ if (fdentries == NULL) {
+ goto out;
+ }
+
+ *count = fdtable->max_fds;
+
+ cpy = fdtable->max_fds * sizeof (fdentry_t);
+ memcpy ((void *)fdentries, (void *)fdtable->fdentries, cpy);
+
+out:
+ return fdentries;
+}
+
+
+fdentry_t *
+gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count)
+{
+ fdentry_t *entries = NULL;
+
+ if (fdtable) {
+ pthread_mutex_lock (&fdtable->lock);
+ {
+ entries = __gf_fd_fdtable_copy_all_fds (fdtable, count);
+ }
+ pthread_mutex_unlock (&fdtable->lock);
+ }
+
+ return entries;
+}
+
+
void
gf_fd_fdtable_destroy (fdtable_t *fdtable)
{
@@ -309,6 +353,54 @@ unlock_out:
}
+inline void
+gf_fdptr_put (fdtable_t *fdtable, fd_t *fd)
+{
+ fdentry_t *fde = NULL;
+ int32_t i = 0;
+
+ if ((fdtable == NULL) || (fd == NULL)) {
+ gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
+ return;
+ }
+
+ pthread_mutex_lock (&fdtable->lock);
+ {
+ for (i = 0; i < fdtable->max_fds; i++) {
+ if (fdtable->fdentries[i].fd == fd) {
+ fde = &fdtable->fdentries[i];
+ break;
+ }
+ }
+
+ if (fde == NULL) {
+ gf_log_callingfn ("fd", GF_LOG_WARNING,
+ "fd (%p) is not present in fdtable", fd);
+ goto unlock_out;
+ }
+
+ /* If the entry is not allocated, put operation must return
+ * without doing anything.
+ * This has the potential of masking out any bugs in a user of
+ * fd that ends up calling gf_fd_put twice for the same fd or
+ * for an unallocated fd, but it is a price we have to pay for
+ * ensuring sanity of our fd-table.
+ */
+ if (fde->next_free != GF_FDENTRY_ALLOCATED)
+ goto unlock_out;
+ fde->fd = NULL;
+ fde->next_free = fdtable->first_free;
+ fdtable->first_free = i;
+ }
+unlock_out:
+ pthread_mutex_unlock (&fdtable->lock);
+
+ if ((fd != NULL) && (fde != NULL)) {
+ fd_unref (fd);
+ }
+}
+
+
fd_t *
gf_fd_fdptr_get (fdtable_t *fdtable, int64_t fd)
{
@@ -401,7 +493,7 @@ fd_destroy (fd_t *fd)
goto out;
if (IA_ISDIR (fd->inode->ia_type)) {
- for (i = 0; i < fd->xl_count; i++) {
+ for (i = 0; i < fd->xl_count; i++) {
if (fd->_ctx[i].key) {
xl = fd->_ctx[i].xl_key;
old_THIS = THIS;
@@ -464,6 +556,7 @@ fd_unref (fd_t *fd)
fd_t *
__fd_bind (fd_t *fd)
{
+ list_del_init (&fd->inode_list);
list_add (&fd->inode_list, &fd->inode->fd_list);
return fd;
@@ -502,7 +595,7 @@ __fd_create (inode_t *inode, uint64_t pid)
if (!fd)
goto out;
- fd->xl_count = inode->table->xl->graph->xl_count + 1;
+ fd->xl_count = 3 * inode->table->xl->graph->xl_count + 1;
fd->_ctx = GF_CALLOC (1, (sizeof (struct _fd_ctx) * fd->xl_count),
gf_common_mt_fd_ctx);
diff --git a/libglusterfs/src/fd.h b/libglusterfs/src/fd.h
index 531dd44f2a2..be9800b3001 100644
--- a/libglusterfs/src/fd.h
+++ b/libglusterfs/src/fd.h
@@ -154,6 +154,8 @@ fd_list_empty (struct _inode *inode);
fd_t *
fd_bind (fd_t *fd);
+fd_t *
+__fd_bind (fd_t *fd);
int
fd_ctx_set (fd_t *fd, xlator_t *xlator, uint64_t value);
@@ -184,4 +186,13 @@ __fd_ref (fd_t *fd);
void
fd_ctx_dump (fd_t *fd, char *prefix);
+fdentry_t *
+gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count);
+
+fdentry_t *
+__gf_fd_fdtable_copy_all_fds (fdtable_t *fdtable, uint32_t *count);
+
+void
+gf_fdptr_put (fdtable_t *fdtable, fd_t *fd);
+
#endif /* _FD_H */
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index 63c28b8cf81..75476cef801 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -388,6 +388,7 @@ typedef enum {
GF_EVENT_TRANSLATOR_OP,
GF_EVENT_AUTH_FAILED,
GF_EVENT_VOLUME_DEFRAG,
+ GF_EVENT_PARENT_DOWN,
GF_EVENT_MAXVAL,
} glusterfs_event_t;
diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h
index 5e4216deca5..9767ad04391 100644
--- a/libglusterfs/src/xlator.h
+++ b/libglusterfs/src/xlator.h
@@ -828,6 +828,8 @@ struct _xlator {
char init_succeeded;
void *private;
struct mem_acct mem_acct;
+ uint64_t winds;
+ char switched;
};
#define xlator_has_parent(xl) (xl->parents != NULL)