diff options
author | Anand Avati <avati@gluster.com> | 2009-12-06 13:48:43 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2009-12-06 11:44:48 -0800 |
commit | 33f3abffe4f0de929d3732a472ad3df766d575b7 (patch) | |
tree | 81865b47cafbe32500c1cebaa554ad07d3a46f6d /xlators/protocol/server/src | |
parent | f08a2073d58ffff8c5b358fbb05702377a251b87 (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
Diffstat (limited to 'xlators/protocol/server/src')
-rw-r--r-- | xlators/protocol/server/src/server-resolve.c | 68 |
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; |