diff options
Diffstat (limited to 'xlators/protocol/server/src')
| -rw-r--r-- | xlators/protocol/server/src/server-helpers.c | 17 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-protocol.h | 11 | ||||
| -rw-r--r-- | xlators/protocol/server/src/server-resolve.c | 219 | 
3 files changed, 188 insertions, 59 deletions
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c index b074ab9b5d0..ae33d6848d9 100644 --- a/xlators/protocol/server/src/server-helpers.c +++ b/xlators/protocol/server/src/server-helpers.c @@ -190,11 +190,28 @@ server_loc_wipe (loc_t *loc)  void  server_resolve_wipe (server_resolve_t *resolve)  { +        struct resolve_comp *comp = NULL; +        int                  i = 0; +          if (resolve->path)                  FREE (resolve->path);          if (resolve->bname)                  FREE (resolve->bname); + +        if (resolve->resolved) +                FREE (resolve->resolved); + +        loc_wipe (&resolve->deep_loc); + +        comp = resolve->components; +        if (comp) { +                for (i = 0; comp[i].basename; i++) { +                        if (comp[i].inode) +                                inode_unref (comp[i].inode); +                } +                FREE (resolve->components); +        }  } diff --git a/xlators/protocol/server/src/server-protocol.h b/xlators/protocol/server/src/server-protocol.h index 24e3a55f01f..cb330ef1e1a 100644 --- a/xlators/protocol/server/src/server-protocol.h +++ b/xlators/protocol/server/src/server-protocol.h @@ -118,6 +118,14 @@ typedef enum {          RESOLVE_EXACT  } server_resolve_type_t; + +struct resolve_comp { +        char      *basename; +        ino_t      ino; +        uint64_t   gen; +        inode_t   *inode; +}; +  typedef struct {          server_resolve_type_t  type;          uint64_t               fd_no; @@ -129,6 +137,9 @@ typedef struct {  	char                  *resolved;          int                    op_ret;          int                    op_errno; +        loc_t                  deep_loc; +        struct resolve_comp   *components; +        int                    comp_count;  } server_resolve_t; diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c index ff7d3f89328..6989bd91524 100644 --- a/xlators/protocol/server/src/server-resolve.c +++ b/xlators/protocol/server/src/server-resolve.c @@ -26,15 +26,12 @@  #include "server-helpers.h" -struct resolve_comp { -        char      *basename; -        ino_t      ino; -        uint64_t   gen; -        inode_t   *inode; -}; -  int  server_resolve_all (call_frame_t *frame); +int +resolve_entry_simple (call_frame_t *frame); +int +resolve_inode_simple (call_frame_t *frame);  int  component_count (const char *path) @@ -54,9 +51,42 @@ component_count (const char *path)  int -prepare_components (server_resolve_t *resolve) +prepare_components (call_frame_t *frame)  { -//        char *path  = NULL; +        server_state_t       *state = NULL; +        xlator_t             *this = NULL; +        server_resolve_t     *resolve = NULL; +        char                 *resolved = NULL; +        int                   count = 0; +        struct resolve_comp  *components = NULL; +        int                   i = 0; +        char                 *trav = NULL; + + +        state = CALL_STATE (frame); +        this  = frame->this; +        resolve = state->resolve_now; + +        resolved = strdup (resolve->path); +        resolve->resolved = resolved; + +        count = component_count (resolve->path); +        components = CALLOC (sizeof (*components), count); +        resolve->components = components; + +        components[0].basename = ""; +        components[0].ino      = 1; +        components[0].gen      = 0; +        components[0].inode    = state->itable->root; + +        i = 1; +        for (trav = resolved; *trav; trav++) { +                if (*trav == '/') { +                        components[i].basename = trav + 1; +                        *trav = 0; +                        i++; +                } +        }          return 0;  } @@ -101,29 +131,28 @@ resolve_loc_touchup (call_frame_t *frame)  } -  int -server_resolve_fd (call_frame_t *frame) +resolve_deep_continue (call_frame_t *frame)  {          server_state_t       *state = NULL;          xlator_t             *this = NULL;          server_resolve_t     *resolve = NULL; -        server_connection_t  *conn = NULL; -        uint64_t              fd_no = -1; +        int                   ret = 0;          state = CALL_STATE (frame);          this  = frame->this;          resolve = state->resolve_now; -        conn  = SERVER_CONNECTION (frame); -        fd_no = resolve->fd_no; +        resolve->op_ret   = 0; +        resolve->op_errno = 0; -        state->fd = gf_fd_fdptr_get (conn->fdtable, fd_no); +        if (resolve->par) +                ret = resolve_entry_simple (frame); +        else +                ret = resolve_inode_simple (frame); -        if (!state->fd) { -                resolve->op_ret   = -1; -                resolve->op_errno = EBADF; -        } +        if (ret == 0) +                resolve_loc_touchup (frame);          server_resolve_all (frame); @@ -132,11 +161,70 @@ server_resolve_fd (call_frame_t *frame)  int -resolve_entry_deep (call_frame_t *frame) +resolve_deep_cbk (call_frame_t *frame, void *cookie, xlator_t *this, +                  int op_ret, int op_errno, inode_t *inode, struct stat *buf, +                  dict_t *xattr, struct stat *postparent) +{ +        server_state_t       *state = NULL; +        server_resolve_t     *resolve = NULL; +        struct resolve_comp  *components = NULL; +        int                   i = 0; +        inode_t              *link_inode = NULL; + +        state = CALL_STATE (frame); +        resolve = state->resolve_now; +        components = resolve->components; + +        i = (long) cookie; + +        if (op_ret == -1) { +                goto get_out_of_here; +        } + +        if (i != 0) { +                /* no linking for root inode */ +                link_inode = inode_link (inode, resolve->deep_loc.parent, +                                         resolve->deep_loc.name, buf); +                inode_lookup (link_inode); +                components[i].inode  = link_inode; +                link_inode = NULL; +        } + +        loc_wipe (&resolve->deep_loc); + +        i++; /* next component */ + +        if (!components[i].basename) { +                /* all components of the path are resolved */ +                goto get_out_of_here; +        } + +        /* join the current component with the path resolved until now */ +        *(components[i].basename - 1) = '/'; + +        resolve->deep_loc.path   = strdup (resolve->resolved); +        resolve->deep_loc.parent = inode_ref (components[i-1].inode); +        resolve->deep_loc.inode  = inode_new (state->itable); +        resolve->deep_loc.name   = components[i].basename; + +        STACK_WIND_COOKIE (frame, resolve_deep_cbk, (void *) (long) i, +                           BOUND_XL (frame), BOUND_XL (frame)->fops->lookup, +                           &resolve->deep_loc, NULL); +        return 0; + +get_out_of_here: +        resolve_deep_continue (frame); +        return 0; +} + + +int +resolve_path_deep (call_frame_t *frame)  {          server_state_t     *state = NULL;          xlator_t           *this = NULL;          server_resolve_t   *resolve = NULL; +        int                 i = 0;          state = CALL_STATE (frame);          this  = frame->this; @@ -145,15 +233,16 @@ resolve_entry_deep (call_frame_t *frame)          gf_log (frame->this->name, GF_LOG_WARNING,                  "seeking deep resolution of %s", resolve->path); -        if (resolve->type == RESOLVE_MUST) { -                resolve->op_ret = -1; -                resolve->op_errno = ENOENT; -        } +        prepare_components (frame); -        resolve_loc_touchup (frame); - -        server_resolve_all (frame); +        /* start from the root */ +        resolve->deep_loc.inode = state->itable->root; +        resolve->deep_loc.path  = strdup ("/"); +        resolve->deep_loc.name  = ""; +        STACK_WIND_COOKIE (frame, resolve_deep_cbk, (void *) (long) i, +                           BOUND_XL (frame), BOUND_XL (frame)->fops->lookup, +                           &resolve->deep_loc, NULL);          return 0;  } @@ -183,6 +272,8 @@ resolve_entry_simple (call_frame_t *frame)          if (!parent) {                  /* simple resolution is indecisive. need to perform                     deep resolution */ +                resolve->op_ret   = -1; +                resolve->op_errno = ENOENT;                  ret = 1;                  goto out;          } @@ -207,6 +298,8 @@ resolve_entry_simple (call_frame_t *frame)                          ret = 0;                          break;                  default: +                        resolve->op_ret   = -1; +                        resolve->op_errno = ENOENT;                          ret = 1;                          break;                  } @@ -243,15 +336,18 @@ server_resolve_entry (call_frame_t *frame)          xlator_t           *this = NULL;          server_resolve_t   *resolve = NULL;          int                 ret = 0; +        loc_t              *loc = NULL;          state = CALL_STATE (frame);          this  = frame->this;          resolve = state->resolve_now; +        loc  = state->loc_now;          ret = resolve_entry_simple (frame);          if (ret > 0) { -                resolve_entry_deep (frame); +                loc_wipe (loc); +                resolve_path_deep (frame);                  return 0;          } @@ -264,35 +360,6 @@ server_resolve_entry (call_frame_t *frame)  int -resolve_inode_deep (call_frame_t *frame) -{ -        server_state_t     *state = NULL; -        xlator_t           *this = NULL; -        server_resolve_t   *resolve = NULL; - -        state = CALL_STATE (frame); -        this  = frame->this; -        resolve = state->resolve_now; - -        gf_log (frame->this->name, GF_LOG_WARNING, -                "seeking deep resolution of %s", resolve->path); - -        if (resolve->type == RESOLVE_MUST) { -                resolve->op_ret = -1; -                resolve->op_errno = ENOENT; -                goto out; -        } - -        resolve_loc_touchup (frame); - -out: -        server_resolve_all (frame); - -        return 0; -} - - -int  resolve_inode_simple (call_frame_t *frame)  {          server_state_t     *state = NULL; @@ -312,6 +379,8 @@ resolve_inode_simple (call_frame_t *frame)          }          if (!inode) { +                resolve->op_ret   = -1; +                resolve->op_errno = ENOENT;                  ret = 1;                  goto out;          } @@ -342,15 +411,18 @@ server_resolve_inode (call_frame_t *frame)          xlator_t           *this = NULL;          server_resolve_t   *resolve = NULL;          int                 ret = 0; +        loc_t              *loc = NULL;          state = CALL_STATE (frame);          this  = frame->this;          resolve = state->resolve_now; +        loc  = state->loc_now;          ret = resolve_inode_simple (frame);          if (ret > 0) { -                resolve_inode_deep (frame); +                loc_wipe (loc); +                resolve_path_deep (frame);                  return 0;          } @@ -363,6 +435,35 @@ server_resolve_inode (call_frame_t *frame)  int +server_resolve_fd (call_frame_t *frame) +{ +        server_state_t       *state = NULL; +        xlator_t             *this = NULL; +        server_resolve_t     *resolve = NULL; +        server_connection_t  *conn = NULL; +        uint64_t              fd_no = -1; + +        state = CALL_STATE (frame); +        this  = frame->this; +        resolve = state->resolve_now; +        conn  = SERVER_CONNECTION (frame); + +        fd_no = resolve->fd_no; + +        state->fd = gf_fd_fdptr_get (conn->fdtable, fd_no); + +        if (!state->fd) { +                resolve->op_ret   = -1; +                resolve->op_errno = EBADF; +        } + +        server_resolve_all (frame); + +        return 0; +} + + +int  server_resolve (call_frame_t *frame)  {          server_state_t     *state = NULL;  | 
