summaryrefslogtreecommitdiffstats
path: root/xlators/mount/fuse/src/fuse-resolve.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mount/fuse/src/fuse-resolve.c')
-rw-r--r--xlators/mount/fuse/src/fuse-resolve.c253
1 files changed, 187 insertions, 66 deletions
diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c
index e89b4423151..b13cb360641 100644
--- a/xlators/mount/fuse/src/fuse-resolve.c
+++ b/xlators/mount/fuse/src/fuse-resolve.c
@@ -25,9 +25,9 @@
#include "fuse-bridge.h"
static int
-gf_resolve_all (fuse_state_t *state);
+fuse_resolve_all (fuse_state_t *state);
static int
-resolve_path_simple (fuse_state_t *state);
+fuse_resolve_path_simple (fuse_state_t *state);
static int
component_count (const char *path)
@@ -48,9 +48,9 @@ static int
prepare_components (fuse_state_t *state)
{
xlator_t *active_xl = NULL;
- gf_resolve_t *resolve = NULL;
+ fuse_resolve_t *resolve = NULL;
char *resolved = NULL;
- struct gf_resolve_comp *components = NULL;
+ struct fuse_resolve_comp *components = NULL;
char *trav = NULL;
int count = 0;
int i = 0;
@@ -87,9 +87,9 @@ out:
static int
-resolve_loc_touchup (fuse_state_t *state)
+fuse_resolve_loc_touchup (fuse_state_t *state)
{
- gf_resolve_t *resolve = NULL;
+ fuse_resolve_t *resolve = NULL;
loc_t *loc = NULL;
char *path = NULL;
int ret = 0;
@@ -129,7 +129,7 @@ fuse_resolve_newfd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, fd_t *fd)
{
fuse_state_t *state = NULL;
- gf_resolve_t *resolve = NULL;
+ fuse_resolve_t *resolve = NULL;
fd_t *old_fd = NULL;
fd_t *tmp_fd = NULL;
uint64_t tmp_fd_ctx = 0;
@@ -163,14 +163,14 @@ fuse_resolve_newfd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log ("resolve", GF_LOG_WARNING,
"failed to set the fd ctx with resolved fd");
out:
- gf_resolve_all (state);
+ fuse_resolve_all (state);
return 0;
}
static void
-gf_resolve_new_fd (fuse_state_t *state)
+fuse_resolve_new_fd (fuse_state_t *state)
{
- gf_resolve_t *resolve = NULL;
+ fuse_resolve_t *resolve = NULL;
fd_t *new_fd = NULL;
fd_t *fd = NULL;
@@ -189,9 +189,9 @@ gf_resolve_new_fd (fuse_state_t *state)
}
static int
-resolve_deep_continue (fuse_state_t *state)
+fuse_resolve_deep_continue (fuse_state_t *state)
{
- gf_resolve_t *resolve = NULL;
+ fuse_resolve_t *resolve = NULL;
int ret = 0;
resolve = state->resolve_now;
@@ -200,32 +200,32 @@ resolve_deep_continue (fuse_state_t *state)
resolve->op_errno = 0;
if (resolve->path)
- ret = resolve_path_simple (state);
+ ret = fuse_resolve_path_simple (state);
if (ret)
gf_log ("resolve", GF_LOG_TRACE,
"return value of resolve_*_simple %d", ret);
- resolve_loc_touchup (state);
+ fuse_resolve_loc_touchup (state);
/* This function is called by either fd resolve or inode resolve */
if (!resolve->fd)
- gf_resolve_all (state);
+ fuse_resolve_all (state);
else
- gf_resolve_new_fd (state);
+ fuse_resolve_new_fd (state);
return 0;
}
static int
-resolve_deep_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+fuse_resolve_deep_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, inode_t *inode, struct iatt *buf,
dict_t *xattr, struct iatt *postparent)
{
xlator_t *active_xl = NULL;
fuse_state_t *state = NULL;
- gf_resolve_t *resolve = NULL;
- struct gf_resolve_comp *components = NULL;
+ fuse_resolve_t *resolve = NULL;
+ struct fuse_resolve_comp *components = NULL;
inode_t *link_inode = NULL;
int i = 0;
@@ -269,22 +269,22 @@ resolve_deep_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
resolve->deep_loc.inode = inode_new (active_xl->itable);
resolve->deep_loc.name = components[i].basename;
- FUSE_FOP_COOKIE (state, active_xl, resolve_deep_cbk, (void *)(long)i,
+ FUSE_FOP_COOKIE (state, active_xl, fuse_resolve_deep_cbk, (void *)(long)i,
GF_FOP_LOOKUP, lookup, &resolve->deep_loc, NULL);
return 0;
get_out_of_here:
- resolve_deep_continue (state);
+ fuse_resolve_deep_continue (state);
return 0;
}
static int
-resolve_path_deep (fuse_state_t *state)
+fuse_resolve_path_deep (fuse_state_t *state)
{
xlator_t *active_xl = NULL;
- gf_resolve_t *resolve = NULL;
- struct gf_resolve_comp *components = NULL;
+ fuse_resolve_t *resolve = NULL;
+ struct fuse_resolve_comp *components = NULL;
inode_t *inode = NULL;
long i = 0;
@@ -317,21 +317,21 @@ resolve_path_deep (fuse_state_t *state)
resolve->deep_loc.inode = inode_new (active_xl->itable);
resolve->deep_loc.name = components[i].basename;
- FUSE_FOP_COOKIE (state, active_xl, resolve_deep_cbk, (void *)(long)i,
+ FUSE_FOP_COOKIE (state, active_xl, fuse_resolve_deep_cbk, (void *)(long)i,
GF_FOP_LOOKUP, lookup, &resolve->deep_loc, NULL);
return 0;
resolved:
- resolve_deep_continue (state);
+ fuse_resolve_deep_continue (state);
return 0;
}
static int
-resolve_path_simple (fuse_state_t *state)
+fuse_resolve_path_simple (fuse_state_t *state)
{
- gf_resolve_t *resolve = NULL;
- struct gf_resolve_comp *components = NULL;
+ fuse_resolve_t *resolve = NULL;
+ struct fuse_resolve_comp *components = NULL;
int ret = -1;
int par_idx = 0;
int ino_idx = 0;
@@ -387,10 +387,140 @@ out:
> 0 - indecisive, need to perform deep resolution
*/
+int
+fuse_resolve_entry_simple (fuse_state_t *state)
+{
+ xlator_t *active_xl = NULL;
+ xlator_t *this = NULL;
+ fuse_resolve_t *resolve = NULL;
+ inode_t *parent = NULL;
+ inode_t *inode = NULL;
+ int ret = 0;
+
+ this = state->this;
+ resolve = state->resolve_now;
+
+ active_xl = fuse_active_subvol (state->this);
+
+ parent = inode_find (active_xl->itable, resolve->pargfid);
+ if (!parent) {
+ /* simple resolution is indecisive. need to perform
+ deep resolution */
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ goto out;
+ }
+
+ /* expected @parent was found from the inode cache */
+ state->loc_now->parent = inode_ref (parent);
+
+ inode = inode_grep (active_xl->itable, parent, resolve->bname);
+ if (!inode) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ goto out;
+ }
+
+ ret = 0;
+
+ state->loc_now->inode = inode_ref (inode);
+
+out:
+ if (parent)
+ inode_unref (parent);
+
+ if (inode)
+ inode_unref (inode);
+
+ return ret;
+}
+
+
+int
+fuse_resolve_entry (fuse_state_t *state)
+{
+ int ret = 0;
+ loc_t *loc = NULL;
+
+ loc = state->loc_now;
+
+ ret = fuse_resolve_entry_simple (state);
+ if (ret > 0) {
+ loc_wipe (loc);
+ fuse_resolve_path_deep (state);
+ return 0;
+ }
+
+ if (ret == 0)
+ fuse_resolve_loc_touchup (state);
+
+ fuse_resolve_all (state);
+
+ return 0;
+}
+
+
+int
+fuse_resolve_inode_simple (fuse_state_t *state)
+{
+ xlator_t *active_xl = NULL;
+ fuse_resolve_t *resolve = NULL;
+ inode_t *inode = NULL;
+ int ret = 0;
+
+ resolve = state->resolve_now;
+ active_xl = fuse_active_subvol (state->this);
+
+ inode = inode_find (active_xl->itable, resolve->gfid);
+ if (!inode) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ goto out;
+ }
+
+ ret = 0;
+
+ state->loc_now->inode = inode_ref (inode);
+
+out:
+ if (inode)
+ inode_unref (inode);
+
+ return ret;
+}
+
+
+int
+fuse_resolve_inode (fuse_state_t *state)
+{
+ int ret = 0;
+ loc_t *loc = NULL;
+
+ loc = state->loc_now;
+
+ ret = fuse_resolve_inode_simple (state);
+
+ if (ret > 0) {
+ loc_wipe (loc);
+ fuse_resolve_path_deep (state);
+ return 0;
+ }
+
+ if (ret == 0)
+ fuse_resolve_loc_touchup (state);
+
+ fuse_resolve_all (state);
+
+ return 0;
+}
+
static int
-gf_resolve_fd (fuse_state_t *state)
+fuse_resolve_fd (fuse_state_t *state)
{
- gf_resolve_t *resolve = NULL;
+ fuse_resolve_t *resolve = NULL;
fd_t *fd = NULL;
int ret = 0;
uint64_t tmp_fd_ctx = 0;
@@ -405,7 +535,7 @@ gf_resolve_fd (fuse_state_t *state)
if (!ret) {
state->fd = (fd_t *)(long)tmp_fd_ctx;
fd_ref (state->fd);
- gf_resolve_all (state);
+ fuse_resolve_all (state);
goto out;
}
@@ -423,7 +553,7 @@ gf_resolve_fd (fuse_state_t *state)
state->loc_now = &state->loc;
- resolve_path_deep (state);
+ fuse_resolve_path_deep (state);
out:
return 0;
@@ -431,26 +561,34 @@ out:
static int
-gf_resolve (fuse_state_t *state)
+fuse_resolve (fuse_state_t *state)
{
- gf_resolve_t *resolve = NULL;
+ fuse_resolve_t *resolve = NULL;
resolve = state->resolve_now;
- if (resolve->path) {
+ if (resolve->fd) {
+
+ fuse_resolve_fd (state);
+
+ } else if (!uuid_is_null (resolve->pargfid)) {
+
+ fuse_resolve_entry (state);
+
+ } else if (!uuid_is_null (resolve->gfid)) {
- resolve_path_deep (state);
+ fuse_resolve_inode (state);
- } else if (resolve->fd) {
+ } else if (resolve->path) {
- gf_resolve_fd (state);
+ fuse_resolve_path_deep (state);
} else {
resolve->op_ret = 0;
resolve->op_errno = EINVAL;
- gf_resolve_all (state);
+ fuse_resolve_all (state);
}
return 0;
@@ -458,7 +596,7 @@ gf_resolve (fuse_state_t *state)
static int
-gf_resolve_done (fuse_state_t *state)
+fuse_resolve_done (fuse_state_t *state)
{
fuse_resume_fn_t fn = NULL;
@@ -482,25 +620,25 @@ out:
* state->resolve_now is used to decide which location/fd is to be resolved now
*/
static int
-gf_resolve_all (fuse_state_t *state)
+fuse_resolve_all (fuse_state_t *state)
{
if (state->resolve_now == NULL) {
state->resolve_now = &state->resolve;
state->loc_now = &state->loc;
- gf_resolve (state);
+ fuse_resolve (state);
} else if (state->resolve_now == &state->resolve) {
state->resolve_now = &state->resolve2;
state->loc_now = &state->loc2;
- gf_resolve (state);
+ fuse_resolve (state);
} else if (state->resolve_now == &state->resolve2) {
- gf_resolve_done (state);
+ fuse_resolve_done (state);
} else {
gf_log ("fuse-resolve", GF_LOG_ERROR,
@@ -563,31 +701,14 @@ fuse_resolve_and_resume (fuse_state_t *state, fuse_resume_fn_t fn)
if (state->fd)
goto resume;
- if (state->loc.path) {
- state->resolve.path = gf_strdup (state->loc.path);
- state->resolve.bname = gf_strdup (state->loc.name);
- /* TODO: make sure there is no leaks in inode refs */
- //loc_wipe (&state->loc);
- state->loc.inode = NULL;
- state->loc.parent = NULL;
- }
-
- /* Needed for rename and link */
- if (state->loc2.path) {
- state->resolve2.path = gf_strdup (state->loc2.path);
- state->resolve2.bname = gf_strdup (state->loc2.name);
- //loc_wipe (&state->loc2);
- state->loc2.inode = NULL;
- state->loc2.parent = NULL;
- }
-
+ /*
if (state->fd) {
state->resolve.fd = state->fd;
- /* TODO: check if its a leak, if yes, then do 'unref' */
- state->fd = NULL;
+ state->fd = NULL; // TODO: we may need a 'fd_unref()' here, not very sure'
}
+ */
- gf_resolve_all (state);
+ fuse_resolve_all (state);
return 0;
resume: