summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Avati <avati@gluster.com>2009-12-06 13:48:43 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-12-06 11:44:48 -0800
commit33f3abffe4f0de929d3732a472ad3df766d575b7 (patch)
tree81865b47cafbe32500c1cebaa554ad07d3a46f6d
parentf08a2073d58ffff8c5b358fbb05702377a251b87 (diff)
resolver: handle resolutions of paths
support a new type of resolution where only the path is sent from the client over the wire without inode/parent/generation numbers. this can happen when cluster translators could not look up inodes on a server and later when the server comes up applications issues operations on the inode without a lookup (since they could be cd'ed inside). In these cases the server makes the best attempt to resolve the path and perform the fop on it Signed-off-by: Anand V. Avati <avati@blackhole.gluster.com> Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 315 (generation number support) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=315
-rw-r--r--xlators/protocol/server/src/server-resolve.c68
1 files changed, 66 insertions, 2 deletions
diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c
index 0db29468ffd..c4e5a9c57d7 100644
--- a/xlators/protocol/server/src/server-resolve.c
+++ b/xlators/protocol/server/src/server-resolve.c
@@ -32,6 +32,8 @@ int
resolve_entry_simple (call_frame_t *frame);
int
resolve_inode_simple (call_frame_t *frame);
+int
+resolve_path_simple (call_frame_t *frame);
int
component_count (const char *path)
@@ -148,8 +150,10 @@ resolve_deep_continue (call_frame_t *frame)
if (resolve->par)
ret = resolve_entry_simple (frame);
- else
+ else if (resolve->ino)
ret = resolve_inode_simple (frame);
+ else if (resolve->path)
+ ret = resolve_path_simple (frame);
resolve_loc_touchup (frame);
@@ -247,6 +251,62 @@ resolve_path_deep (call_frame_t *frame)
}
+int
+resolve_path_simple (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ struct resolve_comp *components = NULL;
+ int ret = -1;
+ int par_idx = 0;
+ int ino_idx = 0;
+ int i = 0;
+
+ state = CALL_STATE (frame);
+ this = frame->this;
+ resolve = state->resolve_now;
+ components = resolve->components;
+
+ if (!components) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
+ }
+
+ for (i = 0; components[i].basename; i++) {
+ par_idx = ino_idx;
+ ino_idx = i;
+ }
+
+ if (!components[par_idx].inode) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
+ }
+
+ if (!components[ino_idx].inode && resolve->type == RESOLVE_MUST) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ goto out;
+ }
+
+ if (components[ino_idx].inode && resolve->type == RESOLVE_NOT) {
+ resolve->op_ret = -1;
+ resolve->op_errno = EEXIST;
+ goto out;
+ }
+
+ if (components[ino_idx].inode)
+ state->loc_now->inode = inode_ref (components[ino_idx].inode);
+ state->loc_now->parent = inode_ref (components[par_idx].inode);
+
+ ret = 0;
+
+out:
+ return ret;
+}
+
/*
Check if the requirements are fulfilled by entries in the inode cache itself
Return value:
@@ -503,7 +563,11 @@ server_resolve (call_frame_t *frame)
server_resolve_inode (frame);
- } else {
+ } else if (resolve->path) {
+
+ resolve_path_deep (frame);
+
+ } else {
resolve->op_ret = -1;
resolve->op_errno = EINVAL;