patches/inode-gen.patch | 12 +++
patches/rebalance-hash.patch | 25 +++++++
patches/server-locking.patch | 147 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 184 insertions(+)
New commits:
commit 47e657847d6a31f978dd5b69c5ea28a806452127
Author: Jeff Darcy <jdarcy(a)redhat.com>
Date: Fri Dec 17 13:00:54 2010 -0500
Stray patches relevant to CloudFS.
diff --git a/patches/inode-gen.patch b/patches/inode-gen.patch
new file mode 100644
index 0000000..07e96fd
--- /dev/null
+++ b/patches/inode-gen.patch
@@ -0,0 +1,12 @@
+diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h
+index 15a4f98..3c95407 100644
+--- a/libglusterfs/src/inode.h
++++ b/libglusterfs/src/inode.h
+@@ -104,6 +104,7 @@ struct _inode {
+ struct list_head list; /* active/lru/purge */
+
+ struct _inode_ctx *_ctx; /* replacement for dict_t *(inode->ctx) */
++ uint64_t gen; /* for locking code */
+ };
+
+
diff --git a/patches/rebalance-hash.patch b/patches/rebalance-hash.patch
new file mode 100644
index 0000000..27dfdae
--- /dev/null
+++ b/patches/rebalance-hash.patch
@@ -0,0 +1,25 @@
+diff --git a/xlators/cluster/dht/src/dht-layout.c b/xlators/cluster/dht/src/dht-layout.c
+index 8a5f45d..17d2b7f 100644
+--- a/xlators/cluster/dht/src/dht-layout.c
++++ b/xlators/cluster/dht/src/dht-layout.c
+@@ -171,8 +171,18 @@ dht_layout_search (xlator_t *this, dht_layout_t *layout, const char
*name)
+ xlator_t *subvol = NULL;
+ int i = 0;
+ int ret = 0;
+-
+-
++ static char pfx[] = ".dht.";
++
++ /*
++ * Make sure that things with the prefix get hashed exactly the same
++ * as without. Why? So that file copies created during rebalance go
++ * exactly where they should be after they're renamed over their
++ * originals, without trying to duplicate the layout algorithms in a
++ * separate piece of code.
++ */
++ if (!strncmp(name,pfx,sizeof(pfx-1))) {
++ name += sizeof(pfx) - 1;
++ }
+ ret = dht_hash_compute (layout->type, name, &hash);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
diff --git a/patches/server-locking.patch b/patches/server-locking.patch
new file mode 100644
index 0000000..aeb6d54
--- /dev/null
+++ b/patches/server-locking.patch
@@ -0,0 +1,147 @@
+diff --git a/xlators/protocol/server/src/server3_1-fops.c
b/xlators/protocol/server/src/server3_1-fops.c
+index fb3010e..f685786 100644
+--- a/xlators/protocol/server/src/server3_1-fops.c
++++ b/xlators/protocol/server/src/server3_1-fops.c
+@@ -31,6 +31,64 @@
+
+ #include "md5.h"
+
++/*
++ * This is really a hack, to demonstrate the general optimistic-locking
++ * approach. For real life, we should store this in a more sophisticated
++ * way.
++ */
++
++#define MAX_OP_LOCKS 10
++
++struct {
++ void *ptr1; /* NULL means not in use */
++ void *ptr2;
++ uint64_t value;
++} op_locks[MAX_OP_LOCKS];
++
++int
++store_op_lock (void *p1, void *p2, uint64_t v)
++{
++ int i;
++
++ for (i = 0; i < MAX_OP_LOCKS; ++i) {
++ if (!op_locks[i].ptr1) {
++ op_locks[i].ptr1 = p1;
++ op_locks[i].ptr2 = p2;
++ op_locks[i].value = v;
++ return 0;
++ }
++ }
++
++ return -1;
++}
++
++int
++fetch_op_lock (void *p1, void *p2, uint64_t *v)
++{
++ int i;
++
++ for (i = 0; i < MAX_OP_LOCKS; ++i) {
++ if ((op_locks[i].ptr1 == p1) && (op_locks[i].ptr2 == p2)) {
++ *v = op_locks[i].value;
++ return 0;
++ }
++ }
++
++ return -1;
++}
++
++void
++delete_op_lock (void *p1, void *p2)
++{
++ int i;
++
++ for (i = 0; i < MAX_OP_LOCKS; ++i) {
++ if ((op_locks[i].ptr1 == p1) && (op_locks[i].ptr2 == p2)) {
++ op_locks[i].ptr1 = NULL;
++ return;
++ }
++ }
++}
+
+ /* Callback function section */
+ int
+@@ -2277,17 +2335,51 @@ err:
+ return 0;
+ }
+
++void
++server_special_setxattr (dict_t *dict, char *key, data_t *value, void *ctx)
++{
++ char **lock_str = ctx;
++
++ /* Only return the first match. */
++ if (*lock_str) {
++ return;
++ }
++
++ if (!strcmp(key,"user.glusterfs.lock")) {
++ *lock_str = data_to_str(value);
++ }
++}
+
+ int
+ server_setxattr_resume (call_frame_t *frame, xlator_t *bound_xl)
+ {
+ server_state_t *state = NULL;
++ char *lock_str = NULL;
++ inode_t *inode = NULL;
++ int ret = 0;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
++ dict_foreach(state->dict,server_special_setxattr,&lock_str);
++ if (lock_str) {
++ inode = state->loc.inode;
++ gf_log(bound_xl->name,GF_LOG_WARNING,
++ "got lock request for %d from %p",
++ inode->ino, state->conn);
++ ret = store_op_lock(inode,state->conn,inode->gen);
++ if (ret != 0) {
++ gf_log(bound_xl->name,GF_LOG_ERROR,
++ "lock request failed (store_op_lock) for %d",
++ inode->ino);
++ state->resolve.op_ret = -1;
++ state->resolve.op_errno = ENOMEM;
++ goto err;
++ }
++ }
++
+ STACK_WIND (frame, server_setxattr_cbk,
+ bound_xl, bound_xl->fops->setxattr,
+ &state->loc, state->dict, state->flags);
+@@ -2389,12 +2481,25 @@ int
+ server_writev_resume (call_frame_t *frame, xlator_t *bound_xl)
+ {
+ server_state_t *state = NULL;
++ inode_t *inode = NULL;
++ uint64_t old_val = 0;
+
+ state = CALL_STATE (frame);
+
+ if (state->resolve.op_ret != 0)
+ goto err;
+
++ inode = state->fd->inode;
++ if (fetch_op_lock(inode,state->conn,&old_val) == 0) {
++ if (old_val != inode->gen) {
++ gf_log(bound_xl->name,GF_LOG_WARNING,
++ "would reject write for %d from %p",
++ inode->ino, state->conn);
++ }
++ delete_op_lock(inode,state->conn);
++ }
++ ++(inode->gen);
++
+ STACK_WIND (frame, server_writev_cbk,
+ bound_xl, bound_xl->fops->writev,
+ state->fd, state->payload_vector, state->payload_count,