summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Avati <avati@gluster.com>2012-01-13 13:27:15 +0530
committerAnand Avati <avati@gluster.com>2012-01-20 05:03:42 -0800
commit7e1f8e3bac201f88e2d9ef62fc69a044716dfced (patch)
tree77540dbf1def2c864f8ae55f2293dba4a1d47488
parent33c568ce1a28c1739f095611b40b7acf40e4e6df (diff)
core: GFID filehandle based backend and anonymous FDs
1. What -------- This change introduces an infrastructure change in the filesystem which lets filesystem operation address objects (inodes) just by its GFID. Thus far GFID has been a unique identifier of a user-visible inode. But in terms of addressability the only mechanism thus far has been the backend filesystem path, which could be derived from the GFID only if it was cached in the inode table along with the entire set of dentry ancestry leading up to the root. This change essentially decouples addressability from the namespace. It is no more necessary to be aware of the parent directory to address a file or directory. 2. Why ------- The biggest use case for such a feature is NFS for generating persistent filehandles. So far the technique for generating filehandles in NFS has been to encode path components so that the appropriate inode_t can be repopulated into the inode table by means of a recursive lookup of each component top-down. Another use case is the ability to perform more intelligent self-healing and rebalancing of inodes with hardlinks and also to detect renames. A derived feature from GFID filehandles is anonymous FDs. An anonymous FD is an internal USABLE "fd_t" which does not map to a user opened file descriptor or to an internal ->open()'d fd. The ability to address a file by the GFID eliminates the need to have a persistent ->open()'d fd for the purpose of avoiding the namespace. This improves NFS read/write performance significantly eliminating open/close calls and also fixes some of today's limitations (like keeping an FD open longer than necessary resulting in disk space leakage) 3. How ------- At each storage/posix translator level, every file is hardlinked inside a hidden .glusterfs directory (under the top level export) with the name as the ascii-encoded standard UUID format string. For reasons of performance and scalability there is a two-tier classification of those hardlinks under directories with the initial parts of the UUID string as the directory names. For directories (which cannot be hardlinked), the approach is to use a symlink which dereferences the parent GFID path along with basename of the directory. The parent GFID dereference will in turn be a dereference of the grandparent with the parent's basename, and so on recursively up to the root export. 4. Development --------------- 4a. To leverage the ability to address an inode by its GFID, the technique is to perform a "nameless lookup". This means, to populate a loc_t structure as: loc_t { pargfid: NULL parent: NULL name: NULL path: NULL gfid: GFID to be looked up [out parameter] inode: inode_new () result [in parameter] } and performing such lookup will return in its callback an inode_t populated with the right contexts and a struct iatt which can be used to perform an inode_link () on the inode (without a parent and basename). The inode will now be hashed and linked in the inode table and findable via inode_find(). A fundamental change moving forward is that the primary fields in a loc_t structure are now going to be (pargfid, name) and (gfid) depending on the kind of FOP. So far path had been the primary field for operations. The remaining fields only serve as hints/helpers. 4b. If read/write is to be performed on an inode_t, the approach so far has been to: fd_create(), STACK_WIND(open, fd), fd_bind (in callback) and then perform STACK_WIND(read, fd) etc. With anonymous fds now you can do fd_anonymous (inode), STACK_WIND (read, fd). This results in great boost in performance in the inbuilt NFS server. 5. Misc ------- The inode_ctx_put[2] has been renamed to inode_ctx_set[2] to be consistent with the rest of the codebase. Change-Id: Ie4629edf6bd32a595f4d7f01e90c0a01f16fb12f BUG: 781318 Reviewed-on: http://review.gluster.com/669 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@gluster.com>
-rw-r--r--libglusterfs/src/fd.c139
-rw-r--r--libglusterfs/src/fd.h10
-rw-r--r--libglusterfs/src/inode.c128
-rw-r--r--libglusterfs/src/inode.h52
-rw-r--r--libglusterfs/src/xlator.c4
-rw-r--r--xlators/cluster/afr/src/afr-common.c138
-rw-r--r--xlators/cluster/afr/src/afr-dir-write.c5
-rw-r--r--xlators/cluster/afr/src/afr-inode-write.c6
-rw-r--r--xlators/cluster/afr/src/afr-self-heal-common.c6
-rw-r--r--xlators/cluster/afr/src/afr-transaction.c41
-rw-r--r--xlators/cluster/afr/src/afr.h3
-rw-r--r--xlators/cluster/dht/src/dht-common.c246
-rw-r--r--xlators/cluster/dht/src/dht-helper.c2
-rw-r--r--xlators/cluster/dht/src/dht-selfheal.c8
-rw-r--r--xlators/features/marker/src/marker.c20
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c1
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h7
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c15
-rw-r--r--xlators/mount/fuse/src/fuse-resolve.c400
-rw-r--r--xlators/performance/quick-read/src/quick-read.c28
-rw-r--r--xlators/performance/read-ahead/src/read-ahead.c78
-rw-r--r--xlators/performance/stat-prefetch/src/stat-prefetch.c6
-rw-r--r--xlators/performance/write-behind/src/write-behind.c113
-rw-r--r--xlators/protocol/client/src/client.h24
-rw-r--r--xlators/protocol/client/src/client3_1-fops.c124
-rw-r--r--xlators/protocol/server/src/server-helpers.c17
-rw-r--r--xlators/protocol/server/src/server-resolve.c388
-rw-r--r--xlators/protocol/server/src/server.h5
-rw-r--r--xlators/protocol/server/src/server3_1-fops.c85
-rw-r--r--xlators/storage/posix/src/Makefile.am4
-rw-r--r--xlators/storage/posix/src/posix-handle.c621
-rw-r--r--xlators/storage/posix/src/posix-handle.h148
-rw-r--r--xlators/storage/posix/src/posix-helpers.c323
-rw-r--r--xlators/storage/posix/src/posix.c730
-rw-r--r--xlators/storage/posix/src/posix.h36
35 files changed, 2403 insertions, 1558 deletions
diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c
index 47b42aef4..50a564ee6 100644
--- a/libglusterfs/src/fd.c
+++ b/libglusterfs/src/fd.c
@@ -35,7 +35,7 @@ gf_fd_fdtable_expand (fdtable_t *fdtable, uint32_t nr);
fd_t *
-_fd_ref (fd_t *fd);
+__fd_ref (fd_t *fd);
static int
gf_fd_chain_fd_entries (fdentry_t *entries, uint32_t startidx,
@@ -269,6 +269,10 @@ gf_fd_put (fdtable_t *fdtable, int32_t fd)
fd_t *fdptr = NULL;
fdentry_t *fde = NULL;
+ if (fd == -2)
+ /* anonymous fd */
+ return;
+
if (fdtable == NULL || fd < 0) {
gf_log_callingfn ("fd", GF_LOG_ERROR, "invalid argument");
return;
@@ -336,7 +340,7 @@ gf_fd_fdptr_get (fdtable_t *fdtable, int64_t fd)
fd_t *
-_fd_ref (fd_t *fd)
+__fd_ref (fd_t *fd)
{
++fd->refcount;
@@ -355,7 +359,7 @@ fd_ref (fd_t *fd)
}
LOCK (&fd->inode->lock);
- refed_fd = _fd_ref (fd);
+ refed_fd = __fd_ref (fd);
UNLOCK (&fd->inode->lock);
return refed_fd;
@@ -363,7 +367,7 @@ fd_ref (fd_t *fd)
fd_t *
-_fd_unref (fd_t *fd)
+__fd_unref (fd_t *fd)
{
GF_ASSERT (fd->refcount);
@@ -443,7 +447,7 @@ fd_unref (fd_t *fd)
LOCK (&fd->inode->lock);
{
- _fd_unref (fd);
+ __fd_unref (fd);
refcount = fd->refcount;
}
UNLOCK (&fd->inode->lock);
@@ -457,28 +461,34 @@ fd_unref (fd_t *fd)
fd_t *
-fd_bind (fd_t *fd)
+__fd_bind (fd_t *fd)
{
- inode_t *inode = NULL;
+ list_add (&fd->inode_list, &fd->inode->fd_list);
+
+ return fd;
+}
+
+fd_t *
+fd_bind (fd_t *fd)
+{
if (!fd || !fd->inode) {
gf_log_callingfn ("fd", GF_LOG_ERROR, "!fd || !fd->inode");
return NULL;
}
- inode = fd->inode;
- LOCK (&inode->lock);
+ LOCK (&fd->inode->lock);
{
- list_add (&fd->inode_list, &inode->fd_list);
+ fd = __fd_bind (fd);
}
- UNLOCK (&inode->lock);
+ UNLOCK (&fd->inode->lock);
return fd;
}
-fd_t *
-fd_create (inode_t *inode, pid_t pid)
+static fd_t *
+__fd_create (inode_t *inode, pid_t pid)
{
fd_t *fd = NULL;
@@ -506,22 +516,52 @@ fd_create (inode_t *inode, pid_t pid)
INIT_LIST_HEAD (&fd->inode_list);
LOCK_INIT (&fd->lock);
+out:
+ return fd;
+}
+
+
+fd_t *
+fd_create (inode_t *inode, pid_t pid)
+{
+ fd_t *fd = NULL;
+
+ fd = __fd_create (inode, pid);
+ if (!fd)
+ goto out;
+
+ fd = fd_ref (fd);
- LOCK (&inode->lock);
- {
- fd = _fd_ref (fd);
- }
- UNLOCK (&inode->lock);
out:
return fd;
}
+static fd_t *
+__fd_lookup (inode_t *inode, pid_t pid)
+{
+ fd_t *iter_fd = NULL;
+ fd_t *fd = NULL;
+
+ if (list_empty (&inode->fd_list))
+ return NULL;
+
+
+ list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
+ if (!pid || iter_fd->pid == pid) {
+ fd = __fd_ref (iter_fd);
+ break;
+ }
+ }
+
+ return fd;
+}
+
+
fd_t *
fd_lookup (inode_t *inode, pid_t pid)
{
fd_t *fd = NULL;
- fd_t *iter_fd = NULL;
if (!inode) {
gf_log_callingfn ("fd", GF_LOG_WARNING, "!inode");
@@ -530,21 +570,45 @@ fd_lookup (inode_t *inode, pid_t pid)
LOCK (&inode->lock);
{
- if (list_empty (&inode->fd_list)) {
- fd = NULL;
- } else {
- list_for_each_entry (iter_fd, &inode->fd_list, inode_list) {
- if (pid) {
- if (iter_fd->pid == pid) {
- fd = _fd_ref (iter_fd);
- break;
- }
- } else {
- fd = _fd_ref (iter_fd);
- break;
- }
- }
- }
+ fd = __fd_lookup (inode, pid);
+ }
+ UNLOCK (&inode->lock);
+
+ return fd;
+}
+
+
+
+fd_t *
+__fd_anonymous (inode_t *inode)
+{
+ fd_t *fd = NULL;
+
+ fd = __fd_lookup (inode, -1);
+
+ if (!fd) {
+ fd = __fd_create (inode, -1);
+
+ if (!fd)
+ return NULL;
+
+ __fd_bind (fd);
+ }
+
+ __fd_ref (fd);
+
+ return fd;
+}
+
+
+fd_t *
+fd_anonymous (inode_t *inode)
+{
+ fd_t *fd = NULL;
+
+ LOCK (&inode->lock);
+ {
+ fd = __fd_anonymous (inode);
}
UNLOCK (&inode->lock);
@@ -552,6 +616,13 @@ fd_lookup (inode_t *inode, pid_t pid)
}
+gf_boolean_t
+fd_is_anonymous (fd_t *fd)
+{
+ return (fd && fd->pid == -1);
+}
+
+
uint8_t
fd_list_empty (inode_t *inode)
{
diff --git a/libglusterfs/src/fd.h b/libglusterfs/src/fd.h
index 3c2be972a..d4cd9bd06 100644
--- a/libglusterfs/src/fd.h
+++ b/libglusterfs/src/fd.h
@@ -132,6 +132,14 @@ fd_t *
fd_lookup (struct _inode *inode, pid_t pid);
+fd_t *
+fd_anonymous (inode_t *inode);
+
+
+gf_boolean_t
+fd_is_anonymous (fd_t *fd);
+
+
uint8_t
fd_list_empty (struct _inode *inode);
@@ -164,7 +172,7 @@ int
__fd_ctx_del (fd_t *fd, xlator_t *xlator, uint64_t *value);
fd_t *
-_fd_ref (fd_t *fd);
+__fd_ref (fd_t *fd);
void
fd_ctx_dump (fd_t *fd, char *prefix);
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
index 3513691c4..c23f0f0e5 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -660,6 +660,39 @@ inode_grep (inode_table_t *table, inode_t *parent, const char *name)
return inode;
}
+int
+inode_grep_for_gfid (inode_table_t *table, inode_t *parent, const char *name,
+ uuid_t gfid, ia_type_t *type)
+{
+ inode_t *inode = NULL;
+ dentry_t *dentry = NULL;
+ int ret = -1;
+
+ if (!table || !parent || !name) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING,
+ "table || parent || name not found");
+ return ret;
+ }
+
+ pthread_mutex_lock (&table->lock);
+ {
+ dentry = __dentry_grep (table, parent, name);
+
+ if (dentry)
+ inode = dentry->inode;
+
+ if (inode) {
+ uuid_copy (gfid, inode->gfid);
+ *type = inode->ia_type;
+ ret = 0;
+ }
+ }
+ pthread_mutex_unlock (&table->lock);
+
+ return ret;
+}
+
+
/* return 1 if gfid is of root, 0 if not */
gf_boolean_t
__is_root_gfid (uuid_t gfid)
@@ -998,6 +1031,7 @@ int
__inode_path (inode_t *inode, const char *name, char **bufp)
{
inode_table_t *table = NULL;
+ inode_t *itrav = NULL;
dentry_t *trav = NULL;
size_t i = 0, size = 0;
int64_t ret = 0;
@@ -1011,8 +1045,10 @@ __inode_path (inode_t *inode, const char *name, char **bufp)
table = inode->table;
- for (trav = __dentry_search_arbit (inode); trav;
- trav = __dentry_search_arbit (trav->parent)) {
+ itrav = inode;
+ for (trav = __dentry_search_arbit (itrav); trav;
+ trav = __dentry_search_arbit (itrav)) {
+ itrav = trav->parent;
i ++; /* "/" */
i += strlen (trav->name);
if (i > PATH_MAX) {
@@ -1024,13 +1060,9 @@ __inode_path (inode_t *inode, const char *name, char **bufp)
}
}
- if (!__is_root_gfid (inode->gfid) &&
- (i == 0)) {
- gf_log (table->name, GF_LOG_WARNING,
- "no dentry for non-root inode : %s",
- uuid_utoa (inode->gfid));
- ret = -ENOENT;
- goto out;
+ if (!__is_root_gfid (itrav->gfid)) {
+ /* "<gfid:00000000-0000-0000-0000-000000000000>"/path */
+ i += GFID_STR_PFX_LEN;
}
if (name) {
@@ -1052,13 +1084,22 @@ __inode_path (inode_t *inode, const char *name, char **bufp)
i -= (len + 1);
}
- for (trav = __dentry_search_arbit (inode); trav;
- trav = __dentry_search_arbit (trav->parent)) {
+ itrav = inode;
+ for (trav = __dentry_search_arbit (itrav); trav;
+ trav = __dentry_search_arbit (itrav)) {
+ itrav = trav->parent;
len = strlen (trav->name);
strncpy (buf + (i - len), trav->name, len);
buf[i-len-1] = '/';
i -= (len + 1);
}
+
+ if (!__is_root_gfid (itrav->gfid)) {
+ snprintf (&buf[i-GFID_STR_PFX_LEN], GFID_STR_PFX_LEN,
+ "<gfid:%s>", uuid_utoa (itrav->gfid));
+ buf[i-1] = '>';
+ }
+
*bufp = buf;
} else {
ret = -ENOMEM;
@@ -1323,45 +1364,47 @@ out:
int
-__inode_ctx_put2 (inode_t *inode, xlator_t *xlator, uint64_t value1,
- uint64_t value2)
+__inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
+ uint64_t *value2_p)
{
int ret = 0;
int index = 0;
- int put_idx = -1;
+ int set_idx = -1;
if (!inode || !xlator)
return -1;
for (index = 0; index < xlator->graph->xl_count; index++) {
if (!inode->_ctx[index].xl_key) {
- if (put_idx == -1)
- put_idx = index;
+ if (set_idx == -1)
+ set_idx = index;
/* dont break, to check if key already exists
further on */
}
if (inode->_ctx[index].xl_key == xlator) {
- put_idx = index;
+ set_idx = index;
break;
}
}
- if (put_idx == -1) {
+ if (set_idx == -1) {
ret = -1;
goto out;;
}
- inode->_ctx[put_idx].xl_key = xlator;
- inode->_ctx[put_idx].value1 = value1;
- inode->_ctx[put_idx].value2 = value2;
+ inode->_ctx[set_idx].xl_key = xlator;
+ if (value1_p)
+ inode->_ctx[set_idx].value1 = *value1_p;
+ if (value2_p)
+ inode->_ctx[set_idx].value2 = *value2_p;
out:
return ret;
}
int
-inode_ctx_put2 (inode_t *inode, xlator_t *xlator, uint64_t value1,
- uint64_t value2)
+inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1_p,
+ uint64_t *value2_p)
{
int ret = 0;
@@ -1370,7 +1413,7 @@ inode_ctx_put2 (inode_t *inode, xlator_t *xlator, uint64_t value1,
LOCK (&inode->lock);
{
- ret = __inode_ctx_put2 (inode, xlator, value1, value2);
+ ret = __inode_ctx_set2 (inode, xlator, value1_p, value2_p);
}
UNLOCK (&inode->lock);
@@ -1466,41 +1509,6 @@ unlock:
}
-int
-__inode_ctx_put (inode_t *inode, xlator_t *key, uint64_t value)
-{
- return __inode_ctx_put2 (inode, key, value, 0);
-}
-
-
-int
-inode_ctx_put (inode_t *inode, xlator_t *key, uint64_t value)
-{
- return inode_ctx_put2 (inode, key, value, 0);
-}
-
-
-int
-__inode_ctx_get (inode_t *inode, xlator_t *key, uint64_t *value)
-{
- return __inode_ctx_get2 (inode, key, value, 0);
-}
-
-
-int
-inode_ctx_get (inode_t *inode, xlator_t *key, uint64_t *value)
-{
- return inode_ctx_get2 (inode, key, value, 0);
-}
-
-
-int
-inode_ctx_del (inode_t *inode, xlator_t *key, uint64_t *value)
-{
- return inode_ctx_del2 (inode, key, value, 0);
-}
-
-
void
inode_dump (inode_t *inode, char *prefix)
{
@@ -1557,7 +1565,7 @@ inode_dump (inode_t *inode, char *prefix)
INIT_LIST_HEAD (&fd_wrapper->next);
list_add_tail (&fd_wrapper->next, &fd_list);
- fd_wrapper->fd = _fd_ref (fd);
+ fd_wrapper->fd = __fd_ref (fd);
}
}
unlock:
diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h
index df415286b..7dda0401d 100644
--- a/libglusterfs/src/inode.h
+++ b/libglusterfs/src/inode.h
@@ -106,6 +106,10 @@ struct _inode {
};
+#define UUID0_STR "00000000-0000-0000-0000-000000000000"
+#define GFID_STR_PFX "<gfid:" UUID0_STR ">"
+#define GFID_STR_PFX_LEN (sizeof (GFID_STR_PFX) - 1)
+
inode_table_t *
inode_table_new (size_t lru_limit, xlator_t *xl);
@@ -142,6 +146,10 @@ inode_rename (inode_table_t *table, inode_t *olddir, const char *oldname,
inode_t *
inode_grep (inode_table_t *table, inode_t *parent, const char *name);
+int
+inode_grep_for_gfid (inode_table_t *table, inode_t *parent, const char *name,
+ uuid_t gfid, ia_type_t *type);
+
inode_t *
inode_find (inode_table_t *table, uuid_t gfid);
@@ -155,32 +163,44 @@ inode_t *
inode_from_path (inode_table_t *table, const char *path);
int
-__inode_ctx_put (inode_t *inode, xlator_t *xlator, uint64_t value);
-
-int
-inode_ctx_put (inode_t *inode, xlator_t *xlator, uint64_t value);
-
-int
-__inode_ctx_get (inode_t *inode, xlator_t *xlator, uint64_t *value);
-
-int
-inode_ctx_get (inode_t *inode, xlator_t *xlator, uint64_t *value);
-
-int
-inode_ctx_del (inode_t *inode, xlator_t *xlator, uint64_t *value);
-
+inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
int
-inode_ctx_put2 (inode_t *inode, xlator_t *xlator, uint64_t value1,
- uint64_t value2);
+__inode_ctx_set2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
int
inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
uint64_t *value2);
+int
+__inode_ctx_get2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
+ uint64_t *value2);
int
inode_ctx_del2 (inode_t *inode, xlator_t *xlator, uint64_t *value1,
uint64_t *value2);
+#define __inode_ctx_set(i,x,v_p) __inode_ctx_set2(i,x,v_p,0)
+#define inode_ctx_set(i,x,v_p) inode_ctx_set2(i,x,v_p,0)
+
+static inline int
+__inode_ctx_put(inode_t *inode, xlator_t *this, uint64_t v)
+{
+ return __inode_ctx_set2 (inode, this, &v, 0);
+}
+
+static inline int
+inode_ctx_put(inode_t *inode, xlator_t *this, uint64_t v)
+{
+ return inode_ctx_set2(inode, this, &v, 0);
+}
+
+#define __inode_ctx_get(i,x,v) __inode_ctx_get2(i,x,v,0)
+#define inode_ctx_get(i,x,v) inode_ctx_get2(i,x,v,0)
+
+#define inode_ctx_del(i,x,v) inode_ctx_del2(i,x,v,0)
+
+
gf_boolean_t
__is_root_gfid (uuid_t gfid);
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
index 023cbc940..160ac2d63 100644
--- a/libglusterfs/src/xlator.c
+++ b/libglusterfs/src/xlator.c
@@ -544,8 +544,8 @@ loc_wipe (loc_t *loc)
inode_unref (loc->parent);
loc->parent = NULL;
}
- uuid_clear (loc->gfid);
- uuid_clear (loc->pargfid);
+
+ memset (loc, 0, sizeof (*loc));
}
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c
index c247d56b7..83b91cd3e 100644
--- a/xlators/cluster/afr/src/afr-common.c
+++ b/xlators/cluster/afr/src/afr-common.c
@@ -2071,7 +2071,7 @@ out:
/* {{{ open */
int
-afr_fd_ctx_set (xlator_t *this, fd_t *fd)
+__afr_fd_ctx_set (xlator_t *this, fd_t *fd)
{
afr_private_t * priv = NULL;
int ret = -1;
@@ -2083,82 +2083,92 @@ afr_fd_ctx_set (xlator_t *this, fd_t *fd)
priv = this->private;
- LOCK (&fd->lock);
- {
- ret = __fd_ctx_get (fd, this, &ctx);
+ ret = __fd_ctx_get (fd, this, &ctx);
- if (ret == 0)
- goto unlock;
+ if (ret == 0)
+ goto out;
- fd_ctx = GF_CALLOC (1, sizeof (afr_fd_ctx_t),
- gf_afr_mt_afr_fd_ctx_t);
- if (!fd_ctx) {
- ret = -ENOMEM;
- goto unlock;
- }
+ fd_ctx = GF_CALLOC (1, sizeof (afr_fd_ctx_t),
+ gf_afr_mt_afr_fd_ctx_t);
+ if (!fd_ctx) {
+ ret = -ENOMEM;
+ goto out;
+ }
- fd_ctx->pre_op_done = GF_CALLOC (sizeof (*fd_ctx->pre_op_done),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->pre_op_done) {
- ret = -ENOMEM;
- goto unlock;
- }
+ fd_ctx->pre_op_done = GF_CALLOC (sizeof (*fd_ctx->pre_op_done),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->pre_op_done) {
+ ret = -ENOMEM;
+ goto out;
+ }
- fd_ctx->pre_op_piggyback = GF_CALLOC (sizeof (*fd_ctx->pre_op_piggyback),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->pre_op_piggyback) {
- ret = -ENOMEM;
- goto unlock;
- }
+ fd_ctx->pre_op_piggyback = GF_CALLOC (sizeof (*fd_ctx->pre_op_piggyback),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->pre_op_piggyback) {
+ ret = -ENOMEM;
+ goto out;
+ }
- fd_ctx->opened_on = GF_CALLOC (sizeof (*fd_ctx->opened_on),
- priv->child_count,
- gf_afr_mt_int32_t);
- if (!fd_ctx->opened_on) {
- ret = -ENOMEM;
- goto unlock;
- }
+ fd_ctx->opened_on = GF_CALLOC (sizeof (*fd_ctx->opened_on),
+ priv->child_count,
+ gf_afr_mt_int32_t);
+ if (!fd_ctx->opened_on) {
+ ret = -ENOMEM;
+ goto out;
+ }
- fd_ctx->lock_piggyback = GF_CALLOC (sizeof (*fd_ctx->lock_piggyback),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->lock_piggyback) {
- ret = -ENOMEM;
- goto unlock;
- }
+ fd_ctx->lock_piggyback = GF_CALLOC (sizeof (*fd_ctx->lock_piggyback),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->lock_piggyback) {
+ ret = -ENOMEM;
+ goto out;
+ }
- fd_ctx->lock_acquired = GF_CALLOC (sizeof (*fd_ctx->lock_acquired),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->lock_acquired) {
- ret = -ENOMEM;
- goto unlock;
- }
+ fd_ctx->lock_acquired = GF_CALLOC (sizeof (*fd_ctx->lock_acquired),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->lock_acquired) {
+ ret = -ENOMEM;
+ goto out;
+ }
- fd_ctx->up_count = priv->up_count;
- fd_ctx->down_count = priv->down_count;
+ fd_ctx->up_count = priv->up_count;
+ fd_ctx->down_count = priv->down_count;
- fd_ctx->locked_on = GF_CALLOC (sizeof (*fd_ctx->locked_on),
- priv->child_count,
- gf_afr_mt_char);
- if (!fd_ctx->locked_on) {
- ret = -ENOMEM;
- goto unlock;
- }
+ fd_ctx->locked_on = GF_CALLOC (sizeof (*fd_ctx->locked_on),
+ priv->child_count,
+ gf_afr_mt_char);
+ if (!fd_ctx->locked_on) {
+ ret = -ENOMEM;
+ goto out;
+ }
- INIT_LIST_HEAD (&fd_ctx->paused_calls);
- INIT_LIST_HEAD (&fd_ctx->entries);
+ INIT_LIST_HEAD (&fd_ctx->paused_calls);
+ INIT_LIST_HEAD (&fd_ctx->entries);
- ret = __fd_ctx_set (fd, this, (uint64_t)(long) fd_ctx);
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG,
- "failed to set fd ctx (%p)", fd);
+ ret = __fd_ctx_set (fd, this, (uint64_t)(long) fd_ctx);
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to set fd ctx (%p)", fd);
+out:
+ return ret;
+}
+
+
+int
+afr_fd_ctx_set (xlator_t *this, fd_t *fd)
+{
+ int ret = -1;
+
+ LOCK (&fd->lock);
+ {
+ ret = __afr_fd_ctx_set (this, fd);
}
-unlock:
UNLOCK (&fd->lock);
-out:
+
return ret;
}
diff --git a/xlators/cluster/afr/src/afr-dir-write.c b/xlators/cluster/afr/src/afr-dir-write.c
index 4d2fcd226..91aa2a9e7 100644
--- a/xlators/cluster/afr/src/afr-dir-write.c
+++ b/xlators/cluster/afr/src/afr-dir-write.c
@@ -974,11 +974,10 @@ afr_link (call_frame_t *frame, xlator_t *this,
local->transaction.done = afr_link_done;
local->transaction.unwind = afr_link_unwind;
- afr_build_parent_loc (&local->transaction.parent_loc, oldloc);
+ afr_build_parent_loc (&local->transaction.parent_loc, newloc);
local->transaction.main_frame = frame;
- local->transaction.basename = AFR_BASENAME (oldloc->path);
- local->transaction.new_basename = AFR_BASENAME (newloc->path);
+ local->transaction.basename = AFR_BASENAME (newloc->path);
afr_transaction (transaction_frame, this, AFR_ENTRY_TRANSACTION);
diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c
index 3deca8df1..bb8b5f0fe 100644
--- a/xlators/cluster/afr/src/afr-inode-write.c
+++ b/xlators/cluster/afr/src/afr-inode-write.c
@@ -356,6 +356,12 @@ afr_open_fd_fix (call_frame_t *frame, xlator_t *this, gf_boolean_t pause_fop)
priv = this->private;
GF_ASSERT (local->fd);
+
+ if (fd_is_anonymous (local->fd)) {
+ fop_continue = _gf_true;
+ goto out;
+ }
+
if (pause_fop)
GF_ASSERT (local->fop_call_continue);
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
index ad84f8541..5acbf90aa 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -2142,6 +2142,12 @@ afr_self_heal (call_frame_t *frame, xlator_t *this, inode_t *inode)
UNLOCK (&priv->lock);
}
+ if (!local->loc.name) {
+ /* nameless lookup */
+ sh->do_missing_entry_self_heal = _gf_false;
+ sh->do_gfid_self_heal = _gf_false;
+ }
+
FRAME_SU_DO (sh_frame, afr_local_t);
if (sh->do_missing_entry_self_heal) {
afr_self_heal_conflicting_entries (sh_frame, this);
diff --git a/xlators/cluster/afr/src/afr-transaction.c b/xlators/cluster/afr/src/afr-transaction.c
index 6ae493f1c..36d74aed8 100644
--- a/xlators/cluster/afr/src/afr-transaction.c
+++ b/xlators/cluster/afr/src/afr-transaction.c
@@ -34,24 +34,53 @@
afr_fd_ctx_t *
-afr_fd_ctx_get (fd_t *fd, xlator_t *this)
+__afr_fd_ctx_get (fd_t *fd, xlator_t *this)
{
uint64_t ctx = 0;
- afr_fd_ctx_t *fd_ctx = NULL;
int ret = 0;
+ afr_fd_ctx_t *fd_ctx = NULL;
+ int i = 0;
+ afr_private_t *priv = NULL;
- ret = fd_ctx_get (fd, this, &ctx);
+ priv = this->private;
- if (ret < 0)
- goto out;
+ ret = __fd_ctx_get (fd, this, &ctx);
- fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+ if (ret < 0 && fd_is_anonymous (fd)) {
+ ret = __afr_fd_ctx_set (this, fd);
+ if (ret < 0)
+ goto out;
+
+ ret = __fd_ctx_get (fd, this, &ctx);
+ if (ret < 0)
+ goto out;
+
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
+ for (i = 0; i < priv->child_count; i++)
+ fd_ctx->opened_on[i] = AFR_FD_OPENED;
+ }
+ fd_ctx = (afr_fd_ctx_t *)(long) ctx;
out:
return fd_ctx;
}
+afr_fd_ctx_t *
+afr_fd_ctx_get (fd_t *fd, xlator_t *this)
+{
+ afr_fd_ctx_t *fd_ctx = NULL;
+
+ LOCK(&fd->lock);
+ {
+ fd_ctx = __afr_fd_ctx_get (fd, this);
+ }
+ UNLOCK(&fd->lock);
+
+ return fd_ctx;
+}
+
+
static void
afr_pid_save (call_frame_t *frame)
{
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index 544c91424..0ff300085 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -791,6 +791,9 @@ afr_lk_transfer_datalock (call_frame_t *dst, call_frame_t *src,
int pump_start (call_frame_t *frame, xlator_t *this);
int
+__afr_fd_ctx_set (xlator_t *this, fd_t *fd);
+
+int
afr_fd_ctx_set (xlator_t *this, fd_t *fd);
int32_t
diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c
index 785ecbc61..d371fc442 100644
--- a/xlators/cluster/dht/src/dht-common.c
+++ b/xlators/cluster/dht/src/dht-common.c
@@ -147,6 +147,246 @@ out:
int
+dht_discover_complete (xlator_t *this, call_frame_t *discover_frame)
+{
+ dht_local_t *local = NULL;
+ call_frame_t *main_frame = NULL;
+ int op_errno = 0;
+ int ret = -1;
+ dht_layout_t *layout = NULL;
+
+ local = discover_frame->local;
+ layout = local->layout;
+
+ LOCK(&discover_frame->lock);
+ {
+ main_frame = local->main_frame;
+ local->main_frame = NULL;
+ }
+ UNLOCK(&discover_frame->lock);
+
+ if (!main_frame)
+ return 0;
+
+ if (local->file_count && local->dir_count) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "path %s exists as a file on one subvolume "
+ "and directory on another. "
+ "Please fix it manually",
+ local->loc.path);
+ op_errno = EIO;
+ goto out;
+ }
+
+ if (local->cached_subvol) {
+ ret = dht_layout_preset (this, local->cached_subvol,
+ local->inode);
+ if (ret < 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "failed to set layout for subvolume %s",
+ local->cached_subvol ? local->cached_subvol->name : "<nil>");
+ op_errno = EINVAL;
+ goto out;
+ }
+ } else {
+ ret = dht_layout_normalize (this, &local->loc, layout);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "normalizing failed on %s",
+ local->loc.path);
+ op_errno = EINVAL;
+ goto out;
+ }
+
+ dht_layout_set (this, local->inode, layout);
+ }
+
+ DHT_STACK_UNWIND (lookup, main_frame, local->op_ret, local->op_errno,
+ local->inode, &local->stbuf, local->xattr,
+ &local->postparent);
+ return 0;
+out:
+ DHT_STACK_UNWIND (lookup, main_frame, -1, op_errno, NULL, NULL, NULL,
+ NULL);
+
+ return ret;
+}
+
+
+int
+dht_discover_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno,
+ inode_t *inode, struct iatt *stbuf, dict_t *xattr,
+ struct iatt *postparent)
+{
+ dht_local_t *local = NULL;
+ int this_call_cnt = 0;
+ call_frame_t *prev = NULL;
+ dht_layout_t *layout = NULL;
+ int ret = -1;
+ int is_dir = 0;
+ int is_linkfile = 0;
+ int attempt_unwind = 0;
+
+ GF_VALIDATE_OR_GOTO ("dht", frame, out);
+ GF_VALIDATE_OR_GOTO ("dht", this, out);
+ GF_VALIDATE_OR_GOTO ("dht", frame->local, out);
+ GF_VALIDATE_OR_GOTO ("dht", this->private, out);
+ GF_VALIDATE_OR_GOTO ("dht", cookie, out);
+
+ local = frame->local;
+ prev = cookie;
+
+ layout = local->layout;
+
+ /* Check if the gfid is different for file from other node */
+ if (!op_ret && uuid_compare (local->gfid, stbuf->ia_gfid)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: gfid different on %s",
+ local->loc.path, prev->this->name);
+ }
+
+
+ LOCK (&frame->lock);
+ {
+ /* TODO: assert equal mode on stbuf->st_mode and
+ local->stbuf->st_mode
+
+ else mkdir/chmod/chown and fix
+ */
+ ret = dht_layout_merge (this, layout, prev->this,
+ op_ret, op_errno, xattr);
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: failed to merge layouts", local->loc.path);
+
+ if (op_ret == -1) {
+ local->op_errno = op_errno;
+ gf_log (this->name, GF_LOG_DEBUG,
+ "lookup of %s on %s returned error (%s)",
+ local->loc.path, prev->this->name,
+ strerror (op_errno));
+
+ goto unlock;
+ }
+
+ is_linkfile = check_is_linkfile (inode, stbuf, xattr);
+ is_dir = check_is_dir (inode, stbuf, xattr);
+
+ if (is_dir) {
+ local->dir_count ++;
+ } else {
+ local->file_count ++;
+
+ if (!is_linkfile) {
+ /* real file */
+ local->cached_subvol = prev->this;
+ attempt_unwind = 1;
+ } else {
+ goto unlock;
+ }
+ }
+
+ local->op_ret = 0;
+
+ if (local->xattr == NULL) {
+ local->xattr = dict_ref (xattr);
+ } else {
+ dht_aggregate_xattr (local->xattr, xattr);
+ }
+
+ if (local->inode == NULL)
+ local->inode = inode_ref (inode);
+
+ dht_iatt_merge (this, &local->stbuf, stbuf, prev->this);
+ dht_iatt_merge (this, &local->postparent, postparent,
+ prev->this);
+ }
+unlock:
+ UNLOCK (&frame->lock);
+out:
+ this_call_cnt = dht_frame_return (frame);
+
+ if (is_last_call (this_call_cnt) || attempt_unwind) {
+ dht_discover_complete (this, frame);
+ }
+
+ if (is_last_call (this_call_cnt))
+ DHT_STACK_DESTROY (frame);
+
+ return 0;
+}
+
+
+int
+dht_discover (call_frame_t *frame, xlator_t *this, loc_t *loc)
+{
+ int ret;
+ dht_local_t *local = NULL;
+ dht_conf_t *conf = NULL;
+ int call_cnt = 0;
+ int op_errno = EINVAL;
+ int i = 0;
+ call_frame_t *discover_frame = NULL;
+
+
+ conf = this->private;
+ local = frame->local;
+
+ ret = dict_set_uint32 (local->xattr_req,
+ "trusted.glusterfs.dht", 4 * 4);
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: failed to set 'trusted.glusterfs.dht' key",
+ loc->path);
+
+ ret = dict_set_uint32 (local->xattr_req,
+ "trusted.glusterfs.dht.linkto", 256);
+ if (ret)
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: failed to set 'trusted.glusterfs.dht.linkto' key",
+ loc->path);
+
+ call_cnt = conf->subvolume_cnt;
+ local->call_cnt = call_cnt;
+
+ local->layout = dht_layout_new (this, conf->subvolume_cnt);
+
+ if (!local->layout) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ uuid_copy (local->gfid, loc->gfid);
+
+ discover_frame = copy_frame (frame);
+ if (!discover_frame) {
+ op_errno = ENOMEM;
+ goto err;
+ }
+
+ discover_frame->local = local;
+ frame->local = NULL;
+ local->main_frame = frame;
+
+ for (i = 0; i < call_cnt; i++) {
+ STACK_WIND (discover_frame, dht_discover_cbk,
+ conf->subvolumes[i],
+ conf->subvolumes[i]->fops->lookup,
+ &local->loc, local->xattr_req);
+ }
+
+ return 0;
+
+err:
+ DHT_STACK_UNWIND (lookup, frame, -1, op_errno, NULL, NULL, NULL, NULL);
+
+ return 0;
+}
+
+
+int
dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno,
inode_t *inode, struct iatt *stbuf, dict_t *xattr,
@@ -1086,6 +1326,12 @@ dht_lookup (call_frame_t *frame, xlator_t *this,
local->xattr_req = dict_new ();
}
+ if (uuid_is_null (loc->pargfid) && !uuid_is_null (loc->gfid) &&
+ !__is_root_gfid (loc->inode->gfid)) {
+ local->cached_subvol = NULL;
+ dht_discover (frame, this, loc);
+ return 0;
+ }
if (!hashed_subvol)
hashed_subvol = dht_subvol_get_hashed (this, loc);
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
index 01d11ee68..65c03b62f 100644
--- a/xlators/cluster/dht/src/dht-helper.c
+++ b/xlators/cluster/dht/src/dht-helper.c
@@ -89,7 +89,7 @@ dht_filter_loc_subvol_key (xlator_t *this, loc_t *loc, loc_t *new_loc,
int ret = 0; /* not found */
/* Why do other tasks if first required 'char' itself is not there */
- if (loc->name && !strchr (loc->name, '@'))
+ if (!loc->name || !strchr (loc->name, '@'))
goto out;
trav = this->children;
diff --git a/xlators/cluster/dht/src/dht-selfheal.c b/xlators/cluster/dht/src/dht-selfheal.c
index 3342c35a9..b87e0ab48 100644
--- a/xlators/cluster/dht/src/dht-selfheal.c
+++ b/xlators/cluster/dht/src/dht-selfheal.c
@@ -136,8 +136,10 @@ dht_selfheal_dir_xattr_persubvol (call_frame_t *frame, loc_t *loc,
int ret = 0;
xlator_t *this = NULL;
int32_t *disk_layout = NULL;
+ dht_local_t *local = NULL;
+ local = frame->local;
subvol = layout->list[i].xlator;
this = frame->this;
@@ -171,6 +173,9 @@ dht_selfheal_dir_xattr_persubvol (call_frame_t *frame, loc_t *loc,
dict_ref (xattr);
+ if (!uuid_is_null (local->gfid))
+ uuid_copy (loc->gfid, local->gfid);
+
STACK_WIND (frame, dht_selfheal_dir_xattr_cbk,
subvol, subvol->fops->setxattr,
loc, xattr, 0);
@@ -306,6 +311,9 @@ dht_selfheal_dir_setattr (call_frame_t *frame, loc_t *loc, struct iatt *stbuf,
return 0;
}
+ if (!uuid_is_null (local->gfid))
+ uuid_copy (loc->gfid, local->gfid);
+
local->call_cnt = missing_attr;
for (i = 0; i < layout->cnt; i++) {
if (layout->list[i].err == -1) {
diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c
index a40755149..93b1518cb 100644
--- a/xlators/features/marker/src/marker.c
+++ b/xlators/features/marker/src/marker.c
@@ -65,6 +65,7 @@ marker_loc_fill (loc_t *loc, inode_t *inode, inode_t *parent, char *path)
if (inode) {
loc->inode = inode_ref (inode);
+ uuid_copy (loc->gfid, loc->inode->gfid);
}
if (parent)
@@ -94,34 +95,25 @@ int
marker_inode_loc_fill (inode_t *inode, loc_t *loc)
{
char *resolvedpath = NULL;
- inode_t *parent = NULL;
int ret = -1;
+ inode_t *parent = NULL;
if ((!inode) || (!loc))
return ret;
- if ((inode) && __is_root_gfid (inode->gfid)) {
- loc->parent = NULL;
- goto ignore_parent;
- }
+ parent = inode_parent (inode, NULL, NULL);
- parent = inode_parent (inode, 0, NULL);
- if (!parent) {
- goto err;
- }
-
-ignore_parent:
ret = inode_path (inode, NULL, &resolvedpath);
if (ret < 0)
goto err;
- ret = marker_loc_fill (loc, inode, parent, resolvedpath);
+ ret = marker_loc_fill (loc, inode, NULL, resolvedpath);
if (ret < 0)
goto err;
err:
- if (parent)
- inode_unref (parent);
+ if (parent)
+ inode_unref (parent);
if (resolvedpath)
GF_FREE (resolvedpath);
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 8c1cd8f75..b8f53a1bc 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -3378,6 +3378,7 @@ fuse_first_lookup (xlator_t *this)
loc.path = "/";
loc.name = "";
loc.inode = fuse_ino_to_inode (1, this);
+ uuid_copy (loc.gfid, loc.inode->gfid);
loc.parent = NULL;
dict = dict_new ();
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
index 39b54f6fe..ae764a7bc 100644
--- a/xlators/mount/fuse/src/fuse-bridge.h
+++ b/xlators/mount/fuse/src/fuse-bridge.h
@@ -148,7 +148,9 @@ typedef struct fuse_private fuse_private_t;
state->finh->unique, \
state->finh->opcode); \
free_fuse_state (state); \
- return; \
+ /* ideally, need to 'return', but let the */ \
+ /* calling function take care of it */ \
+ break; \
} \
\
frame->root->state = state; \
@@ -165,6 +167,7 @@ typedef struct fuse_private fuse_private_t;
} else { \
STACK_WIND (frame, ret, xl, xl->fops->fop, args); \
} \
+ \
} while (0)
@@ -242,7 +245,7 @@ typedef struct {
char *resolved;
int op_ret;
int op_errno;
- loc_t deep_loc;
+ loc_t resolve_loc;
struct fuse_resolve_comp *components;
int comp_count;
} fuse_resolve_t;
diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c
index 941907cea..9bf85f979 100644
--- a/xlators/mount/fuse/src/fuse-helpers.c
+++ b/xlators/mount/fuse/src/fuse-helpers.c
@@ -68,7 +68,7 @@ fuse_resolve_wipe (fuse_resolve_t *resolve)
if (resolve->resolved)
GF_FREE ((void *)resolve->resolved);
- loc_wipe (&resolve->deep_loc);
+ loc_wipe (&resolve->resolve_loc);
comp = resolve->components;
@@ -321,6 +321,8 @@ fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
if (!parent) {
parent = fuse_ino_to_inode (par, state->this);
loc->parent = parent;
+ if (parent)
+ uuid_copy (loc->pargfid, parent->gfid);
}
inode = loc->inode;
@@ -342,16 +344,17 @@ fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino,
if (!inode) {
inode = fuse_ino_to_inode (ino, state->this);
loc->inode = inode;
+ if (inode)
+ uuid_copy (loc->gfid, inode->gfid);
}
parent = loc->parent;
if (!parent) {
- parent = fuse_ino_to_inode (par, state->this);
- if (!parent) {
- parent = inode_parent (inode, null_gfid, NULL);
- }
-
+ parent = inode_parent (inode, null_gfid, NULL);
loc->parent = parent;
+ if (parent)
+ uuid_copy (loc->pargfid, parent->gfid);
+
}
ret = inode_path (inode, NULL, &path);
diff --git a/xlators/mount/fuse/src/fuse-resolve.c b/xlators/mount/fuse/src/fuse-resolve.c
index 33606f879..755e2f429 100644
--- a/xlators/mount/fuse/src/fuse-resolve.c
+++ b/xlators/mount/fuse/src/fuse-resolve.c
@@ -26,375 +26,203 @@
static int
fuse_resolve_all (fuse_state_t *state);
-static int
-fuse_resolve_path_simple (fuse_state_t *state);
-
-static int
-component_count (const char *path)
-{
- int count = 0;
- const char *trav = NULL;
-
- for (trav = path; *trav; trav++) {
- if (*trav == '/')
- count++;
- }
-
- return count + 2;
-}
-
-static int
-prepare_components (fuse_state_t *state)
-{
- fuse_resolve_t *resolve = NULL;
- char *resolved = NULL;
- struct fuse_resolve_comp *components = NULL;
- char *trav = NULL;
- int count = 0;
- int i = 0;
-
- resolve = state->resolve_now;
-
- resolved = gf_strdup (resolve->path);
- resolve->resolved = resolved;
-
- count = component_count (resolve->path);
- components = GF_CALLOC (sizeof (*components), count, 0); //TODO
- if (!components)
- goto out;
- resolve->components = components;
-
- components[0].basename = "";
- components[0].ino = 1;
- components[0].gen = 0;
- components[0].inode = inode_ref (state->itable->root);
-
- i = 1;
- for (trav = resolved; *trav; trav++) {
- if (*trav == '/') {
- components[i].basename = trav + 1;
- *trav = 0;
- i++;
- }
- }
-out:
- return 0;
-}
+int fuse_resolve_continue (fuse_state_t *state);
+int fuse_resolve_entry_simple (fuse_state_t *state);
+int fuse_resolve_inode_simple (fuse_state_t *state);
static int
fuse_resolve_loc_touchup (fuse_state_t *state)
{
fuse_resolve_t *resolve = NULL;
- loc_t *loc = NULL;
- char *path = NULL;
- int ret = 0;
+ loc_t *loc = NULL;
+ char *path = NULL;
+ int ret = 0;
resolve = state->resolve_now;
loc = state->loc_now;
if (!loc->path) {
- if (loc->parent) {
+ if (loc->parent && resolve->bname) {
ret = inode_path (loc->parent, resolve->bname, &path);
} else if (loc->inode) {
ret = inode_path (loc->inode, NULL, &path);
}
if (ret)
- gf_log ("", GF_LOG_TRACE,
+ gf_log (THIS->name, GF_LOG_TRACE,
"return value inode_path %d", ret);
-
- if (!path)
- path = gf_strdup (resolve->path);
-
loc->path = path;
}
- loc->name = strrchr (loc->path, '/');
- if (loc->name)
- loc->name++;
-
- if (!loc->parent && loc->inode) {
- loc->parent = inode_parent (loc->inode, 0, NULL);
- }
-
return 0;
}
-static int
-fuse_resolve_newfd_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
- int32_t op_ret, int32_t op_errno, fd_t *fd)
+
+int
+fuse_resolve_gfid_entry_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)
{
fuse_state_t *state = NULL;
fuse_resolve_t *resolve = NULL;
- fd_t *old_fd = NULL;
- fd_t *tmp_fd = NULL;
- fuse_fd_ctx_t *tmp_fd_ctx = 0;
- uint64_t val = 0;
- int ret = 0;
+ inode_t *link_inode = NULL;
+ loc_t *resolve_loc = NULL;
state = frame->root->state;
resolve = state->resolve_now;
+ resolve_loc = &resolve->resolve_loc;
STACK_DESTROY (frame->root);
if (op_ret == -1) {
- resolve->op_ret = -1;
- resolve->op_errno = op_errno;
+ gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :
+ GF_LOG_WARNING),
+ "%s/%s: failed to resolve (%s)",
+ uuid_utoa (resolve_loc->pargfid), resolve_loc->name,
+ strerror (op_errno));
goto out;
}
- old_fd = resolve->fd;
-
- state->fd = fd_ref (fd);
-
- fd_bind (fd);
+ link_inode = inode_link (inode, resolve_loc->parent,
+ resolve_loc->name, buf);
- resolve->fd = NULL;
+ if (!link_inode)
+ goto out;
- LOCK (&old_fd->lock);
- {
- ret = __fd_ctx_get (old_fd, state->this, &val);
- if (!ret) {
- tmp_fd_ctx = (fuse_fd_ctx_t *)(unsigned long)val;
- tmp_fd = tmp_fd_ctx->fd;
- if (tmp_fd) {
- fd_unref (tmp_fd);
- tmp_fd_ctx->fd = NULL;
- }
- } else {
- tmp_fd_ctx = __fuse_fd_ctx_check_n_create (old_fd,
- state->this);
- }
+ inode_lookup (link_inode);
- if (tmp_fd_ctx) {
- tmp_fd_ctx->fd = fd;
- } else {
- gf_log ("resolve", GF_LOG_WARNING,
- "failed to set the fd ctx with resolved fd");
- }
- }
- UNLOCK (&old_fd->lock);
+ inode_unref (link_inode);
out:
- fuse_resolve_all (state);
- return 0;
-}
-
-static void
-fuse_resolve_new_fd (fuse_state_t *state)
-{
- fuse_resolve_t *resolve = NULL;
- fd_t *new_fd = NULL;
- fd_t *fd = NULL;
-
- resolve = state->resolve_now;
- fd = resolve->fd;
-
- new_fd = fd_create (state->loc.inode, state->finh->pid);
- new_fd->flags = (fd->flags & ~O_TRUNC);
-
- gf_log ("resolve", GF_LOG_DEBUG,
- "%"PRIu64": OPEN %s", state->finh->unique,
- state->loc.path);
-
- FUSE_FOP (state, fuse_resolve_newfd_cbk, GF_FOP_OPEN,
- open, &state->loc, new_fd->flags, new_fd, 0);
-}
-
-static int
-fuse_resolve_deep_continue (fuse_state_t *state)
-{
- fuse_resolve_t *resolve = NULL;
- int ret = 0;
-
- resolve = state->resolve_now;
-
- resolve->op_ret = 0;
- resolve->op_errno = 0;
-
- if (resolve->path)
- ret = fuse_resolve_path_simple (state);
- if (ret)
- gf_log ("resolve", GF_LOG_TRACE,
- "return value of resolve_*_simple %d", ret);
-
- fuse_resolve_loc_touchup (state);
-
- /* This function is called by either fd resolve or inode resolve */
- if (!resolve->fd)
- fuse_resolve_all (state);
- else
- fuse_resolve_new_fd (state);
+ loc_wipe (resolve_loc);
+ fuse_resolve_continue (state);
return 0;
}
-static int
-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)
+int
+fuse_resolve_gfid_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)
{
- fuse_state_t *state = NULL;
- fuse_resolve_t *resolve = NULL;
- struct fuse_resolve_comp *components = NULL;
- inode_t *link_inode = NULL;
- int i = 0;
+ fuse_state_t *state = NULL;
+ fuse_resolve_t *resolve = NULL;
+ inode_t *link_inode = NULL;
+ loc_t *resolve_loc = NULL;
state = frame->root->state;
resolve = state->resolve_now;
- components = resolve->components;
-
- i = (long) cookie;
+ resolve_loc = &resolve->resolve_loc;
STACK_DESTROY (frame->root);
if (op_ret == -1) {
- goto get_out_of_here;
+ gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :
+ GF_LOG_WARNING),
+ "%s: failed to resolve (%s)",
+ uuid_utoa (resolve_loc->gfid), strerror (op_errno));
+ loc_wipe (&resolve->resolve_loc);
+ goto out;
}
- if (i != 0) {
- /* no linking for root inode */
- link_inode = inode_link (inode, resolve->deep_loc.parent,
- resolve->deep_loc.name, buf);
- components[i].inode = link_inode;
- link_inode = NULL;
- }
+ loc_wipe (resolve_loc);
- loc_wipe (&resolve->deep_loc);
- i++; /* next component */
+ link_inode = inode_link (inode, NULL, NULL, buf);
- if (!components[i].basename) {
- /* all components of the path are resolved */
- goto get_out_of_here;
+ if (!link_inode)
+ goto out;
+
+ inode_lookup (link_inode);
+
+ if (uuid_is_null (resolve->pargfid)) {
+ inode_unref (link_inode);
+ goto out;
}
- /* join the current component with the path resolved until now */
- *(components[i].basename - 1) = '/';
+ resolve_loc->parent = link_inode;
+ uuid_copy (resolve_loc->pargfid, resolve_loc->parent->gfid);
- resolve->deep_loc.path = gf_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;
+ resolve_loc->name = resolve->bname;
- FUSE_FOP_COOKIE (state, state->itable->xl, fuse_resolve_deep_cbk,
- (void *)(long)i,
- GF_FOP_LOOKUP, lookup, &resolve->deep_loc, NULL);
- return 0;
+ resolve_loc->inode = inode_new (state->itable);
+ inode_path (resolve_loc->parent, resolve_loc->name,
+ (char **) &resolve_loc->path);
+
+ FUSE_FOP (state, fuse_resolve_gfid_entry_cbk, GF_FOP_LOOKUP,
+ lookup, &resolve->resolve_loc, NULL);
-get_out_of_here:
- fuse_resolve_deep_continue (state);
+ return 0;
+out:
+ fuse_resolve_continue (state);
return 0;
}
-static int
-fuse_resolve_path_deep (fuse_state_t *state)
+int
+fuse_resolve_gfid (fuse_state_t *state)
{
- fuse_resolve_t *resolve = NULL;
- struct fuse_resolve_comp *components = NULL;
- inode_t *inode = NULL;
- long i = 0;
+ fuse_resolve_t *resolve = NULL;
+ loc_t *resolve_loc = NULL;
+ int ret = 0;
resolve = state->resolve_now;
+ resolve_loc = &resolve->resolve_loc;
- prepare_components (state);
-
- components = resolve->components;
-
- /* start from the root */
- for (i = 1; components[i].basename; i++) {
- *(components[i].basename - 1) = '/';
- inode = inode_grep (state->itable, components[i-1].inode,
- components[i].basename);
- if (!inode)
- break;
- components[i].inode = inode;
+ if (!uuid_is_null (resolve->pargfid)) {
+ uuid_copy (resolve_loc->gfid, resolve->pargfid);
+ resolve_loc->inode = inode_new (state->itable);
+ ret = inode_path (resolve_loc->inode, NULL,
+ (char **)&resolve_loc->path);
+ } else if (!uuid_is_null (resolve->gfid)) {
+ uuid_copy (resolve_loc->gfid, resolve->gfid);
+ resolve_loc->inode = inode_new (state->itable);
+ ret = inode_path (resolve_loc->inode, NULL,
+ (char **)&resolve_loc->path);
+ }
+ if (ret <= 0) {
+ gf_log (THIS->name, GF_LOG_WARNING,
+ "failed to get the path from inode %s",
+ uuid_utoa (resolve->gfid));
}
- if (!components[i].basename)
- goto resolved;
-
- resolve->deep_loc.path = gf_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;
-
- FUSE_FOP_COOKIE (state, state->itable->xl, fuse_resolve_deep_cbk,
- (void *)(long)i,
- GF_FOP_LOOKUP, lookup, &resolve->deep_loc, NULL);
+ FUSE_FOP (state, fuse_resolve_gfid_cbk, GF_FOP_LOOKUP,
+ lookup, &resolve->resolve_loc, NULL);
return 0;
-resolved:
- fuse_resolve_deep_continue (state);
- return 0;
}
-static int
-fuse_resolve_path_simple (fuse_state_t *state)
+int
+fuse_resolve_continue (fuse_state_t *state)
{
- fuse_resolve_t *resolve = NULL;
- struct fuse_resolve_comp *components = NULL;
- int ret = -1;
- int par_idx = 0;
- int ino_idx = 0;
- int i = 0;
+ fuse_resolve_t *resolve = NULL;
+ int ret = 0;
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->type == RESOLVE_EXACT)) {
- 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) {
- if (state->loc_now->inode) {
- inode_unref (state->loc_now->inode);
- }
-
- state->loc_now->inode = inode_ref (components[ino_idx].inode);
- }
+ resolve->op_ret = 0;
+ resolve->op_errno = 0;
- if (state->loc_now->parent) {
- inode_unref (state->loc_now->parent);
- }
+ /* TODO: should we handle 'fd' here ? */
+ if (!uuid_is_null (resolve->pargfid))
+ ret = fuse_resolve_entry_simple (state);
+ else if (!uuid_is_null (resolve->gfid))
+ ret = fuse_resolve_inode_simple (state);
+ if (ret)
+ gf_log (THIS->name, GF_LOG_DEBUG,
+ "return value of resolve_*_simple %d", ret);
- state->loc_now->parent = inode_ref (components[par_idx].inode);
+ fuse_resolve_loc_touchup (state);
- ret = 0;
+ fuse_resolve_all (state);
-out:
- return ret;
+ return 0;
}
+
/*
Check if the requirements are fulfilled by entries in the inode cache itself
Return value:
@@ -445,6 +273,7 @@ fuse_resolve_entry_simple (fuse_state_t *state)
}
state->loc_now->inode = inode_ref (inode);
+ uuid_copy (state->loc_now->gfid, resolve->gfid);
out:
if (parent)
@@ -468,7 +297,7 @@ fuse_resolve_entry (fuse_state_t *state)
ret = fuse_resolve_entry_simple (state);
if (ret > 0) {
loc_wipe (loc);
- fuse_resolve_path_deep (state);
+ fuse_resolve_gfid (state);
return 0;
}
@@ -505,6 +334,7 @@ fuse_resolve_inode_simple (fuse_state_t *state)
}
state->loc_now->inode = inode_ref (inode);
+ uuid_copy (state->loc_now->gfid, resolve->gfid);
out:
if (inode)
@@ -526,7 +356,7 @@ fuse_resolve_inode (fuse_state_t *state)
if (ret > 0) {
loc_wipe (loc);
- fuse_resolve_path_deep (state);
+ fuse_resolve_gfid (state);
return 0;
}
@@ -574,8 +404,6 @@ fuse_resolve_fd (fuse_state_t *state)
state->loc_now = &state->loc;
- fuse_resolve_path_deep (state);
-
out:
return 0;
}
@@ -600,10 +428,6 @@ fuse_resolve (fuse_state_t *state)
fuse_resolve_inode (state);
- } else if (resolve->path) {
-
- fuse_resolve_path_deep (state);
-
} else {
resolve->op_ret = 0;
diff --git a/xlators/performance/quick-read/src/quick-read.c b/xlators/performance/quick-read/src/quick-read.c
index 7db1e686f..6c9a0f0e5 100644
--- a/xlators/performance/quick-read/src/quick-read.c
+++ b/xlators/performance/quick-read/src/quick-read.c
@@ -82,47 +82,25 @@ static int32_t
qr_loc_fill (loc_t *loc, inode_t *inode, char *path)
{
int32_t ret = -1;
- char *parent = NULL;
- char *path_copy = NULL;
GF_VALIDATE_OR_GOTO_WITH_ERROR ("quick-read", loc, out, errno, EINVAL);
GF_VALIDATE_OR_GOTO_WITH_ERROR ("quick-read", inode, out, errno,
EINVAL);
GF_VALIDATE_OR_GOTO_WITH_ERROR ("quick-read", path, out, errno, EINVAL);
- GF_VALIDATE_OR_GOTO_WITH_ERROR ("quick-read", inode->table, out, errno,
- EINVAL);
loc->inode = inode_ref (inode);
- loc->path = gf_strdup (path);
-
- path_copy = gf_strdup (path);
- if (path_copy == NULL) {
- ret = -1;
- goto out;
- }
+ uuid_copy (loc->gfid, inode->gfid);
- parent = dirname (path_copy);
-
- loc->parent = inode_from_path (inode->table, parent);
- if (loc->parent == NULL) {
- ret = -1;
- errno = EINVAL;
- gf_log ("quick-read", GF_LOG_WARNING,
- "cannot search parent inode for path (%s)", path);
+ loc->path = gf_strdup (path);
+ if (!loc->path)
goto out;
- }
- loc->name = strrchr (loc->path, '/');
ret = 0;
out:
if (ret == -1) {
qr_loc_wipe (loc);
}
- if (path_copy) {
- GF_FREE (path_copy);
- }
-
return ret;
}
diff --git a/xlators/performance/read-ahead/src/read-ahead.c b/xlators/performance/read-ahead/src/read-ahead.c
index 6d7641e69..37f34f2eb 100644
--- a/xlators/performance/read-ahead/src/read-ahead.c
+++ b/xlators/performance/read-ahead/src/read-ahead.c
@@ -489,12 +489,8 @@ ra_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
fd_ctx_get (fd, this, &tmp_file);
file = (ra_file_t *)(long)tmp_file;
- if (file == NULL) {
- op_errno = EBADF;
- gf_log (this->name, GF_LOG_WARNING,
- "readv received on fd (%p) with no"
- " file set in its context", fd);
- goto unwind;
+ if (!file || file->disabled) {
+ goto disabled;
}
if (file->offset != offset) {
@@ -520,14 +516,6 @@ ra_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
flush_region (frame, file, 0, file->pages.prev->offset + 1);
}
- if (file->disabled) {
- STACK_WIND (frame, ra_readv_disabled_cbk,
- FIRST_CHILD (frame->this),
- FIRST_CHILD (frame->this)->fops->readv,
- file->fd, size, offset);
- return 0;
- }
-
local = (void *) GF_CALLOC (1, sizeof (*local), gf_ra_mt_ra_local_t);
if (!local) {
op_errno = ENOMEM;
@@ -562,6 +550,13 @@ unwind:
STACK_UNWIND_STRICT (readv, frame, -1, op_errno, NULL, 0, NULL, NULL);
return 0;
+
+disabled:
+ STACK_WIND (frame, ra_readv_disabled_cbk,
+ FIRST_CHILD (frame->this),
+ FIRST_CHILD (frame->this)->fops->readv,
+ fd, size, offset);
+ return 0;
}
@@ -600,16 +595,10 @@ ra_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
fd_ctx_get (fd, this, &tmp_file);
file = (ra_file_t *)(long)tmp_file;
- if (file == NULL) {
- op_errno = EBADF;
- gf_log (this->name, GF_LOG_WARNING,
- "flush received on fd (%p) with no"
- " file set in its context", fd);
- goto unwind;
+ if (file) {
+ flush_region (frame, file, 0, file->pages.prev->offset+1);
}
- flush_region (frame, file, 0, file->pages.prev->offset+1);
-
STACK_WIND (frame, ra_flush_cbk, FIRST_CHILD (this),
FIRST_CHILD (this)->fops->flush, fd);
return 0;
@@ -634,16 +623,10 @@ ra_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync)
fd_ctx_get (fd, this, &tmp_file);
file = (ra_file_t *)(long)tmp_file;
- if (file == NULL) {
- op_errno = EBADF;
- gf_log (this->name, GF_LOG_WARNING,
- "fsync received on fd (%p) with no"
- " file set in its context", fd);
- goto unwind;
+ if (file) {
+ flush_region (frame, file, 0, file->pages.prev->offset+1);
}
- flush_region (frame, file, 0, file->pages.prev->offset+1);
-
STACK_WIND (frame, ra_fsync_cbk, FIRST_CHILD (this),
FIRST_CHILD (this)->fops->fsync, fd, datasync);
return 0;
@@ -659,28 +642,16 @@ ra_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
struct iatt *postbuf)
{
- fd_t *fd = NULL;
ra_file_t *file = NULL;
- uint64_t tmp_file = 0;
GF_ASSERT (frame);
- fd = frame->local;
-
- fd_ctx_get (fd, this, &tmp_file);
- file = (ra_file_t *)(long)tmp_file;
+ file = frame->local;
- if (file == NULL) {
- gf_log (this->name, GF_LOG_WARNING,
- "no read-ahead context set in fd (%p)", fd);
- op_errno = EBADF;
- op_ret = -1;
- goto out;
+ if (file) {
+ flush_region (frame, file, 0, file->pages.prev->offset+1);
}
- flush_region (frame, file, 0, file->pages.prev->offset+1);
-
-out:
frame->local = NULL;
STACK_UNWIND_STRICT (writev, frame, op_ret, op_errno, prebuf, postbuf);
return 0;
@@ -701,20 +672,13 @@ ra_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
fd_ctx_get (fd, this, &tmp_file);
file = (ra_file_t *)(long)tmp_file;
- if (file == NULL) {
- op_errno = EBADF;
- gf_log (this->name, GF_LOG_WARNING, "writev received on fd with"
- "no file set in its context");
- goto unwind;
+ if (file) {
+ flush_region (frame, file, 0, file->pages.prev->offset+1);
+ frame->local = file;
+ /* reset the read-ahead counters too */
+ file->expected = file->page_count = 0;
}
- flush_region (frame, file, 0, file->pages.prev->offset+1);
-
- /* reset the read-ahead counters too */
- file->expected = file->page_count = 0;
-
- frame->local = fd;
-
STACK_WIND (frame, ra_writev_cbk,
FIRST_CHILD(this),
FIRST_CHILD(this)->fops->writev,
diff --git a/xlators/performance/stat-prefetch/src/stat-prefetch.c b/xlators/performance/stat-prefetch/src/stat-prefetch.c
index 563da9e72..73cc3a955 100644
--- a/xlators/performance/stat-prefetch/src/stat-prefetch.c
+++ b/xlators/performance/stat-prefetch/src/stat-prefetch.c
@@ -19,6 +19,7 @@
#include "stat-prefetch.h"
#include "statedump.h"
+#include "fd.h"
#define GF_SP_CACHE_BUCKETS 1
#define GF_SP_CACHE_ENTRIES_EXPECTED (128 * 1024) //1048576
@@ -667,9 +668,6 @@ out:
}
-fd_t *
-_fd_ref (fd_t *fd);
-
void
sp_remove_caches_from_all_fds_opened (xlator_t *this, inode_t *inode,
char *name)
@@ -705,7 +703,7 @@ sp_remove_caches_from_all_fds_opened (xlator_t *this, inode_t *inode,
INIT_LIST_HEAD (&wrapper->list);
- wrapper->fd = _fd_ref (fd);
+ wrapper->fd = __fd_ref (fd);
list_add_tail (&wrapper->list, &head);
}
}
diff --git a/xlators/performance/write-behind/src/write-behind.c b/xlators/performance/write-behind/src/write-behind.c
index 1555a79a7..52e038720 100644
--- a/xlators/performance/write-behind/src/write-behind.c
+++ b/xlators/performance/write-behind/src/write-behind.c
@@ -832,17 +832,20 @@ wb_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
GF_VALIDATE_OR_GOTO (frame->this->name, fd, unwind);
+
if ((!IA_ISDIR (fd->inode->ia_type))
&& fd_ctx_get (fd, this, &tmp_file)) {
- gf_log (this->name, GF_LOG_WARNING,
- "write behind file pointer is"
- " not stored in context of fd(%p), returning EBADFD",
- fd);
- op_errno = EBADFD;
- goto unwind;
+ file = wb_file_create (this, fd, 0);
+ } else {
+ file = (wb_file_t *)(long)tmp_file;
+ if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "wb_file not found for fd %p", fd);
+ op_errno = EBADFD;
+ goto unwind;
+ }
}
- file = (wb_file_t *)(long)tmp_file;
local = GF_CALLOC (1, sizeof (*local),
gf_wb_mt_wb_local_t);
if (local == NULL) {
@@ -1115,18 +1118,20 @@ wb_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
GF_VALIDATE_OR_GOTO (frame->this->name, this, unwind);
GF_VALIDATE_OR_GOTO (frame->this->name, fd, unwind);
+
if ((!IA_ISDIR (fd->inode->ia_type))
&& fd_ctx_get (fd, this, &tmp_file)) {
- gf_log (this->name, GF_LOG_WARNING,
- "write behind file pointer is"
- " not stored in context of fd(%p), returning EBADFD",
- fd);
- op_errno = EBADFD;
- goto unwind;
+ file = wb_file_create (this, fd, 0);
+ } else {
+ file = (wb_file_t *)(long)tmp_file;
+ if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "wb_file not found for fd %p", fd);
+ op_errno = EBADFD;
+ goto unwind;
+ }
}
- file = (wb_file_t *)(long)tmp_file;
-
local = GF_CALLOC (1, sizeof (*local), gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
@@ -2091,21 +2096,15 @@ wb_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, struct iovec *vector,
if ((!IA_ISDIR (fd->inode->ia_type))
&& fd_ctx_get (fd, this, &tmp_file)) {
- gf_log (this->name, GF_LOG_WARNING,
- "write behind file pointer is"
- " not stored in context of fd(%p), returning EBADFD",
- fd);
-
- op_errno = EBADFD;
- goto unwind;
- }
-
- file = (wb_file_t *)(long)tmp_file;
- if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
- gf_log (this->name, GF_LOG_WARNING,
- "wb_file not found for fd %p", fd);
- op_errno = EBADFD;
- goto unwind;
+ file = wb_file_create (this, fd, 0);
+ } else {
+ file = (wb_file_t *)(long)tmp_file;
+ if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "wb_file not found for fd %p", fd);
+ op_errno = EBADFD;
+ goto unwind;
+ }
}
if (file != NULL) {
@@ -2265,16 +2264,17 @@ wb_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
if ((!IA_ISDIR (fd->inode->ia_type))
&& fd_ctx_get (fd, this, &tmp_file)) {
- gf_log (this->name, GF_LOG_WARNING,
- "write behind file pointer is"
- " not stored in context of fd(%p), returning EBADFD",
- fd);
- op_errno = EBADFD;
- goto unwind;
+ file = wb_file_create (this, fd, 0);
+ } else {
+ file = (wb_file_t *)(long)tmp_file;
+ if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "wb_file not found for fd %p", fd);
+ op_errno = EBADFD;
+ goto unwind;
+ }
}
- file = (wb_file_t *)(long)tmp_file;
-
local = GF_CALLOC (1, sizeof (*local), gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
@@ -2449,19 +2449,20 @@ wb_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
conf = this->private;
+
if ((!IA_ISDIR (fd->inode->ia_type))
&& fd_ctx_get (fd, this, &tmp_file)) {
- gf_log (this->name, GF_LOG_WARNING,
- "write behind file pointer is"
- " not stored in context of fd(%p), returning EBADFD",
- fd);
-
- op_errno = EBADFD;
- goto unwind;
+ file = wb_file_create (this, fd, 0);
+ } else {
+ file = (wb_file_t *)(long)tmp_file;
+ if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "wb_file not found for fd %p", fd);
+ op_errno = EBADFD;
+ goto unwind;
+ }
}
- file = (wb_file_t *)(long)tmp_file;
-
if (file != NULL) {
local = GF_CALLOC (1, sizeof (*local), gf_wb_mt_wb_local_t);
if (local == NULL) {
@@ -2593,18 +2594,20 @@ wb_fsync (call_frame_t *frame, xlator_t *this, fd_t *fd, int32_t datasync)
GF_VALIDATE_OR_GOTO_WITH_ERROR (frame->this->name, fd, unwind,
op_errno, EINVAL);
+
if ((!IA_ISDIR (fd->inode->ia_type))
&& fd_ctx_get (fd, this, &tmp_file)) {
- gf_log (this->name, GF_LOG_WARNING,
- "write behind file pointer is"
- " not stored in context of fd(%p), returning EBADFD",
- fd);
- op_errno = EBADFD;
- goto unwind;
+ file = wb_file_create (this, fd, 0);
+ } else {
+ file = (wb_file_t *)(long)tmp_file;
+ if ((!IA_ISDIR (fd->inode->ia_type)) && (file == NULL)) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "wb_file not found for fd %p", fd);
+ op_errno = EBADFD;
+ goto unwind;
+ }
}
- file = (wb_file_t *)(long)tmp_file;
-
local = GF_CALLOC (1, sizeof (*local), gf_wb_mt_wb_local_t);
if (local == NULL) {
op_errno = ENOMEM;
diff --git a/xlators/protocol/client/src/client.h b/xlators/protocol/client/src/client.h
index 459ceed70..69830db9d 100644
--- a/xlators/protocol/client/src/client.h
+++ b/xlators/protocol/client/src/client.h
@@ -35,28 +35,18 @@
#define CLIENT_CMD_DISCONNECT "trusted.glusterfs.client-disconnect"
#define CLIENT_DUMP_LOCKS "trusted.glusterfs.clientlk-dump"
-#define CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, label) \
+#define CLIENT_GET_REMOTE_FD(conf, fd, remote_fd, label) \
do { \
+ clnt_fd_ctx_t *fdctx = NULL; \
pthread_mutex_lock (&conf->lock); \
{ \
- fdctx = this_fd_get_ctx (args->fd, this); \
+ fdctx = this_fd_get_ctx (fd, THIS); \
} \
pthread_mutex_unlock (&conf->lock); \
- \
- if (fdctx == NULL) { \
- gf_log (this->name, GF_LOG_WARNING, \
- "(%s): failed to get fd ctx. EBADFD", \
- uuid_utoa (args->fd->inode->gfid)); \
- op_errno = EBADFD; \
- goto label; \
- } \
- \
- if (fdctx->remote_fd == -1) { \
- gf_log (this->name, GF_LOG_WARNING, \
- "(%s): failed to get fd ctx. EBADFD", \
- uuid_utoa (args->fd->inode->gfid)); \
- op_errno = EBADFD; \
- goto label; \
+ if (!fdctx) { \
+ remote_fd = -2; \
+ } else { \
+ remote_fd = fdctx->remote_fd; \
} \
} while (0);
diff --git a/xlators/protocol/client/src/client3_1-fops.c b/xlators/protocol/client/src/client3_1-fops.c
index 9b0fd63cc..6300b264f 100644
--- a/xlators/protocol/client/src/client3_1-fops.c
+++ b/xlators/protocol/client/src/client3_1-fops.c
@@ -2600,7 +2600,10 @@ client3_1_lookup (call_frame_t *frame, xlator_t *this,
}
req.path = (char *)args->loc->path;
- req.bname = (char *)args->loc->name;
+ if (args->loc->name)
+ req.bname = (char *)args->loc->name;
+ else
+ req.bname = "";
req.dict.dict_len = dict_len;
ret = client_submit_request (this, &req, frame, conf->fops,
@@ -2750,7 +2753,7 @@ client3_1_ftruncate (call_frame_t *frame, xlator_t *this,
void *data)
{
clnt_args_t *args = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
gfs3_ftruncate_req req = {{0,},};
int op_errno = EINVAL;
@@ -2763,10 +2766,11 @@ client3_1_ftruncate (call_frame_t *frame, xlator_t *this,
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
req.offset = args->offset;
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
ret = client_submit_request (this, &req, frame, conf->fops,
GFS3_OP_FTRUNCATE,
@@ -3510,7 +3514,7 @@ client3_1_readv (call_frame_t *frame, xlator_t *this,
void *data)
{
clnt_args_t *args = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
int op_errno = ESTALE;
gfs3_read_req req = {{0,},};
@@ -3526,11 +3530,12 @@ client3_1_readv (call_frame_t *frame, xlator_t *this,
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
req.size = args->size;
req.offset = args->offset;
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
/* TODO: what is the size we should send ? */
rsp_iobuf = iobuf_get (this->ctx->iobuf_pool);
@@ -3601,7 +3606,7 @@ int32_t
client3_1_writev (call_frame_t *frame, xlator_t *this, void *data)
{
clnt_args_t *args = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
gfs3_write_req req = {{0,},};
int op_errno = ESTALE;
@@ -3613,11 +3618,12 @@ client3_1_writev (call_frame_t *frame, xlator_t *this, void *data)
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
req.size = args->size;
req.offset = args->offset;
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
ret = client_submit_vec_request (this, &req, frame, conf->fops, GFS3_OP_WRITE,
client3_1_writev_cbk, args->vector,
@@ -3647,7 +3653,7 @@ client3_1_flush (call_frame_t *frame, xlator_t *this,
{
clnt_args_t *args = NULL;
gfs3_flush_req req = {{0,},};
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
clnt_local_t *local = NULL;
int op_errno = ESTALE;
@@ -3659,7 +3665,7 @@ client3_1_flush (call_frame_t *frame, xlator_t *this,
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
conf = this->private;
@@ -3674,7 +3680,8 @@ client3_1_flush (call_frame_t *frame, xlator_t *this,
local->owner = frame->root->lk_owner;
frame->local = local;
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
ret = client_submit_request (this, &req, frame, conf->fops,
GFS3_OP_FLUSH, client3_1_flush_cbk, NULL,
@@ -3699,7 +3706,7 @@ client3_1_fsync (call_frame_t *frame, xlator_t *this,
{
clnt_args_t *args = NULL;
gfs3_fsync_req req = {{0,},};
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
int op_errno = 0;
int ret = 0;
@@ -3710,10 +3717,11 @@ client3_1_fsync (call_frame_t *frame, xlator_t *this,
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
req.data = args->flags;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
ret = client_submit_request (this, &req, frame, conf->fops,
GFS3_OP_FSYNC, client3_1_fsync_cbk, NULL,
@@ -3738,7 +3746,7 @@ client3_1_fstat (call_frame_t *frame, xlator_t *this,
{
clnt_args_t *args = NULL;
gfs3_fstat_req req = {{0,},};
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
int op_errno = ESTALE;
int ret = 0;
@@ -3749,9 +3757,10 @@ client3_1_fstat (call_frame_t *frame, xlator_t *this,
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
ret = client_submit_request (this, &req, frame, conf->fops,
GFS3_OP_FSTAT, client3_1_fstat_cbk, NULL,
@@ -3834,7 +3843,7 @@ int32_t
client3_1_fsyncdir (call_frame_t *frame, xlator_t *this, void *data)
{
clnt_args_t *args = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
int op_errno = ESTALE;
gfs3_fsyncdir_req req = {{0,},};
@@ -3846,10 +3855,11 @@ client3_1_fsyncdir (call_frame_t *frame, xlator_t *this, void *data)
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
req.data = args->flags;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
conf = this->private;
@@ -3994,7 +4004,7 @@ client3_1_fsetxattr (call_frame_t *frame, xlator_t *this,
void *data)
{
clnt_args_t *args = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
gfs3_fsetxattr_req req = {{0,},};
int op_errno = ESTALE;
@@ -4007,11 +4017,11 @@ client3_1_fsetxattr (call_frame_t *frame, xlator_t *this,
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
req.flags = args->flags;
- memcpy (req.gfid, args->fd->inode->gfid, 16);
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
if (args->dict) {
ret = dict_allocate_and_serialize (args->dict,
@@ -4056,7 +4066,7 @@ client3_1_fgetxattr (call_frame_t *frame, xlator_t *this,
void *data)
{
clnt_args_t *args = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
gfs3_fgetxattr_req req = {{0,},};
int op_errno = ESTALE;
@@ -4074,7 +4084,7 @@ client3_1_fgetxattr (call_frame_t *frame, xlator_t *this,
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
local = GF_CALLOC (1, sizeof (*local),
gf_client_mt_clnt_local_t);
@@ -4108,12 +4118,13 @@ client3_1_fgetxattr (call_frame_t *frame, xlator_t *this,
rsp_iobref = NULL;
req.namelen = 1; /* Use it as a flag */
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
req.name = (char *)args->name;
if (!req.name) {
req.name = "";
req.namelen = 0;
}
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
ret = client_submit_request (this, &req, frame, conf->fops,
GFS3_OP_FGETXATTR,
@@ -4413,7 +4424,7 @@ client3_1_fxattrop (call_frame_t *frame, xlator_t *this,
void *data)
{
clnt_args_t *args = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
gfs3_fxattrop_req req = {{0,},};
int op_errno = ESTALE;
@@ -4432,11 +4443,11 @@ client3_1_fxattrop (call_frame_t *frame, xlator_t *this,
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
req.flags = args->flags;
- memcpy (req.gfid, args->fd->inode->gfid, 16);
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
local = GF_CALLOC (1, sizeof (*local),
gf_client_mt_clnt_local_t);
@@ -4580,7 +4591,7 @@ client3_1_lk (call_frame_t *frame, xlator_t *this,
gfs3_lk_req req = {{0,},};
int32_t gf_cmd = 0;
int32_t gf_type = 0;
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_local_t *local = NULL;
clnt_conf_t *conf = NULL;
int op_errno = ESTALE;
@@ -4597,7 +4608,7 @@ client3_1_lk (call_frame_t *frame, xlator_t *this,
goto unwind;
}
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
ret = client_cmd_to_gf_cmd (args->cmd, &gf_cmd);
if (ret) {
@@ -4624,10 +4635,11 @@ client3_1_lk (call_frame_t *frame, xlator_t *this,
local->fd = fd_ref (args->fd);
frame->local = local;
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
req.cmd = gf_cmd;
req.type = gf_type;
gf_proto_flock_from_flock (&req.flock, args->flock);
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
ret = client_submit_request (this, &req, frame, conf->fops, GFS3_OP_LK,
client3_1_lk_cbk, NULL,
@@ -4733,7 +4745,7 @@ client3_1_finodelk (call_frame_t *frame, xlator_t *this,
gfs3_finodelk_req req = {{0,},};
int32_t gf_cmd = 0;
int32_t gf_type = 0;
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
int op_errno = ESTALE;
int ret = 0;
@@ -4744,7 +4756,7 @@ client3_1_finodelk (call_frame_t *frame, xlator_t *this,
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
if (args->cmd == F_GETLK || args->cmd == F_GETLK64)
gf_cmd = GF_LK_GETLK;
@@ -4771,10 +4783,11 @@ client3_1_finodelk (call_frame_t *frame, xlator_t *this,
}
req.volume = (char *)args->volume;
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
req.cmd = gf_cmd;
req.type = gf_type;
gf_proto_flock_from_flock (&req.flock, args->flock);
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
ret = client_submit_request (this, &req, frame, conf->fops,
GFS3_OP_FINODELK,
@@ -4857,7 +4870,7 @@ client3_1_fentrylk (call_frame_t *frame, xlator_t *this,
{
clnt_args_t *args = NULL;
gfs3_fentrylk_req req = {{0,},};
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
int op_errno = ESTALE;
int ret = 0;
@@ -4868,9 +4881,9 @@ client3_1_fentrylk (call_frame_t *frame, xlator_t *this,
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
req.cmd = args->cmd_entrylk;
req.type = args->type;
req.volume = (char *)args->volume;
@@ -4879,6 +4892,7 @@ client3_1_fentrylk (call_frame_t *frame, xlator_t *this,
req.name = (char *)args->basename;
req.namelen = 1;
}
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
ret = client_submit_request (this, &req, frame, conf->fops,
GFS3_OP_FENTRYLK,
@@ -4903,7 +4917,7 @@ client3_1_rchecksum (call_frame_t *frame, xlator_t *this,
void *data)
{
clnt_args_t *args = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
gfs3_rchecksum_req req = {0,};
int op_errno = ESTALE;
@@ -4915,11 +4929,11 @@ client3_1_rchecksum (call_frame_t *frame, xlator_t *this,
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
req.len = args->len;
req.offset = args->offset;
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
ret = client_submit_request (this, &req, frame, conf->fops,
GFS3_OP_RCHECKSUM,
@@ -4945,7 +4959,7 @@ client3_1_readdir (call_frame_t *frame, xlator_t *this,
void *data)
{
clnt_args_t *args = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
gfs3_readdir_req req = {{0,},};
gfs3_readdir_rsp rsp = {0, };
@@ -4965,7 +4979,7 @@ client3_1_readdir (call_frame_t *frame, xlator_t *this,
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
readdir_rsp_size = xdr_sizeof ((xdrproc_t) xdr_gfs3_readdir_rsp, &rsp)
+ args->size;
@@ -5004,7 +5018,8 @@ client3_1_readdir (call_frame_t *frame, xlator_t *this,
req.size = args->size;
req.offset = args->offset;
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
ret = client_submit_request (this, &req, frame, conf->fops,
GFS3_OP_READDIR,
@@ -5047,7 +5062,7 @@ client3_1_readdirp (call_frame_t *frame, xlator_t *this,
clnt_args_t *args = NULL;
gfs3_readdirp_req req = {{0,},};
gfs3_readdirp_rsp rsp = {0,};
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
int op_errno = ESTALE;
int ret = 0;
@@ -5065,7 +5080,7 @@ client3_1_readdirp (call_frame_t *frame, xlator_t *this,
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
readdirp_rsp_size = xdr_sizeof ((xdrproc_t) xdr_gfs3_readdirp_rsp, &rsp)
+ args->size;
@@ -5106,7 +5121,8 @@ client3_1_readdirp (call_frame_t *frame, xlator_t *this,
req.size = args->size;
req.offset = args->offset;
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
+ memcpy (req.gfid, args->fd->inode->gfid, 16);
ret = client_submit_request (this, &req, frame, conf->fops,
GFS3_OP_READDIRP,
@@ -5192,7 +5208,7 @@ int32_t
client3_1_fsetattr (call_frame_t *frame, xlator_t *this, void *data)
{
clnt_args_t *args = NULL;
- clnt_fd_ctx_t *fdctx = NULL;
+ int64_t remote_fd = -1;
clnt_conf_t *conf = NULL;
gfs3_fsetattr_req req = {0,};
int op_errno = ESTALE;
@@ -5204,9 +5220,9 @@ client3_1_fsetattr (call_frame_t *frame, xlator_t *this, void *data)
args = data;
conf = this->private;
- CLIENT_GET_FD_CTX(conf, args, fdctx, op_errno, unwind);
+ CLIENT_GET_REMOTE_FD(conf, args->fd, remote_fd, unwind);
- req.fd = fdctx->remote_fd;
+ req.fd = remote_fd;
req.valid = args->valid;
gf_stat_from_iatt (&req.stbuf, args->stbuf);
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
index 45f14dcb3..f259a651f 100644
--- a/xlators/protocol/server/src/server-helpers.c
+++ b/xlators/protocol/server/src/server-helpers.c
@@ -69,28 +69,13 @@ 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)
GF_FREE ((void *)resolve->path);
if (resolve->bname)
GF_FREE ((void *)resolve->bname);
- if (resolve->resolved)
- GF_FREE ((void *)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);
- }
- GF_FREE ((void *)resolve->components);
- }
+ loc_wipe (&resolve->resolve_loc);
}
diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c
index 50ae9231c..38ab368c3 100644
--- a/xlators/protocol/server/src/server-resolve.c
+++ b/xlators/protocol/server/src/server-resolve.c
@@ -33,72 +33,9 @@ resolve_entry_simple (call_frame_t *frame);
int
resolve_inode_simple (call_frame_t *frame);
int
-resolve_path_simple (call_frame_t *frame);
-
+resolve_continue (call_frame_t *frame);
int
-component_count (const char *path)
-{
- int count = 0;
- const char *trav = NULL;
-
- for (trav = path; *trav; trav++) {
- if (*trav == '/')
- count++;
- }
-
- return count + 2;
-}
-
-
-int
-prepare_components (call_frame_t *frame)
-{
- server_state_t *state = 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);
- resolve = state->resolve_now;
-
- resolved = gf_strdup (resolve->path);
- resolve->resolved = resolved;
-
- count = component_count (resolve->path);
- components = GF_CALLOC (sizeof (*components), count,
- gf_server_mt_resolv_comp_t);
- if (!components)
- goto out;
-
- resolve->components = components;
-
- components[0].basename = "";
- components[0].inode = state->itable->root;
-
- i = 1;
- for (trav = resolved; *trav; trav++) {
- if (*trav == '/') {
- *trav = 0;
-
- if (!(*(trav + 1))) {
- /* Skip trailing "/" in a path.
- This is the check which prevents
- inode_link'age of itable->root
- */
- break;
- }
-
- components[i].basename = trav + 1;
- i++;
- }
- }
-out:
- return 0;
-}
-
+resolve_anonfd_simple (call_frame_t *frame);
int
resolve_loc_touchup (call_frame_t *frame)
@@ -123,231 +60,177 @@ resolve_loc_touchup (call_frame_t *frame)
if (ret)
gf_log (frame->this->name, GF_LOG_TRACE,
"return value inode_path %d", ret);
-
- if (!path)
- path = gf_strdup (resolve->path);
-
loc->path = path;
}
- loc->name = strrchr (loc->path, '/');
- if (loc->name)
- loc->name++;
-
- if (!loc->parent && loc->inode) {
- loc->parent = inode_parent (loc->inode, 0, NULL);
- }
-
return 0;
}
int
-resolve_deep_continue (call_frame_t *frame)
+resolve_gfid_entry_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)
{
server_state_t *state = NULL;
- xlator_t *this = NULL;
server_resolve_t *resolve = NULL;
- int ret = 0;
+ inode_t *link_inode = NULL;
+ loc_t *resolve_loc = NULL;
state = CALL_STATE (frame);
- this = frame->this;
resolve = state->resolve_now;
+ resolve_loc = &resolve->resolve_loc;
- resolve->op_ret = 0;
- resolve->op_errno = 0;
+ if (op_ret == -1) {
+ gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :
+ GF_LOG_WARNING),
+ "%s/%s: failed to resolve (%s)",
+ uuid_utoa (resolve_loc->pargfid), resolve_loc->name,
+ strerror (op_errno));
+ goto out;
+ }
- if (!uuid_is_null (resolve->pargfid))
- ret = resolve_entry_simple (frame);
- else if (!uuid_is_null (resolve->gfid))
- ret = resolve_inode_simple (frame);
- else if (resolve->path)
- ret = resolve_path_simple (frame);
- if (ret)
- gf_log (this->name, GF_LOG_DEBUG,
- "return value of resolve_*_simple %d", ret);
+ link_inode = inode_link (inode, resolve_loc->parent,
+ resolve_loc->name, buf);
- resolve_loc_touchup (frame);
+ if (!link_inode)
+ goto out;
- server_resolve_all (frame);
+ inode_lookup (link_inode);
+
+ inode_unref (link_inode);
+out:
+ loc_wipe (resolve_loc);
+
+ resolve_continue (frame);
return 0;
}
int
-resolve_deep_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+resolve_gfid_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)
{
server_state_t *state = NULL;
server_resolve_t *resolve = NULL;
- struct resolve_comp *components = NULL;
- int i = 0;
inode_t *link_inode = NULL;
+ loc_t *resolve_loc = NULL;
state = CALL_STATE (frame);
resolve = state->resolve_now;
- components = resolve->components;
-
- i = (long) cookie;
+ resolve_loc = &resolve->resolve_loc;
if (op_ret == -1) {
gf_log (this->name, ((op_errno == ENOENT) ? GF_LOG_DEBUG :
GF_LOG_WARNING),
"%s: failed to resolve (%s)",
- resolve->resolved, strerror (op_errno));
- goto get_out_of_here;
+ uuid_utoa (resolve_loc->gfid), strerror (op_errno));
+ loc_wipe (&resolve->resolve_loc);
+ goto out;
}
- 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_loc);
- loc_wipe (&resolve->deep_loc);
+ link_inode = inode_link (inode, NULL, NULL, buf);
- i++; /* next component */
+ if (!link_inode)
+ goto out;
- if (!components[i].basename) {
- /* all components of the path are resolved */
- goto get_out_of_here;
+ inode_lookup (link_inode);
+
+ if (uuid_is_null (resolve->pargfid)) {
+ inode_unref (link_inode);
+ goto out;
}
- /* join the current component with the path resolved until now */
- *(components[i].basename - 1) = '/';
+ resolve_loc->parent = link_inode;
+ uuid_copy (resolve_loc->pargfid, resolve_loc->parent->gfid);
- resolve->deep_loc.path = gf_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;
+ resolve_loc->name = resolve->bname;
- if (frame && frame->root->state && BOUND_XL (frame)) {
- STACK_WIND_COOKIE (frame, resolve_deep_cbk, (void *) (long) i,
- BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
- &resolve->deep_loc, NULL);
- return 0;
- }
+ resolve_loc->inode = inode_new (state->itable);
+ inode_path (resolve_loc->parent, resolve_loc->name,
+ (char **) &resolve_loc->path);
-get_out_of_here:
- resolve_deep_continue (frame);
+ STACK_WIND (frame, resolve_gfid_entry_cbk,
+ BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
+ &resolve->resolve_loc, NULL);
+ return 0;
+out:
+ resolve_continue (frame);
return 0;
}
int
-resolve_path_deep (call_frame_t *frame)
+resolve_gfid (call_frame_t *frame)
{
- server_state_t *state = NULL;
- server_resolve_t *resolve = NULL;
- int i = 0;
+ server_state_t *state = NULL;
+ xlator_t *this = NULL;
+ server_resolve_t *resolve = NULL;
+ loc_t *resolve_loc = NULL;
+ int ret = 0;
state = CALL_STATE (frame);
+ this = frame->this;
resolve = state->resolve_now;
+ resolve_loc = &resolve->resolve_loc;
- gf_log (BOUND_XL (frame)->name, GF_LOG_DEBUG,
- "RESOLVE %s() seeking deep resolution of %s",
- gf_fop_list[frame->root->op], resolve->path);
-
- prepare_components (frame);
-
- /* start from the root */
- resolve->deep_loc.inode = state->itable->root;
- resolve->deep_loc.path = gf_strdup ("/");
- resolve->deep_loc.name = "";
-
- if (frame && frame->root->state && BOUND_XL (frame)) {
- STACK_WIND_COOKIE (frame, resolve_deep_cbk, (void *) (long) i,
- BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
- &resolve->deep_loc, NULL);
- return 0;
+ if (!uuid_is_null (resolve->pargfid)) {
+ uuid_copy (resolve_loc->gfid, resolve->pargfid);
+ resolve_loc->inode = inode_new (state->itable);
+ ret = inode_path (resolve_loc->inode, NULL,
+ (char **)&resolve_loc->path);
+ } else if (!uuid_is_null (resolve->gfid)) {
+ uuid_copy (resolve_loc->gfid, resolve->gfid);
+ resolve_loc->inode = inode_new (state->itable);
+ ret = inode_path (resolve_loc->inode, NULL,
+ (char **)&resolve_loc->path);
}
- resolve_deep_continue (frame);
+ STACK_WIND (frame, resolve_gfid_cbk,
+ BOUND_XL (frame), BOUND_XL (frame)->fops->lookup,
+ &resolve->resolve_loc, NULL);
return 0;
}
int
-resolve_path_simple (call_frame_t *frame)
+resolve_continue (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 = -1;
- int ino_idx = -1;
- int i = 0;
+ int ret = 0;
state = CALL_STATE (frame);
+ this = frame->this;
resolve = state->resolve_now;
- components = resolve->components;
-
- if (!components) {
- gf_log ("", GF_LOG_INFO,
- "failed to resolve, component not found");
- 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 (ino_idx == -1) {
- gf_log ("", GF_LOG_INFO,
- "failed to resolve, inode index not found");
- resolve->op_ret = -1;
- resolve->op_errno = EINVAL;
- goto out;
- }
-
- if (par_idx == -1)
- /* "/" will not have a parent */
- goto noparent;
-
- if (!components[par_idx].inode) {
- gf_log ("", GF_LOG_INFO,
- "failed to resolve, parent inode not found");
- resolve->op_ret = -1;
- resolve->op_errno = ENOENT;
- goto out;
- }
- state->loc_now->parent = inode_ref (components[par_idx].inode);
-noparent:
-
- if (!components[ino_idx].inode &&
- (resolve->type == RESOLVE_MUST || resolve->type == RESOLVE_EXACT)) {
- gf_log ("", GF_LOG_INFO,
- "failed to resolve, inode not found");
- resolve->op_ret = -1;
- resolve->op_errno = ENOENT;
- goto out;
- }
+ resolve->op_ret = 0;
+ resolve->op_errno = 0;
- if (components[ino_idx].inode && resolve->type == RESOLVE_NOT) {
- gf_log ("", GF_LOG_INFO,
- "failed to resolve, inode found");
- resolve->op_ret = -1;
- resolve->op_errno = EEXIST;
+ if (resolve->fd_no != -1) {
+ ret = resolve_anonfd_simple (frame);
goto out;
- }
-
- if (components[ino_idx].inode)
- state->loc_now->inode = inode_ref (components[ino_idx].inode);
-
- ret = 0;
+ } else if (!uuid_is_null (resolve->pargfid))
+ ret = resolve_entry_simple (frame);
+ else if (!uuid_is_null (resolve->gfid))
+ ret = resolve_inode_simple (frame);
+ if (ret)
+ gf_log (this->name, GF_LOG_DEBUG,
+ "return value of resolve_*_simple %d", ret);
+ resolve_loc_touchup (frame);
out:
- return ret;
+ server_resolve_all (frame);
+
+ return 0;
}
+
/*
Check if the requirements are fulfilled by entries in the inode cache itself
Return value:
@@ -380,7 +263,9 @@ resolve_entry_simple (call_frame_t *frame)
}
/* expected @parent was found from the inode cache */
+ uuid_copy (state->loc_now->pargfid, resolve->pargfid);
state->loc_now->parent = inode_ref (parent);
+ state->loc_now->name = resolve->bname;
inode = inode_grep (state->itable, parent, resolve->bname);
if (!inode) {
@@ -441,7 +326,7 @@ server_resolve_entry (call_frame_t *frame)
if (ret > 0) {
loc_wipe (loc);
- resolve_path_deep (frame);
+ resolve_gfid (frame);
return 0;
}
@@ -477,6 +362,7 @@ resolve_inode_simple (call_frame_t *frame)
ret = 0;
state->loc_now->inode = inode_ref (inode);
+ uuid_copy (state->loc_now->gfid, resolve->gfid);
out:
if (inode)
@@ -500,7 +386,7 @@ server_resolve_inode (call_frame_t *frame)
if (ret > 0) {
loc_wipe (loc);
- resolve_path_deep (frame);
+ resolve_gfid (frame);
return 0;
}
@@ -514,6 +400,62 @@ server_resolve_inode (call_frame_t *frame)
int
+resolve_anonfd_simple (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ server_resolve_t *resolve = NULL;
+ inode_t *inode = NULL;
+ int ret = 0;
+
+ state = CALL_STATE (frame);
+ resolve = state->resolve_now;
+
+ inode = inode_find (state->itable, resolve->gfid);
+
+ if (!inode) {
+ resolve->op_ret = -1;
+ resolve->op_errno = ENOENT;
+ ret = 1;
+ goto out;
+ }
+
+ ret = 0;
+
+ state->fd = fd_anonymous (inode);
+out:
+ if (inode)
+ inode_unref (inode);
+
+ return ret;
+}
+
+
+int
+server_resolve_anonfd (call_frame_t *frame)
+{
+ server_state_t *state = NULL;
+ int ret = 0;
+ loc_t *loc = NULL;
+
+ state = CALL_STATE (frame);
+ loc = state->loc_now;
+
+ ret = resolve_anonfd_simple (frame);
+
+ if (ret > 0) {
+ loc_wipe (loc);
+ resolve_gfid (frame);
+ return 0;
+ }
+
+ server_resolve_all (frame);
+
+ return 0;
+
+}
+
+
+int
server_resolve_fd (call_frame_t *frame)
{
server_state_t *state = NULL;
@@ -527,6 +469,11 @@ server_resolve_fd (call_frame_t *frame)
fd_no = resolve->fd_no;
+ if (fd_no == -2) {
+ server_resolve_anonfd (frame);
+ return 0;
+ }
+
state->fd = gf_fd_fdptr_get (conn->fdtable, fd_no);
if (!state->fd) {
@@ -562,14 +509,11 @@ server_resolve (call_frame_t *frame)
server_resolve_inode (frame);
- } else if (resolve->path) {
-
- gf_log (frame->this->name, GF_LOG_INFO,
- "pure path resolution for %s (%s)",
- resolve->path, gf_fop_list[frame->root->op]);
- resolve_path_deep (frame);
-
- } else {
+ } else {
+ if (resolve == &state->resolve)
+ gf_log (frame->this->name, GF_LOG_WARNING,
+ "no resolution type for %s (%s)",
+ resolve->path, gf_fop_list[frame->root->op]);
resolve->op_ret = -1;
resolve->op_errno = EINVAL;
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
index c8fd5f271..6a37482f4 100644
--- a/xlators/protocol/server/src/server.h
+++ b/xlators/protocol/server/src/server.h
@@ -122,12 +122,9 @@ typedef struct {
u_char pargfid[16];
char *path;
char *bname;
- char *resolved;
int op_ret;
int op_errno;
- loc_t deep_loc;
- struct resolve_comp *components;
- int comp_count;
+ loc_t resolve_loc;
} server_resolve_t;
diff --git a/xlators/protocol/server/src/server3_1-fops.c b/xlators/protocol/server/src/server3_1-fops.c
index 60444061d..8df517be3 100644
--- a/xlators/protocol/server/src/server3_1-fops.c
+++ b/xlators/protocol/server/src/server3_1-fops.c
@@ -2690,7 +2690,6 @@ server_stat (rpcsvc_request_t *req)
return 0;
/* Initialize args first, then decode */
- args.path = alloca (req->msg[0].iov_len);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_stat_req)) {
//failed to decode msg;
@@ -2715,7 +2714,6 @@ server_stat (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.gfid, args.gfid, 16);
- state->resolve.path = gf_strdup (args.path);
ret = 0;
resolve_and_resume (frame, server_stat_resume);
@@ -2735,8 +2733,6 @@ server_setattr (rpcsvc_request_t *req)
if (!req)
return 0;
- args.path = alloca (req->msg[0].iov_len);
-
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_setattr_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
@@ -2760,7 +2756,6 @@ server_setattr (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.gfid, args.gfid, 16);
- state->resolve.path = gf_strdup (args.path);
gf_stat_to_iatt (&args.stbuf, &state->stbuf);
state->valid = args.valid;
@@ -2828,8 +2823,6 @@ server_readlink (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
-
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_readlink_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
@@ -2853,7 +2846,6 @@ server_readlink (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.gfid, args.gfid, 16);
- state->resolve.path = gf_strdup (args.path);
state->size = args.size;
@@ -2877,7 +2869,6 @@ server_create (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_create_req)) {
@@ -2927,7 +2918,6 @@ server_create (rpcsvc_request_t *req)
buf = NULL;
}
- state->resolve.path = gf_strdup (args.path);
state->resolve.bname = gf_strdup (args.bname);
state->mode = args.mode;
state->flags = gf_flags_to_flags (args.flags);
@@ -2976,8 +2966,6 @@ server_open (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
-
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_open_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
@@ -3001,7 +2989,6 @@ server_open (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.gfid, args.gfid, 16);
- state->resolve.path = gf_strdup (args.path);
state->flags = gf_flags_to_flags (args.flags);
@@ -3048,6 +3035,7 @@ server_readv (rpcsvc_request_t *req)
state->resolve.fd_no = args.fd;
state->size = args.size;
state->offset = args.offset;
+ memcpy (state->resolve.gfid, args.gfid, 16);
ret = 0;
resolve_and_resume (frame, server_readv_resume);
@@ -3095,6 +3083,7 @@ server_writev (rpcsvc_request_t *req)
state->resolve.fd_no = args.fd;
state->offset = args.offset;
state->iobref = iobref_ref (req->iobref);
+ memcpy (state->resolve.gfid, args.gfid, 16);
if (len < req->msg[0].iov_len) {
state->payload_vector[0].iov_base
@@ -3236,6 +3225,7 @@ server_fsync (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->flags = args.data;
+ memcpy (state->resolve.gfid, args.gfid, 16);
ret = 0;
resolve_and_resume (frame, server_fsync_resume);
@@ -3279,6 +3269,7 @@ server_flush (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
ret = 0;
resolve_and_resume (frame, server_flush_resume);
@@ -3323,6 +3314,7 @@ server_ftruncate (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->offset = args.offset;
+ memcpy (state->resolve.gfid, args.gfid, 16);
ret = 0;
resolve_and_resume (frame, server_ftruncate_resume);
@@ -3365,6 +3357,7 @@ server_fstat (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
ret = 0;
resolve_and_resume (frame, server_fstat_resume);
@@ -3384,7 +3377,6 @@ server_truncate (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_truncate_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
@@ -3407,7 +3399,6 @@ server_truncate (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
- state->resolve.path = gf_strdup (args.path);
memcpy (state->resolve.gfid, args.gfid, 16);
state->offset = args.offset;
@@ -3430,7 +3421,6 @@ server_unlink (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_unlink_req)) {
@@ -3455,7 +3445,6 @@ server_unlink (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
- state->resolve.path = gf_strdup (args.path);
state->resolve.bname = gf_strdup (args.bname);
memcpy (state->resolve.pargfid, args.pargfid, 16);
@@ -3482,7 +3471,6 @@ server_setxattr (rpcsvc_request_t *req)
conn = req->trans->xl_private;
- args.path = alloca (req->msg[0].iov_len);
args.dict.dict_val = alloca (req->msg[0].iov_len);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_setxattr_req)) {
@@ -3507,7 +3495,6 @@ server_setxattr (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
- state->resolve.path = gf_strdup (args.path);
state->flags = args.flags;
memcpy (state->resolve.gfid, args.gfid, 16);
@@ -3595,6 +3582,7 @@ server_fsetxattr (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->flags = args.flags;
+ memcpy (state->resolve.gfid, args.gfid, 16);
if (args.dict.dict_len) {
dict = dict_new ();
@@ -3732,7 +3720,6 @@ server_xattrop (rpcsvc_request_t *req)
conn = req->trans->xl_private;
args.dict.dict_val = alloca (req->msg[0].iov_len);
- args.path = alloca (req->msg[0].iov_len);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_xattrop_req)) {
//failed to decode msg;
@@ -3756,7 +3743,6 @@ server_xattrop (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
- state->resolve.path = gf_strdup (args.path);
state->flags = args.flags;
memcpy (state->resolve.gfid, args.gfid, 16);
@@ -3808,8 +3794,7 @@ server_getxattr (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
- args.name = alloca (4096);
+ args.name = alloca (256);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_getxattr_req)) {
//failed to decode msg;
@@ -3833,7 +3818,6 @@ server_getxattr (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
- state->resolve.path = gf_strdup (args.path);
memcpy (state->resolve.gfid, args.gfid, 16);
if (args.namelen) {
@@ -3860,7 +3844,7 @@ server_fgetxattr (rpcsvc_request_t *req)
if (!req)
return ret;
- args.name = alloca (4096);
+ args.name = alloca (256);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fgetxattr_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
@@ -3884,6 +3868,7 @@ server_fgetxattr (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
if (args.namelen)
state->name = gf_strdup (args.name);
@@ -3907,8 +3892,7 @@ server_removexattr (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
- args.name = alloca (4096);
+ args.name = alloca (256);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_removexattr_req)) {
//failed to decode msg;
@@ -3932,7 +3916,6 @@ server_removexattr (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
- state->resolve.path = gf_strdup (args.path);
memcpy (state->resolve.gfid, args.gfid, 16);
state->name = gf_strdup (args.name);
@@ -3956,8 +3939,6 @@ server_opendir (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
-
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_opendir_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
@@ -3980,7 +3961,6 @@ server_opendir (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_MUST;
- state->resolve.path = gf_strdup (args.path);
memcpy (state->resolve.gfid, args.gfid, 16);
ret = 0;
@@ -4037,6 +4017,7 @@ server_readdirp (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->offset = args.offset;
+ memcpy (state->resolve.gfid, args.gfid, 16);
ret = 0;
resolve_and_resume (frame, server_readdirp_resume);
@@ -4091,6 +4072,7 @@ server_readdir (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->offset = args.offset;
+ memcpy (state->resolve.gfid, args.gfid, 16);
ret = 0;
resolve_and_resume (frame, server_readdir_resume);
@@ -4133,6 +4115,7 @@ server_fsyncdir (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
state->resolve.fd_no = args.fd;
state->flags = args.data;
+ memcpy (state->resolve.gfid, args.gfid, 16);
ret = 0;
resolve_and_resume (frame, server_fsyncdir_resume);
@@ -4155,7 +4138,6 @@ server_mknod (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_mknod_req)) {
@@ -4208,7 +4190,6 @@ server_mknod (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_NOT;
memcpy (state->resolve.pargfid, args.pargfid, 16);
- state->resolve.path = gf_strdup (args.path);
state->resolve.bname = gf_strdup (args.bname);
state->mode = args.mode;
@@ -4254,7 +4235,6 @@ server_mkdir (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_mkdir_req)) {
@@ -4306,7 +4286,6 @@ server_mkdir (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_NOT;
memcpy (state->resolve.pargfid, args.pargfid, 16);
- state->resolve.path = gf_strdup (args.path);
state->resolve.bname = gf_strdup (args.bname);
state->mode = args.mode;
@@ -4348,7 +4327,6 @@ server_rmdir (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_rmdir_req)) {
@@ -4374,7 +4352,6 @@ server_rmdir (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.pargfid, args.pargfid, 16);
- state->resolve.path = gf_strdup (args.path);
state->resolve.bname = gf_strdup (args.bname);
state->flags = args.flags;
@@ -4399,8 +4376,7 @@ server_inodelk (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
- args.volume = alloca (4096);
+ args.volume = alloca (256);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_inodelk_req)) {
//failed to decode msg;
@@ -4425,7 +4401,6 @@ server_inodelk (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_EXACT;
memcpy (state->resolve.gfid, args.gfid, 16);
- state->resolve.path = gf_strdup (args.path);
cmd = args.cmd;
switch (cmd) {
@@ -4474,7 +4449,7 @@ server_finodelk (rpcsvc_request_t *req)
if (!req)
return ret;
- args.volume = alloca (4096);
+ args.volume = alloca (256);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_finodelk_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
@@ -4500,6 +4475,7 @@ server_finodelk (rpcsvc_request_t *req)
state->volume = gf_strdup (args.volume);
state->resolve.fd_no = args.fd;
state->cmd = args.cmd;
+ memcpy (state->resolve.gfid, args.gfid, 16);
switch (state->cmd) {
case GF_LK_GETLK:
@@ -4547,9 +4523,8 @@ server_entrylk (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
- args.volume = alloca (4096);
- args.name = alloca (4096);
+ args.volume = alloca (256);
+ args.name = alloca (256);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_entrylk_req)) {
//failed to decode msg;
@@ -4573,7 +4548,6 @@ server_entrylk (rpcsvc_request_t *req)
}
state->resolve.type = RESOLVE_EXACT;
- state->resolve.path = gf_strdup (args.path);
memcpy (state->resolve.gfid, args.gfid, 16);
if (args.namelen)
@@ -4600,8 +4574,8 @@ server_fentrylk (rpcsvc_request_t *req)
if (!req)
return ret;
- args.name = alloca (4096);
- args.volume = alloca (4096);
+ args.name = alloca (256);
+ args.volume = alloca (256);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_fentrylk_req)) {
//failed to decode msg;
@@ -4628,6 +4602,7 @@ server_fentrylk (rpcsvc_request_t *req)
state->resolve.fd_no = args.fd;
state->cmd = args.cmd;
state->type = args.type;
+ memcpy (state->resolve.gfid, args.gfid, 16);
if (args.namelen)
state->name = gf_strdup (args.name);
@@ -4650,7 +4625,6 @@ server_access (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_access_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
@@ -4674,7 +4648,6 @@ server_access (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.gfid, args.gfid, 16);
- state->resolve.path = gf_strdup (args.path);
state->mask = args.mask;
ret = 0;
@@ -4698,7 +4671,6 @@ server_symlink (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
args.linkname = alloca (4096);
@@ -4752,7 +4724,6 @@ server_symlink (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_NOT;
memcpy (state->resolve.pargfid, args.pargfid, 16);
- state->resolve.path = gf_strdup (args.path);
state->resolve.bname = gf_strdup (args.bname);
state->name = gf_strdup (args.linkname);
@@ -4925,6 +4896,7 @@ server_lk (rpcsvc_request_t *req)
state->resolve.fd_no = args.fd;
state->cmd = args.cmd;
state->type = args.type;
+ memcpy (state->resolve.gfid, args.gfid, 16);
switch (state->cmd) {
case GF_LK_GETLK:
@@ -5052,7 +5024,6 @@ server_lookup (rpcsvc_request_t *req)
conn = req->trans->xl_private;
- args.path = alloca (req->msg[0].iov_len);
args.bname = alloca (req->msg[0].iov_len);
args.dict.dict_val = alloca (req->msg[0].iov_len);
@@ -5080,14 +5051,14 @@ server_lookup (rpcsvc_request_t *req)
req->rpc_err = GARBAGE_ARGS;
goto out;
}
- memcpy (state->resolve.gfid, args.gfid, 16);
state->resolve.type = RESOLVE_DONTCARE;
- memcpy (state->resolve.pargfid, args.pargfid, 16);
- state->resolve.path = gf_strdup (args.path);
- if (IS_NOT_ROOT (STRLEN_0 (args.path))) {
+ if (args.bname && strcmp (args.bname, "")) {
+ memcpy (state->resolve.pargfid, args.pargfid, 16);
state->resolve.bname = gf_strdup (args.bname);
+ } else {
+ memcpy (state->resolve.gfid, args.gfid, 16);
}
if (args.dict.dict_len) {
@@ -5147,7 +5118,6 @@ server_statfs (rpcsvc_request_t *req)
if (!req)
return ret;
- args.path = alloca (req->msg[0].iov_len);
if (!xdr_to_generic (req->msg[0], &args, (xdrproc_t)xdr_gfs3_statfs_req)) {
//failed to decode msg;
req->rpc_err = GARBAGE_ARGS;
@@ -5171,7 +5141,6 @@ server_statfs (rpcsvc_request_t *req)
state->resolve.type = RESOLVE_MUST;
memcpy (state->resolve.gfid, args.gfid, 16);
- state->resolve.path = gf_strdup (args.path);
ret = 0;
resolve_and_resume (frame, server_statfs_resume);
diff --git a/xlators/storage/posix/src/Makefile.am b/xlators/storage/posix/src/Makefile.am
index 90ea1fd51..d1d420017 100644
--- a/xlators/storage/posix/src/Makefile.am
+++ b/xlators/storage/posix/src/Makefile.am
@@ -4,10 +4,10 @@ xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/storage
posix_la_LDFLAGS = -module -avoidversion
-posix_la_SOURCES = posix.c posix-helpers.c
+posix_la_SOURCES = posix.c posix-helpers.c posix-handle.c
posix_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
-noinst_HEADERS = posix.h posix-mem-types.h
+noinst_HEADERS = posix.h posix-mem-types.h posix-handle.h
AM_CFLAGS = -fPIC -fno-strict-aliasing -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE \
-D$(GF_HOST_OS) -Wall -I$(top_srcdir)/libglusterfs/src -shared \
diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c
new file mode 100644
index 000000000..b0693324d
--- /dev/null
+++ b/xlators/storage/posix/src/posix-handle.c
@@ -0,0 +1,621 @@
+/*
+ Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <alloca.h>
+
+#include "posix-handle.h"
+#include "posix.h"
+#include "xlator.h"
+
+
+#define HANDLE_PFX ".glusterfs"
+
+#define UUID0_STR "00000000-0000-0000-0000-000000000000"
+#define SLEN(str) (sizeof(str) - 1)
+
+
+int
+posix_handle_relpath (xlator_t *this, uuid_t gfid, const char *basename,
+ char *buf, size_t buflen)
+{
+ char *uuid_str = NULL;
+ int len = 0;
+
+ len = SLEN("../")
+ + SLEN("../")
+ + SLEN("00/")
+ + SLEN("00/")
+ + SLEN(UUID0_STR)
+ + 1 /* '\0' */
+ ;
+
+ if (basename) {
+ len += (strlen (basename) + 1);
+ }
+
+ if (buflen < len || !buf)
+ return len;
+
+ uuid_str = uuid_utoa (gfid);
+
+ if (basename) {
+ len = snprintf (buf, buflen, "../../%02x/%02x/%s/%s",
+ gfid[0], gfid[1], uuid_str, basename);
+ } else {
+ len = snprintf (buf, buflen, "../../%02x/%02x/%s",
+ gfid[0], gfid[1], uuid_str);
+ }
+
+ return len;
+}
+
+
+/*
+ TODO: explain how this pump fixes ELOOP
+*/
+int
+posix_handle_pump (xlator_t *this, char *buf, int len, int maxlen,
+ char *base_str, int base_len, int pfx_len)
+{
+ char linkname[512] = {0,}; /* "../../<gfid>/<NAME_MAX>" */
+ int ret = 0;
+ int blen = 0;
+ int link_len = 0;
+
+ /* is a directory's symlink-handle */
+ ret = readlink (base_str, linkname, 512);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "internal readlink failed on %s (%s)",
+ base_str, strerror (errno));
+ goto err;
+ }
+
+ if (ret < 512)
+ linkname[ret] = 0;
+
+ link_len = ret;
+
+ if ((ret == 8) && memcmp (linkname, "../../..", 8) == 0) {
+ if (strcmp (base_str, buf) == 0) {
+ strncpy (buf + pfx_len, "..", 3);
+ }
+ goto out;
+ }
+
+ if (ret < 50 || ret >= 512) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "malformed internal link %s for %s",
+ linkname, base_str);
+ goto err;
+ }
+
+ if (memcmp (linkname, "../../", 6) != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "malformed internal link %s for %s",
+ linkname, base_str);
+ goto err;
+ }
+
+ if ((linkname[2] != '/') ||
+ (linkname[5] != '/') ||
+ (linkname[8] != '/') ||
+ (linkname[11] != '/') ||
+ (linkname[48] != '/')) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "malformed internal link %s for %s",
+ linkname, base_str);
+ goto err;
+ }
+
+ if ((linkname[20] != '-') ||
+ (linkname[25] != '-') ||
+ (linkname[30] != '-') ||
+ (linkname[35] != '-')) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "malformed internal link %s for %s",
+ linkname, base_str);
+ goto err;
+ }
+
+ blen = link_len - 48;
+ memmove (buf + base_len + blen, buf + base_len,
+ (strlen (buf) - base_len) + 1);
+
+ strncpy (base_str + pfx_len, linkname + 6, 42);
+
+ if (len + blen < maxlen)
+ strncpy (buf + pfx_len, linkname + 6, link_len - 6);
+out:
+ return len + blen;
+err:
+ return -1;
+}
+
+
+/*
+ posix_handle_path differs from posix_handle_gfid_path in the way that the
+ path filled in @buf by posix_handle_path will return type IA_IFDIR when
+ an lstat() is performed on it, whereas posix_handle_gfid_path returns path
+ to the handle symlink (typically used for the purpose of unlinking it).
+
+ posix_handle_path also guarantees immunity to ELOOP on the path returned by it
+*/
+
+int
+posix_handle_path (xlator_t *this, uuid_t gfid, const char *basename,
+ char *ubuf, size_t size)
+{
+ struct posix_private *priv = NULL;
+ char *uuid_str = NULL;
+ int len = 0;
+ int ret = -1;
+ struct stat stat;
+ char *base_str = NULL;
+ int base_len = 0;
+ int pfx_len;
+ int maxlen;
+ char *buf;
+
+ priv = this->private;
+
+ uuid_str = uuid_utoa (gfid);
+
+ if (ubuf) {
+ buf = ubuf;
+ maxlen = size;
+ } else {
+ maxlen = PATH_MAX;
+ buf = alloca (maxlen);
+ }
+
+ base_len = (priv->base_path_length + SLEN(HANDLE_PFX) + 45);
+ base_str = alloca (base_len + 1);
+ base_len = snprintf (base_str, base_len + 1, "%s/%s/%02x/%02x/%s",
+ priv->base_path, HANDLE_PFX, gfid[0], gfid[1],
+ uuid_str);
+
+ pfx_len = priv->base_path_length + 1 + SLEN(HANDLE_PFX) + 1;
+
+ if (basename) {
+ len = snprintf (buf, maxlen, "%s/%s", base_str, basename);
+ } else {
+ len = snprintf (buf, maxlen, "%s", base_str);
+ }
+
+ ret = lstat (base_str, &stat);
+
+ if (!(ret == 0 && S_ISLNK(stat.st_mode) && stat.st_nlink == 1))
+ goto out;
+
+ do {
+ errno = 0;
+ ret = posix_handle_pump (this, buf, len, maxlen,
+ base_str, base_len, pfx_len);
+ if (ret == -1)
+ break;
+
+ len = ret;
+
+ ret = lstat (buf, &stat);
+ } while ((ret == -1) && errno == ELOOP);
+
+out:
+ return len + 1;
+}
+
+
+int
+posix_handle_gfid_path (xlator_t *this, uuid_t gfid, const char *basename,
+ char *buf, size_t buflen)
+{
+ struct posix_private *priv = NULL;
+ char *uuid_str = NULL;
+ int len = 0;
+
+ priv = this->private;
+
+ len = priv->base_path_length /* option directory "/export" */
+ + SLEN("/")
+ + SLEN(HANDLE_PFX)
+ + SLEN("/")
+ + SLEN("00/")
+ + SLEN("00/")
+ + SLEN(UUID0_STR)
+ + 1 /* '\0' */
+ ;
+
+ if (basename) {
+ len += (strlen (basename) + 1);
+ } else {
+ len += 256; /* worst-case for directory's symlink-handle expansion */
+ }
+
+ if ((buflen < len) || !buf)
+ return len;
+
+ uuid_str = uuid_utoa (gfid);
+
+ if (__is_root_gfid (gfid)) {
+ if (basename) {
+ len = snprintf (buf, buflen, "%s/%s", priv->base_path,
+ basename);
+ } else {
+ strncpy (buf, priv->base_path, buflen);
+ }
+ goto out;
+ }
+
+ if (basename) {
+ len = snprintf (buf, buflen, "%s/%s/%02x/%02x/%s/%s", priv->base_path,
+ HANDLE_PFX, gfid[0], gfid[1], uuid_str, basename);
+ } else {
+ len = snprintf (buf, buflen, "%s/%s/%02x/%02x/%s", priv->base_path,
+ HANDLE_PFX, gfid[0], gfid[1], uuid_str);
+ }
+out:
+ return len;
+}
+
+
+int
+posix_handle_init (xlator_t *this)
+{
+ struct posix_private *priv = NULL;
+ char *handle_pfx = NULL;
+ int ret = 0;
+ int len = 0;
+ struct stat stbuf;
+ struct stat rootbuf;
+ struct stat exportbuf;
+ char *rootstr = NULL;
+ uuid_t gfid = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
+
+ priv = this->private;
+
+ ret = stat (priv->base_path, &exportbuf);
+ if (ret || !S_ISDIR (exportbuf.st_mode)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Not a directory: %s", priv->base_path);
+ return -1;
+ }
+
+ handle_pfx = alloca (priv->base_path_length + 1 + strlen (HANDLE_PFX)
+ + 1);
+
+ sprintf (handle_pfx, "%s/%s", priv->base_path, HANDLE_PFX);
+
+ ret = stat (handle_pfx, &stbuf);
+ switch (ret) {
+ case -1:
+ if (errno == ENOENT) {
+ ret = mkdir (handle_pfx, 0600);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Creating directory %s failed: %s",
+ handle_pfx, strerror (errno));
+ return -1;
+ }
+ } else {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Checking for %s failed: %s",
+ handle_pfx, strerror (errno));
+ return -1;
+ }
+ break;
+ case 0:
+ if (!S_ISDIR (stbuf.st_mode)) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Not a directory: %s",
+ handle_pfx);
+ return -1;
+ }
+ break;
+ default:
+ break;
+ }
+
+ stat (handle_pfx, &priv->handledir);
+
+ len = posix_handle_path (this, gfid, NULL, NULL, 0);
+ rootstr = alloca (len);
+ posix_handle_path (this, gfid, NULL, rootstr, len);
+
+ ret = stat (rootstr, &rootbuf);
+ switch (ret) {
+ case -1:
+ if (errno != ENOENT) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: %s", priv->base_path,
+ strerror (errno));
+ return -1;
+ }
+
+ ret = posix_handle_mkdir_hashes (this, rootstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "mkdir %s failed (%s)",
+ rootstr, strerror (errno));
+ return -1;
+ }
+
+ ret = symlink ("../../..", rootstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "symlink %s creation failed (%s)",
+ rootstr, strerror (errno));
+ return -1;
+ }
+ break;
+ case 0:
+ if ((exportbuf.st_ino == rootbuf.st_ino) &&
+ (exportbuf.st_dev == rootbuf.st_dev))
+ return 0;
+
+ gf_log (this->name, GF_LOG_ERROR,
+ "Different dirs %s (%lld/%lld) != %s (%lld/%lld)",
+ priv->base_path, (long long) exportbuf.st_ino,
+ (long long) exportbuf.st_dev, rootstr,
+ (long long) rootbuf.st_ino, (long long) rootbuf.st_dev);
+ return -1;
+
+ break;
+ }
+
+ return 0;
+}
+
+
+int
+posix_handle_mkdir_hashes (xlator_t *this, const char *newpath)
+{
+ char *duppath = NULL;
+ char *parpath = NULL;
+ int ret = 0;
+
+ duppath = strdupa (newpath);
+ parpath = dirname (duppath);
+ parpath = dirname (duppath);
+
+ ret = mkdir (parpath, 0700);
+ if (ret == -1 && errno != EEXIST) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "error mkdir hash-1 %s (%s)",
+ parpath, strerror (errno));
+ return -1;
+ }
+
+ strcpy (duppath, newpath);
+ parpath = dirname (duppath);
+
+ ret = mkdir (parpath, 0700);
+ if (ret == -1 && errno != EEXIST) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "error mkdir hash-2 %s (%s)",
+ parpath, strerror (errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+posix_handle_hard (xlator_t *this, const char *oldpath, uuid_t gfid, struct stat *oldbuf)
+{
+ char *newpath = NULL;
+ struct stat newbuf;
+ int ret = -1;
+
+
+ MAKE_HANDLE_PATH (newpath, this, gfid, NULL);
+
+ ret = lstat (newpath, &newbuf);
+ if (ret == -1 && errno != ENOENT) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: %s", newpath, strerror (errno));
+ return -1;
+ }
+
+ if (ret == -1 && errno == ENOENT) {
+ ret = posix_handle_mkdir_hashes (this, newpath);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "mkdir %s failed (%s)",
+ newpath, strerror (errno));
+ return -1;
+ }
+
+ ret = link (oldpath, newpath);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "link %s -> %s failed (%s)",
+ oldpath, newpath, strerror (errno));
+ return -1;
+ }
+
+ ret = lstat (newpath, &newbuf);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lstat on %s failed (%s)",
+ newpath, strerror (errno));
+ return -1;
+ }
+ }
+
+ ret = lstat (newpath, &newbuf);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "lstat on %s failed (%s)", newpath, strerror (errno));
+ return -1;
+ }
+
+ if (newbuf.st_ino != oldbuf->st_ino ||
+ newbuf.st_dev != oldbuf->st_dev) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "mismatching ino/dev between file %s (%lld/%lld) "
+ "and handle %s (%lld/%lld)",
+ oldpath, (long long) oldbuf->st_ino, (long long) oldbuf->st_dev,
+ newpath, (long long) newbuf.st_ino, (long long) newbuf.st_dev);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+
+int
+posix_handle_soft (xlator_t *this, const char *real_path, loc_t *loc,
+ uuid_t gfid, struct stat *oldbuf)
+{
+ char *oldpath = NULL;
+ char *newpath = NULL;
+ struct stat newbuf;
+ int ret = -1;
+
+
+ MAKE_HANDLE_PATH (newpath, this, gfid, NULL);
+ MAKE_HANDLE_RELPATH (oldpath, this, loc->pargfid, loc->name);
+
+
+ ret = lstat (newpath, &newbuf);
+ if (ret == -1 && errno != ENOENT) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: %s", newpath, strerror (errno));
+ return -1;
+ }
+
+ if (ret == -1 && errno == ENOENT) {
+ ret = posix_handle_mkdir_hashes (this, newpath);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "mkdir %s failed (%s)",
+ newpath, strerror (errno));
+ return -1;
+ }
+
+ ret = symlink (oldpath, newpath);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "symlink %s -> %s failed (%s)",
+ oldpath, newpath, strerror (errno));
+ return -1;
+ }
+
+ ret = lstat (newpath, &newbuf);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat on %s failed (%s)",
+ newpath, strerror (errno));
+ return -1;
+ }
+ }
+
+ ret = stat (real_path, &newbuf);
+ if (ret) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "stat on %s failed (%s)", newpath, strerror (errno));
+ return -1;
+ }
+
+ if (!oldbuf)
+ return ret;
+
+ if (newbuf.st_ino != oldbuf->st_ino ||
+ newbuf.st_dev != oldbuf->st_dev) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "mismatching ino/dev between file %s (%lld/%lld) "
+ "and handle %s (%lld/%lld)",
+ oldpath, (long long) oldbuf->st_ino, (long long) oldbuf->st_dev,
+ newpath, (long long) newbuf.st_ino, (long long) newbuf.st_dev);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+
+static int
+posix_handle_unset_gfid (xlator_t *this, uuid_t gfid)
+{
+ char *path = NULL;
+ int ret = 0;
+ struct stat stat;
+
+ MAKE_HANDLE_GFID_PATH (path, this, gfid, NULL);
+
+ ret = lstat (path, &stat);
+
+ if (ret == -1) {
+ if (errno != ENOENT) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: %s", path, strerror (errno));
+ }
+ goto out;
+ }
+
+ ret = unlink (path);
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "unlink %s failed (%s)", path, strerror (errno));
+ }
+
+out:
+ return ret;
+}
+
+
+int
+posix_handle_unset (xlator_t *this, uuid_t gfid, const char *basename)
+{
+ int ret;
+ struct iatt stat;
+ char *path = NULL;
+
+
+ if (!basename) {
+ ret = posix_handle_unset_gfid (this, gfid);
+ return ret;
+ }
+
+ MAKE_HANDLE_PATH (path, this, gfid, basename);
+
+ ret = posix_istat (this, gfid, basename, &stat);
+
+ if (ret == -1) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "%s: %s", path, strerror (errno));
+ return -1;
+ }
+
+ ret = posix_handle_unset_gfid (this, stat.ia_gfid);
+
+ return ret;
+}
+
diff --git a/xlators/storage/posix/src/posix-handle.h b/xlators/storage/posix/src/posix-handle.h
new file mode 100644
index 000000000..b22149f63
--- /dev/null
+++ b/xlators/storage/posix/src/posix-handle.h
@@ -0,0 +1,148 @@
+/*
+ Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ This file is part of GlusterFS.
+
+ GlusterFS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3 of the License,
+ or (at your option) any later version.
+
+ GlusterFS is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _POSIX_HANDLE_H
+#define _POSIX_HANDLE_H
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include "xlator.h"
+
+
+#define LOC_HAS_ABSPATH(loc) ((loc) && (loc->path) && (loc->path[0] == '/'))
+
+#define MAKE_REAL_PATH(var, this, path) do { \
+ var = alloca (strlen (path) + POSIX_BASE_PATH_LEN(this) + 2); \
+ strcpy (var, POSIX_BASE_PATH(this)); \
+ strcpy (&var[POSIX_BASE_PATH_LEN(this)], path); \
+ } while (0)
+
+
+#define MAKE_HANDLE_PATH(var, this, gfid, base) do { \
+ int __len; \
+ __len = posix_handle_path (this, gfid, base, NULL, 0); \
+ if (__len <= 0) \
+ break; \
+ var = alloca (__len); \
+ __len = posix_handle_path (this, gfid, base, var, __len); \
+ } while (0)
+
+
+#define MAKE_HANDLE_GFID_PATH(var, this, gfid, base) do { \
+ int __len = 0; \
+ __len = posix_handle_gfid_path (this, gfid, base, NULL, 0); \
+ if (__len <= 0) \
+ break; \
+ var = alloca (__len); \
+ __len = posix_handle_gfid_path (this, gfid, base, var, __len); \
+ } while (0)
+
+
+#define MAKE_HANDLE_RELPATH(var, this, gfid, base) do { \
+ int __len; \
+ __len = posix_handle_relpath (this, gfid, base, NULL, 0); \
+ if (__len <= 0) \
+ break; \
+ var = alloca (__len); \
+ __len = posix_handle_relpath (this, gfid, base, var, __len); \
+ } while (0)
+
+
+#define MAKE_INODE_HANDLE(rpath, this, loc, iatt_p) do { \
+ if (uuid_is_null (loc->gfid)) { \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "null gfid for path %s", loc->path); \
+ break; \
+ } \
+ errno = 0; \
+ op_ret = posix_istat (this, loc->gfid, NULL, iatt_p); \
+ if (errno != ELOOP) { \
+ MAKE_HANDLE_PATH (rpath, this, loc->gfid, NULL); \
+ break; \
+ } \
+ /* __ret == -1 && errno == ELOOP */ \
+ if (LOC_HAS_ABSPATH (loc)) { \
+ MAKE_REAL_PATH (rpath, this, loc->path); \
+ op_ret = posix_pstat (this, loc->gfid, rpath, iatt_p); \
+ break; \
+ } \
+ } while (0)
+
+
+#define MAKE_ENTRY_HANDLE(entp, parp, this, loc, ent_p) do { \
+ char *__parp; \
+ \
+ if (uuid_is_null (loc->pargfid) || !loc->name) { \
+ gf_log (this->name, GF_LOG_ERROR, \
+ "null pargfid/name for path %s", loc->path); \
+ break; \
+ } \
+ \
+ errno = 0; \
+ op_ret = posix_istat (this, loc->pargfid, loc->name, ent_p); \
+ if (errno != ELOOP) { \
+ MAKE_HANDLE_PATH (parp, this, loc->pargfid, NULL); \
+ MAKE_HANDLE_PATH (entp, this, loc->pargfid, loc->name); \
+ break; \
+ } \
+ /* __ret == -1 && errno == ELOOP */ \
+ if (LOC_HAS_ABSPATH (loc)) { \
+ MAKE_REAL_PATH (entp, this, loc->path); \
+ __parp = strdupa (entp); \
+ parp = dirname (__parp); \
+ op_ret = posix_pstat (this, NULL, entp, ent_p); \
+ break; \
+ } \
+ /* expand ELOOP */ \
+ } while (0)
+
+
+
+int
+posix_handle_path (xlator_t *this, uuid_t gfid, const char *basename, char *buf,
+ size_t len);
+int
+posix_handle_path_safe (xlator_t *this, uuid_t gfid, const char *basename,
+ char *buf, size_t len);
+
+int
+posix_handle_gfid_path (xlator_t *this, uuid_t gfid, const char *basename,
+ char *buf, size_t len);
+
+int
+posix_handle_hard (xlator_t *this, const char *path, uuid_t gfid,
+ struct stat *buf);
+
+
+int
+posix_handle_soft (xlator_t *this, const char *real_path, loc_t *loc,
+ uuid_t gfid, struct stat *buf);
+
+int
+posix_handle_unset (xlator_t *this, uuid_t gfid, const char *basename);
+
+int posix_handle_mkdir_hashes (xlator_t *this, const char *newpath);
+
+int posix_handle_init (xlator_t *this);
+
+#endif /* !_POSIX_HANDLE_H */
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
index edc64f583..31a4e667d 100644
--- a/xlators/storage/posix/src/posix-helpers.c
+++ b/xlators/storage/posix/src/posix-helpers.c
@@ -264,19 +264,22 @@ out:
}
int
-posix_lstat_with_gfid (xlator_t *this, const char *path, struct iatt *stbuf_p)
+posix_fdstat (xlator_t *this, int fd, struct iatt *stbuf_p)
{
int ret = 0;
- struct stat lstatbuf = {0, };
+ struct stat fstatbuf = {0, };
struct iatt stbuf = {0, };
- ret = lstat (path, &lstatbuf);
+ ret = fstat (fd, &fstatbuf);
if (ret == -1)
goto out;
- iatt_from_stat (&stbuf, &lstatbuf);
+ if (fstatbuf.st_nlink && !S_ISDIR (fstatbuf.st_mode))
+ fstatbuf.st_nlink--;
- ret = posix_fill_gfid_path (this, path, &stbuf);
+ iatt_from_stat (&stbuf, &fstatbuf);
+
+ ret = posix_fill_gfid_fd (this, fd, &stbuf);
if (ret)
gf_log_callingfn (this->name, GF_LOG_DEBUG, "failed to get gfid");
@@ -284,33 +287,105 @@ posix_lstat_with_gfid (xlator_t *this, const char *path, struct iatt *stbuf_p)
if (stbuf_p)
*stbuf_p = stbuf;
+
out:
return ret;
}
int
-posix_fstat_with_gfid (xlator_t *this, int fd, struct iatt *stbuf_p)
+posix_istat (xlator_t *this, uuid_t gfid, const char *basename,
+ struct iatt *buf_p)
{
- int ret = 0;
- struct stat fstatbuf = {0, };
- struct iatt stbuf = {0, };
+ char *real_path = NULL;
+ struct stat lstatbuf = {0, };
+ struct iatt stbuf = {0, };
+ int ret = 0;
+ struct posix_private *priv = NULL;
- ret = fstat (fd, &fstatbuf);
- if (ret == -1)
+
+ priv = this->private;
+
+ MAKE_HANDLE_PATH (real_path, this, gfid, basename);
+
+ ret = lstat (real_path, &lstatbuf);
+
+ if (ret == -1) {
+ if (errno != ENOENT && errno != ELOOP)
+ gf_log (this->name, GF_LOG_WARNING,
+ "lstat failed on %s (%s)",
+ real_path, strerror (errno));
goto out;
+ }
- iatt_from_stat (&stbuf, &fstatbuf);
+ if ((lstatbuf.st_ino == priv->handledir.st_ino) &&
+ (lstatbuf.st_dev == priv->handledir.st_dev)) {
+ errno = ENOENT;
+ return -1;
+ }
- ret = posix_fill_gfid_fd (this, fd, &stbuf);
- if (ret)
- gf_log_callingfn (this->name, GF_LOG_DEBUG, "failed to get gfid");
+ if (!S_ISDIR (lstatbuf.st_mode))
+ lstatbuf.st_nlink --;
+
+ iatt_from_stat (&stbuf, &lstatbuf);
+
+ if (basename)
+ posix_fill_gfid_path (this, real_path, &stbuf);
+ else
+ uuid_copy (stbuf.ia_gfid, gfid);
posix_fill_ino_from_gfid (this, &stbuf);
- if (stbuf_p)
- *stbuf_p = stbuf;
+ if (buf_p)
+ *buf_p = stbuf;
+out:
+ return ret;
+}
+
+
+int
+posix_pstat (xlator_t *this, uuid_t gfid, const char *path,
+ struct iatt *buf_p)
+{
+ struct stat lstatbuf = {0, };
+ struct iatt stbuf = {0, };
+ int ret = 0;
+ struct posix_private *priv = NULL;
+
+
+ priv = this->private;
+
+ ret = lstat (path, &lstatbuf);
+
+ if (ret == -1) {
+ if (errno != ENOENT)
+ gf_log (this->name, GF_LOG_WARNING,
+ "lstat failed on %s (%s)",
+ path, strerror (errno));
+ goto out;
+ }
+
+ if ((lstatbuf.st_ino == priv->handledir.st_ino) &&
+ (lstatbuf.st_dev == priv->handledir.st_dev)) {
+ errno = ENOENT;
+ return -1;
+ }
+
+ if (!S_ISDIR (lstatbuf.st_mode))
+ lstatbuf.st_nlink --;
+
+ iatt_from_stat (&stbuf, &lstatbuf);
+
+ if (gfid && !uuid_is_null (gfid))
+ uuid_copy (stbuf.ia_gfid, gfid);
+ else
+ posix_fill_gfid_path (this, path, &stbuf);
+
+ posix_fill_ino_from_gfid (this, &stbuf);
+
+ if (buf_p)
+ *buf_p = stbuf;
out:
return ret;
}
@@ -340,63 +415,15 @@ out:
}
-/*
- * If the parent directory of {real_path} has the setgid bit set,
- * then set {gid} to the gid of the parent. Otherwise,
- * leave {gid} unchanged.
- */
-
-int
-setgid_override (xlator_t *this, char *real_path, gid_t *gid)
-{
- char * tmp_path = NULL;
- char * parent_path = NULL;
- struct iatt parent_stbuf;
-
- int op_ret = 0;
-
- tmp_path = gf_strdup (real_path);
- if (!tmp_path) {
- op_ret = -ENOMEM;
- goto out;
- }
-
- parent_path = dirname (tmp_path);
-
- op_ret = posix_lstat_with_gfid (this, parent_path, &parent_stbuf);
- if (op_ret == -1) {
- op_ret = -errno;
- gf_log_callingfn (this->name, GF_LOG_ERROR,
- "lstat on parent directory (%s) failed: %s",
- parent_path, strerror (errno));
- goto out;
- }
-
- if (parent_stbuf.ia_prot.sgid) {
- /*
- * Entries created inside a setgid directory
- * should inherit the gid from the parent
- */
-
- *gid = parent_stbuf.ia_gid;
- }
-out:
-
- if (tmp_path)
- GF_FREE (tmp_path);
-
- return op_ret;
-}
-
-
int
-posix_gfid_set (xlator_t *this, const char *path, dict_t *xattr_req)
+posix_gfid_set (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req)
{
void *uuid_req = NULL;
uuid_t uuid_curr;
int ret = 0;
struct stat stat = {0, };
+
if (!xattr_req)
goto out;
@@ -406,17 +433,31 @@ posix_gfid_set (xlator_t *this, const char *path, dict_t *xattr_req)
ret = sys_lgetxattr (path, GFID_XATTR_KEY, uuid_curr, 16);
if (ret == 16) {
ret = 0;
- goto out;
+ goto verify_handle;
}
ret = dict_get_ptr (xattr_req, "gfid-req", &uuid_req);
if (ret) {
- gf_log_callingfn (this->name, GF_LOG_DEBUG,
- "failed to get the gfid from dict");
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get the gfid from dict for %s",
+ loc->path);
goto out;
}
ret = sys_lsetxattr (path, GFID_XATTR_KEY, uuid_req, 16, XATTR_CREATE);
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_WARNING,
+ "setting GFID on %s failed (%s)", path,
+ strerror (errno));
+ goto out;
+ }
+ uuid_copy (uuid_curr, uuid_req);
+
+verify_handle:
+ if (!S_ISDIR (stat.st_mode))
+ ret = posix_handle_hard (this, path, uuid_curr, &stat);
+ else
+ ret = posix_handle_soft (this, path, loc, uuid_curr, &stat);
out:
return ret;
@@ -424,22 +465,26 @@ out:
int
-posix_set_file_contents (xlator_t *this, const char *real_path,
- data_pair_t *trav, int flags)
+posix_set_file_contents (xlator_t *this, const char *path, data_pair_t *trav,
+ int flags)
{
char * key = NULL;
- char real_filepath[ZR_PATH_MAX] = {0,};
+ char real_path[PATH_MAX];
int32_t file_fd = -1;
int op_ret = 0;
int ret = -1;
+
+ /* XXX: does not handle assigning GFID to created files */
+ return -1;
+
key = &(trav->key[15]);
- sprintf (real_filepath, "%s/%s", real_path, key);
+ sprintf (real_path, "%s/%s", path, key);
if (flags & XATTR_REPLACE) {
/* if file exists, replace it
* else, error out */
- file_fd = open (real_filepath, O_TRUNC|O_WRONLY);
+ file_fd = open (real_path, O_TRUNC|O_WRONLY);
if (file_fd == -1) {
goto create;
@@ -453,7 +498,7 @@ posix_set_file_contents (xlator_t *this, const char *real_path,
gf_log (this->name, GF_LOG_ERROR,
"write failed while doing setxattr "
"for key %s on path %s: %s",
- key, real_filepath, strerror (errno));
+ key, real_path, strerror (errno));
goto out;
}
@@ -462,14 +507,14 @@ posix_set_file_contents (xlator_t *this, const char *real_path,
op_ret = -errno;
gf_log (this->name, GF_LOG_ERROR,
"close failed on %s: %s",
- real_filepath, strerror (errno));
+ real_path, strerror (errno));
goto out;
}
}
create: /* we know file doesn't exist, create it */
- file_fd = open (real_filepath, O_CREAT|O_WRONLY, 0644);
+ file_fd = open (real_path, O_CREAT|O_WRONLY, 0644);
if (file_fd == -1) {
op_ret = -errno;
@@ -485,7 +530,7 @@ posix_set_file_contents (xlator_t *this, const char *real_path,
gf_log (this->name, GF_LOG_ERROR,
"write failed on %s while setxattr with "
"key %s: %s",
- real_filepath, key, strerror (errno));
+ real_path, key, strerror (errno));
goto out;
}
@@ -495,7 +540,7 @@ posix_set_file_contents (xlator_t *this, const char *real_path,
gf_log (this->name, GF_LOG_ERROR,
"close failed on %s while setxattr with "
"key %s: %s",
- real_filepath, key, strerror (errno));
+ real_path, key, strerror (errno));
goto out;
}
}
@@ -506,33 +551,32 @@ out:
int
-posix_get_file_contents (xlator_t *this, const char *real_path,
+posix_get_file_contents (xlator_t *this, uuid_t pargfid,
const char *name, char **contents)
{
- char real_filepath[ZR_PATH_MAX] = {0,};
- char * key = NULL;
+ char *real_path = NULL;
int32_t file_fd = -1;
struct iatt stbuf = {0,};
int op_ret = 0;
int ret = -1;
- key = (char *) &(name[15]);
- sprintf (real_filepath, "%s/%s", real_path, key);
- op_ret = posix_lstat_with_gfid (this, real_filepath, &stbuf);
+ MAKE_HANDLE_PATH (real_path, this, pargfid, name);
+
+ op_ret = posix_istat (this, pargfid, name, &stbuf);
if (op_ret == -1) {
op_ret = -errno;
gf_log (this->name, GF_LOG_ERROR, "lstat failed on %s: %s",
- real_filepath, strerror (errno));
+ real_path, strerror (errno));
goto out;
}
- file_fd = open (real_filepath, O_RDONLY);
+ file_fd = open (real_path, O_RDONLY);
if (file_fd == -1) {
op_ret = -errno;
gf_log (this->name, GF_LOG_ERROR, "open failed on %s: %s",
- real_filepath, strerror (errno));
+ real_path, strerror (errno));
goto out;
}
@@ -547,7 +591,7 @@ posix_get_file_contents (xlator_t *this, const char *real_path,
if (ret <= 0) {
op_ret = -1;
gf_log (this->name, GF_LOG_ERROR, "read on %s failed: %s",
- real_filepath, strerror (errno));
+ real_path, strerror (errno));
goto out;
}
@@ -558,7 +602,7 @@ posix_get_file_contents (xlator_t *this, const char *real_path,
if (op_ret == -1) {
op_ret = -errno;
gf_log (this->name, GF_LOG_ERROR, "close on %s failed: %s",
- real_filepath, strerror (errno));
+ real_path, strerror (errno));
goto out;
}
@@ -775,9 +819,6 @@ posix_janitor_thread_proc (void *data)
closedir (pfd->dir);
}
- if (pfd->path)
- GF_FREE (pfd->path);
-
GF_FREE (pfd);
}
}
@@ -882,3 +923,97 @@ posix_entry_create_xattr_set (xlator_t *this, const char *path,
out:
return ret;
}
+
+
+static int
+__posix_fd_ctx_get (fd_t *fd, xlator_t *this, struct posix_fd **pfd_p)
+{
+ uint64_t tmp_pfd = 0;
+ struct posix_fd *pfd = NULL;
+ int ret = -1;
+ char *real_path = NULL;
+ int _fd = -1;
+ DIR *dir = NULL;
+
+ ret = __fd_ctx_get (fd, this, &tmp_pfd);
+ if (ret == 0) {
+ pfd = (void *)(long) tmp_pfd;
+ ret = 0;
+ goto out;
+ }
+
+ if (fd->pid != -1)
+ /* anonymous fd */
+ goto out;
+
+ MAKE_HANDLE_PATH (real_path, this, fd->inode->gfid, NULL);
+
+ pfd = GF_CALLOC (1, sizeof (*pfd), gf_posix_mt_posix_fd);
+ if (!pfd) {
+ goto out;
+ }
+ pfd->fd = -1;
+
+ if (fd->inode->ia_type == IA_IFDIR) {
+ dir = opendir (real_path);
+ if (!dir) {
+ GF_FREE (pfd);
+ pfd = NULL;
+ goto out;
+ }
+ _fd = dirfd (dir);
+ }
+
+ if (fd->inode->ia_type == IA_IFREG) {
+ _fd = open (real_path, O_RDWR|O_LARGEFILE);
+ if (_fd == -1) {
+ GF_FREE (pfd);
+ pfd = NULL;
+ goto out;
+ }
+ }
+
+ pfd->fd = _fd;
+ pfd->dir = dir;
+
+ ret = __fd_ctx_set (fd, this, (uint64_t) (long) pfd);
+ if (ret != 0) {
+ if (_fd != -1)
+ close (_fd);
+ if (dir)
+ closedir (dir);
+ GF_FREE (pfd);
+ pfd = NULL;
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (pfd_p)
+ *pfd_p = pfd;
+ return ret;
+}
+
+
+int
+posix_fd_ctx_get (fd_t *fd, xlator_t *this, struct posix_fd **pfd)
+{
+ int ret;
+
+ LOCK (&fd->inode->lock);
+ {
+ ret = __posix_fd_ctx_get (fd, this, pfd);
+ }
+ UNLOCK (&fd->inode->lock);
+
+ return ret;
+}
+
+
+int
+posix_fd_ctx_get_off (fd_t *fd, xlator_t *this, struct posix_fd **pfd,
+ off_t offset)
+{
+ return posix_fd_ctx_get (fd, this, pfd);
+}
+
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index cf5d855fe..5257633ce 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -101,13 +101,12 @@ posix_lookup (call_frame_t *frame, xlator_t *this,
loc_t *loc, dict_t *xattr_req)
{
struct iatt buf = {0, };
- char * real_path = NULL;
int32_t op_ret = -1;
int32_t entry_ret = 0;
int32_t op_errno = 0;
dict_t * xattr = NULL;
- char * pathdup = NULL;
- char * parentpath = NULL;
+ char * real_path = NULL;
+ char * par_path = NULL;
struct iatt postparent = {0,};
VALIDATE_OR_GOTO (frame, out);
@@ -115,18 +114,23 @@ posix_lookup (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (loc, out);
VALIDATE_OR_GOTO (loc->path, out);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ if (uuid_is_null (loc->pargfid)) {
+ /* nameless lookup */
+ MAKE_INODE_HANDLE (real_path, this, loc, &buf);
+ } else {
+ MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &buf);
- posix_gfid_set (this, real_path, xattr_req);
+ if (uuid_is_null (loc->inode->gfid))
+ posix_gfid_set (this, real_path, loc, xattr_req);
+ }
- op_ret = posix_lstat_with_gfid (this, real_path, &buf);
op_errno = errno;
if (op_ret == -1) {
if (op_errno != ENOENT) {
gf_log (this->name, GF_LOG_ERROR,
"lstat on %s failed: %s",
- loc->path, strerror (op_errno));
+ real_path, strerror (op_errno));
}
entry_ret = -1;
@@ -139,27 +143,19 @@ posix_lookup (call_frame_t *frame, xlator_t *this,
}
parent:
- if (loc->parent) {
- pathdup = gf_strdup (real_path);
- GF_VALIDATE_OR_GOTO (this->name, pathdup, out);
-
- parentpath = dirname (pathdup);
-
- op_ret = posix_lstat_with_gfid (this, parentpath, &postparent);
+ if (par_path) {
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "post-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ "post-operation lstat on parent %s failed: %s",
+ par_path, strerror (op_errno));
goto out;
}
}
op_ret = entry_ret;
out:
- if (pathdup)
- GF_FREE (pathdup);
-
if (xattr)
dict_ref (xattr);
@@ -177,10 +173,10 @@ int32_t
posix_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
struct iatt buf = {0,};
- char * real_path = NULL;
int32_t op_ret = -1;
int32_t op_errno = 0;
struct posix_private *priv = NULL;
+ char *real_path = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -192,13 +188,13 @@ posix_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
VALIDATE_OR_GOTO (priv, out);
SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_REAL_PATH (real_path, this, loc->path);
- op_ret = posix_lstat_with_gfid (this, real_path, &buf);
+ MAKE_INODE_HANDLE (real_path, this, loc, &buf);
+
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "lstat on %s failed: %s", loc->path,
+ "lstat on %s failed: %s", real_path,
strerror (op_errno));
goto out;
}
@@ -328,9 +324,8 @@ posix_setattr (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (loc, out);
SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_INODE_HANDLE (real_path, this, loc, &statpre);
- op_ret = posix_lstat_with_gfid (this, real_path, &statpre);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -384,7 +379,7 @@ posix_setattr (call_frame_t *frame, xlator_t *this,
}
}
- op_ret = posix_lstat_with_gfid (this, real_path, &statpost);
+ op_ret = posix_pstat (this, loc->gfid, real_path, &statpost);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -456,7 +451,6 @@ posix_fsetattr (call_frame_t *frame, xlator_t *this,
struct iatt statpre = {0,};
struct iatt statpost = {0,};
struct posix_fd *pfd = NULL;
- uint64_t tmp_pfd = 0;
int32_t ret = -1;
DECLARE_OLD_FS_ID_VAR;
@@ -467,16 +461,15 @@ posix_fsetattr (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (fd, out);
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
op_errno = -ret;
gf_log (this->name, GF_LOG_DEBUG,
"pfd is NULL from fd=%p", fd);
goto out;
}
- pfd = (struct posix_fd *)(long)tmp_pfd;
- op_ret = posix_fstat_with_gfid (this, pfd->fd, &statpre);
+ op_ret = posix_fdstat (this, pfd->fd, &statpre);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -531,7 +524,7 @@ posix_fsetattr (call_frame_t *frame, xlator_t *this,
}
}
- op_ret = posix_fstat_with_gfid (this, pfd->fd, &statpost);
+ op_ret = posix_fdstat (this, pfd->fd, &statpost);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -570,7 +563,7 @@ posix_opendir (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (fd, out);
SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_INODE_HANDLE (real_path, this, loc, NULL);
dir = opendir (real_path);
@@ -578,7 +571,7 @@ posix_opendir (call_frame_t *frame, xlator_t *this,
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"opendir failed on %s: %s",
- loc->path, strerror (op_errno));
+ real_path, strerror (op_errno));
goto out;
}
@@ -587,7 +580,7 @@ posix_opendir (call_frame_t *frame, xlator_t *this,
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"dirfd() failed on %s: %s",
- loc->path, strerror (op_errno));
+ real_path, strerror (op_errno));
goto out;
}
@@ -599,16 +592,12 @@ posix_opendir (call_frame_t *frame, xlator_t *this,
pfd->dir = dir;
pfd->fd = dirfd (dir);
- pfd->path = gf_strdup (real_path);
- if (!pfd->path) {
- goto out;
- }
op_ret = fd_ctx_set (fd, this, (uint64_t)(long)pfd);
if (op_ret)
gf_log (this->name, GF_LOG_WARNING,
"failed to set the fd context path=%s fd=%p",
- loc->path, fd);
+ real_path, fd);
op_ret = 0;
@@ -619,8 +608,6 @@ out:
dir = NULL;
}
if (pfd) {
- if (pfd->path)
- GF_FREE (pfd->path);
GF_FREE (pfd);
pfd = NULL;
}
@@ -654,19 +641,12 @@ posix_releasedir (xlator_t *this,
pfd = (struct posix_fd *)(long)tmp_pfd;
if (!pfd->dir) {
gf_log (this->name, GF_LOG_WARNING,
- "pfd->dir is NULL for fd=%p path=%s",
- fd, pfd->path ? pfd->path : "<NULL>");
+ "pfd->dir is NULL for fd=%p", fd);
goto out;
}
priv = this->private;
- if (!pfd->path) {
- gf_log (this->name, GF_LOG_WARNING,
- "pfd->path was NULL. fd=%p pfd=%p",
- fd, pfd);
- }
-
pthread_mutex_lock (&priv->janitor_lock);
{
INIT_LIST_HEAD (&pfd->list);
@@ -686,7 +666,6 @@ posix_readlink (call_frame_t *frame, xlator_t *this,
{
char * dest = NULL;
int32_t op_ret = -1;
- int32_t lstat_ret = -1;
int32_t op_errno = 0;
char * real_path = NULL;
struct iatt stbuf = {0,};
@@ -699,29 +678,25 @@ posix_readlink (call_frame_t *frame, xlator_t *this,
dest = alloca (size + 1);
- MAKE_REAL_PATH (real_path, this, loc->path);
-
- op_ret = readlink (real_path, dest, size);
+ MAKE_INODE_HANDLE (real_path, this, loc, &stbuf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "readlink on %s failed: %s", loc->path,
+ "lstat on %s failed: %s", real_path,
strerror (op_errno));
goto out;
}
- dest[op_ret] = 0;
-
- lstat_ret = posix_lstat_with_gfid (this, real_path, &stbuf);
- if (lstat_ret == -1) {
- op_ret = -1;
+ op_ret = readlink (real_path, dest, size);
+ if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "lstat on %s failed: %s", loc->path,
+ "readlink on %s failed: %s", real_path,
strerror (op_errno));
goto out;
}
+ dest[op_ret] = 0;
out:
SET_TO_OLD_FS_ID ();
@@ -739,14 +714,13 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
int32_t op_ret = -1;
int32_t op_errno = 0;
char *real_path = 0;
+ char *par_path = 0;
struct iatt stbuf = { 0, };
char was_present = 1;
struct posix_private *priv = NULL;
gid_t gid = 0;
- char *pathdup = NULL;
struct iatt preparent = {0,};
struct iatt postparent = {0,};
- char *parentpath = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -757,32 +731,25 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
priv = this->private;
VALIDATE_OR_GOTO (priv, out);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, NULL);
gid = frame->root->gid;
- op_ret = setgid_override (this, real_path, &gid);
- if (op_ret < 0) {
- op_errno = -op_ret;
- op_ret = -1;
- goto out;
- }
-
SET_FS_ID (frame->root->uid, gid);
- pathdup = gf_strdup (real_path);
- GF_VALIDATE_OR_GOTO (this->name, pathdup, out);
- parentpath = dirname (pathdup);
-
- op_ret = posix_lstat_with_gfid (this, parentpath, &preparent);
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"pre-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ real_path, strerror (op_errno));
goto out;
}
+ if (preparent.ia_prot.sgid) {
+ gid = preparent.ia_gid;
+ }
+
#ifdef __NetBSD__
if (S_ISFIFO(mode))
op_ret = mkfifo (real_path, mode);
@@ -799,23 +766,23 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
if (tmp_fd == -1) {
gf_log (this->name, GF_LOG_ERROR,
"create failed on %s: %s",
- loc->path, strerror (errno));
+ real_path, strerror (errno));
goto out;
}
close (tmp_fd);
} else {
gf_log (this->name, GF_LOG_ERROR,
- "mknod on %s failed: %s", loc->path,
+ "mknod on %s failed: %s", real_path,
strerror (op_errno));
goto out;
}
}
- op_ret = posix_gfid_set (this, real_path, params);
+ op_ret = posix_gfid_set (this, real_path, loc, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting gfid on %s failed", loc->path);
+ "setting gfid on %s failed", real_path);
}
#ifndef HAVE_SET_FSID
@@ -823,7 +790,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "lchown on %s failed: %s", loc->path,
+ "lchown on %s failed: %s", real_path,
strerror (op_errno));
goto out;
}
@@ -832,41 +799,38 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
op_ret = posix_acl_xattr_set (this, real_path, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting ACLs on %s failed (%s)", loc->path,
+ "setting ACLs on %s failed (%s)", real_path,
strerror (errno));
}
op_ret = posix_entry_create_xattr_set (this, real_path, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting xattrs on %s failed (%s)", loc->path,
+ "setting xattrs on %s failed (%s)", real_path,
strerror (errno));
}
- op_ret = posix_lstat_with_gfid (this, real_path, &stbuf);
+ op_ret = posix_pstat (this, NULL, real_path, &stbuf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "mknod on %s failed: %s", loc->path,
+ "mknod on %s failed: %s", real_path,
strerror (op_errno));
goto out;
}
- op_ret = posix_lstat_with_gfid (this, parentpath, &postparent);
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "post-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ "post-operation lstat on parent %s failed: %s",
+ par_path, strerror (op_errno));
goto out;
}
op_ret = 0;
out:
- if (pathdup)
- GF_FREE (pathdup);
-
SET_TO_OLD_FS_ID ();
STACK_UNWIND_STRICT (mknod, frame, op_ret, op_errno,
@@ -879,6 +843,7 @@ out:
return 0;
}
+
int
posix_mkdir (call_frame_t *frame, xlator_t *this,
loc_t *loc, mode_t mode, dict_t *params)
@@ -886,12 +851,11 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,
int32_t op_ret = -1;
int32_t op_errno = 0;
char *real_path = NULL;
+ char *par_path = NULL;
struct iatt stbuf = {0, };
char was_present = 1;
struct posix_private *priv = NULL;
gid_t gid = 0;
- char *pathdup = NULL;
- char *parentpath = NULL;
struct iatt preparent = {0,};
struct iatt postparent = {0,};
@@ -904,51 +868,44 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,
priv = this->private;
VALIDATE_OR_GOTO (priv, out);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, NULL);
gid = frame->root->gid;
- op_ret = posix_lstat_with_gfid (this, real_path, &stbuf);
+ op_ret = posix_pstat (this, NULL, real_path, &stbuf);
if ((op_ret == -1) && (errno == ENOENT)) {
was_present = 0;
}
- op_ret = setgid_override (this, real_path, &gid);
- if (op_ret < 0) {
- op_errno = -op_ret;
- op_ret = -1;
- goto out;
- }
-
SET_FS_ID (frame->root->uid, gid);
- pathdup = gf_strdup (real_path);
- if (!pathdup)
- goto out;
-
- parentpath = dirname (pathdup);
- op_ret = posix_lstat_with_gfid (this, parentpath, &preparent);
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "pre-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ "pre-operation lstat on parent %s failed: %s",
+ par_path, strerror (op_errno));
goto out;
}
+ if (preparent.ia_prot.sgid) {
+ gid = preparent.ia_gid;
+ mode |= S_ISGID;
+ }
+
op_ret = mkdir (real_path, mode);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "mkdir of %s failed: %s", loc->path,
+ "mkdir of %s failed: %s", real_path,
strerror (op_errno));
goto out;
}
- op_ret = posix_gfid_set (this, real_path, params);
+ op_ret = posix_gfid_set (this, real_path, loc, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting gfid on %s failed", loc->path);
+ "setting gfid on %s failed", real_path);
}
#ifndef HAVE_SET_FSID
@@ -956,7 +913,7 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "chown on %s failed: %s", loc->path,
+ "chown on %s failed: %s", real_path,
strerror (op_errno));
goto out;
}
@@ -965,41 +922,38 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,
op_ret = posix_acl_xattr_set (this, real_path, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting ACLs on %s failed (%s)", loc->path,
+ "setting ACLs on %s failed (%s)", real_path,
strerror (errno));
}
op_ret = posix_entry_create_xattr_set (this, real_path, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting xattrs on %s failed (%s)", loc->path,
+ "setting xattrs on %s failed (%s)", real_path,
strerror (errno));
}
- op_ret = posix_lstat_with_gfid (this, real_path, &stbuf);
+ op_ret = posix_pstat (this, NULL, real_path, &stbuf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "lstat on %s failed: %s", loc->path,
+ "lstat on %s failed: %s", real_path,
strerror (op_errno));
goto out;
}
- op_ret = posix_lstat_with_gfid (this, parentpath, &postparent);
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"post-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ real_path, strerror (op_errno));
goto out;
}
op_ret = 0;
out:
- if (pathdup)
- GF_FREE (pathdup);
-
SET_TO_OLD_FS_ID ();
STACK_UNWIND_STRICT (mkdir, frame, op_ret, op_errno,
@@ -1020,9 +974,9 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
int32_t op_ret = -1;
int32_t op_errno = 0;
char *real_path = NULL;
- char *pathdup = NULL;
- char *parentpath = NULL;
+ char *par_path = NULL;
int32_t fd = -1;
+ struct iatt stbuf;
struct posix_private *priv = NULL;
struct iatt preparent = {0,};
struct iatt postparent = {0,};
@@ -1034,23 +988,20 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (loc, out);
SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_REAL_PATH (real_path, this, loc->path);
-
- pathdup = gf_strdup (real_path);
- if (!pathdup)
- goto out;
-
- parentpath = dirname (pathdup);
+ MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf);
- op_ret = posix_lstat_with_gfid (this, parentpath, &preparent);
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "pre-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ "pre-operation lstat on parent %s failed: %s",
+ par_path, strerror (op_errno));
goto out;
}
+ if (stbuf.ia_nlink == 1)
+ posix_handle_unset (this, stbuf.ia_gfid, NULL);
+
priv = this->private;
if (priv->background_unlink) {
if (IA_ISREG (loc->inode->ia_type)) {
@@ -1059,7 +1010,7 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
op_ret = -1;
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "open of %s failed: %s", loc->path,
+ "open of %s failed: %s", real_path,
strerror (op_errno));
goto out;
}
@@ -1070,26 +1021,23 @@ posix_unlink (call_frame_t *frame, xlator_t *this,
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "unlink of %s failed: %s", loc->path,
+ "unlink of %s failed: %s", real_path,
strerror (op_errno));
goto out;
}
- op_ret = posix_lstat_with_gfid (this, parentpath, &postparent);
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "post-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ "post-operation lstat on parent %s failed: %s",
+ par_path, strerror (op_errno));
goto out;
}
op_ret = 0;
out:
- if (pathdup)
- GF_FREE (pathdup);
-
SET_TO_OLD_FS_ID ();
STACK_UNWIND_STRICT (unlink, frame, op_ret, op_errno,
@@ -1110,10 +1058,10 @@ posix_rmdir (call_frame_t *frame, xlator_t *this,
int32_t op_ret = -1;
int32_t op_errno = 0;
char * real_path = NULL;
- char * pathdup = NULL;
- char * parentpath = NULL;
+ char * par_path = NULL;
struct iatt preparent = {0,};
struct iatt postparent = {0,};
+ struct iatt stbuf;
struct posix_private *priv = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -1125,20 +1073,14 @@ posix_rmdir (call_frame_t *frame, xlator_t *this,
priv = this->private;
SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_REAL_PATH (real_path, this, loc->path);
-
- pathdup = gf_strdup (real_path);
- if (!pathdup)
- goto out;
-
- parentpath = dirname (pathdup);
+ MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf);
- op_ret = posix_lstat_with_gfid (this, parentpath, &preparent);
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "pre-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ "pre-operation lstat on parent %s failed: %s",
+ par_path, strerror (op_errno));
goto out;
}
@@ -1155,6 +1097,10 @@ posix_rmdir (call_frame_t *frame, xlator_t *this,
}
op_errno = errno;
+ if (op_ret == 0) {
+ posix_handle_unset (this, stbuf.ia_gfid, NULL);
+ }
+
if (op_errno == EEXIST)
/* Solaris sets errno = EEXIST instead of ENOTEMPTY */
op_errno = ENOTEMPTY;
@@ -1162,7 +1108,7 @@ posix_rmdir (call_frame_t *frame, xlator_t *this,
/* No need to log a common error as ENOTEMPTY */
if (op_ret == -1 && op_errno != ENOTEMPTY) {
gf_log (this->name, GF_LOG_ERROR,
- "rmdir of %s failed: %s", loc->path,
+ "rmdir of %s failed: %s", real_path,
strerror (op_errno));
}
@@ -1170,23 +1116,20 @@ posix_rmdir (call_frame_t *frame, xlator_t *this,
gf_log (this->name,
(op_errno == ENOTEMPTY) ? GF_LOG_DEBUG : GF_LOG_ERROR,
"%s on %s failed", (flags) ? "rename" : "rmdir",
- loc->path);
+ real_path);
goto out;
}
- op_ret = posix_lstat_with_gfid (this, parentpath, &postparent);
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"post-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ par_path, strerror (op_errno));
goto out;
}
out:
- if (pathdup)
- GF_FREE (pathdup);
-
SET_TO_OLD_FS_ID ();
STACK_UNWIND_STRICT (rmdir, frame, op_ret, op_errno,
@@ -1203,12 +1146,11 @@ posix_symlink (call_frame_t *frame, xlator_t *this,
int32_t op_ret = -1;
int32_t op_errno = 0;
char * real_path = 0;
+ char * par_path = 0;
struct iatt stbuf = { 0, };
struct posix_private *priv = NULL;
gid_t gid = 0;
char was_present = 1;
- char *pathdup = NULL;
- char *parentpath = NULL;
struct iatt preparent = {0,};
struct iatt postparent = {0,};
@@ -1222,52 +1164,43 @@ posix_symlink (call_frame_t *frame, xlator_t *this,
priv = this->private;
VALIDATE_OR_GOTO (priv, out);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf);
- op_ret = posix_lstat_with_gfid (this, real_path, &stbuf);
if ((op_ret == -1) && (errno == ENOENT)){
was_present = 0;
}
- gid = frame->root->gid;
-
- op_ret = setgid_override (this, real_path, &gid);
- if (op_ret < 0) {
- op_errno = -op_ret;
- op_ret = -1;
- goto out;
- }
-
SET_FS_ID (frame->root->uid, gid);
- pathdup = gf_strdup (real_path);
- if (!pathdup)
- goto out;
- parentpath = dirname (pathdup);
+ gid = frame->root->gid;
- op_ret = posix_lstat_with_gfid (this, parentpath, &preparent);
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "pre-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ "pre-operation lstat on parent %s failed: %s",
+ par_path, strerror (op_errno));
goto out;
}
+ if (preparent.ia_prot.sgid) {
+ gid = preparent.ia_gid;
+ }
+
op_ret = symlink (linkname, real_path);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"symlink of %s --> %s failed: %s",
- loc->path, linkname, strerror (op_errno));
+ real_path, linkname, strerror (op_errno));
goto out;
}
- op_ret = posix_gfid_set (this, real_path, params);
+ op_ret = posix_gfid_set (this, real_path, loc, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting gfid on %s failed", loc->path);
+ "setting gfid on %s failed", real_path);
}
#ifndef HAVE_SET_FSID
@@ -1276,7 +1209,7 @@ posix_symlink (call_frame_t *frame, xlator_t *this,
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"lchown failed on %s: %s",
- loc->path, strerror (op_errno));
+ real_path, strerror (op_errno));
goto out;
}
#endif
@@ -1284,41 +1217,38 @@ posix_symlink (call_frame_t *frame, xlator_t *this,
op_ret = posix_acl_xattr_set (this, real_path, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting ACLs on %s failed (%s)", loc->path,
+ "setting ACLs on %s failed (%s)", real_path,
strerror (errno));
}
op_ret = posix_entry_create_xattr_set (this, real_path, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting xattrs on %s failed (%s)", loc->path,
+ "setting xattrs on %s failed (%s)", real_path,
strerror (errno));
}
- op_ret = posix_lstat_with_gfid (this, real_path, &stbuf);
+ op_ret = posix_pstat (this, NULL, real_path, &stbuf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"lstat failed on %s: %s",
- loc->path, strerror (op_errno));
+ real_path, strerror (op_errno));
goto out;
}
- op_ret = posix_lstat_with_gfid (this, parentpath, &postparent);
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "post-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ "post-operation lstat on parent %s failed: %s",
+ par_path, strerror (op_errno));
goto out;
}
op_ret = 0;
out:
- if (pathdup)
- GF_FREE (pathdup);
-
SET_TO_OLD_FS_ID ();
STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno,
@@ -1340,19 +1270,20 @@ posix_rename (call_frame_t *frame, xlator_t *this,
int32_t op_errno = 0;
char *real_oldpath = NULL;
char *real_newpath = NULL;
+ char *par_oldpath = NULL;
+ char *par_newpath = NULL;
struct iatt stbuf = {0, };
struct posix_private *priv = NULL;
char was_present = 1;
- char *oldpathdup = NULL;
- char *oldparentpath = NULL;
- char *newpathdup = NULL;
- char *newparentpath = NULL;
struct iatt preoldparent = {0, };
struct iatt postoldparent = {0, };
struct iatt prenewparent = {0, };
struct iatt postnewparent = {0, };
char olddirid[64];
char newdirid[64];
+ uuid_t victim;
+ int was_dir;
+ int nlink;
DECLARE_OLD_FS_ID_VAR;
@@ -1365,42 +1296,35 @@ posix_rename (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (priv, out);
SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_REAL_PATH (real_oldpath, this, oldloc->path);
- MAKE_REAL_PATH (real_newpath, this, newloc->path);
-
- oldpathdup = gf_strdup (real_oldpath);
- if (!oldpathdup)
- goto out;
+ MAKE_ENTRY_HANDLE (real_oldpath, par_oldpath, this, oldloc, NULL);
+ MAKE_ENTRY_HANDLE (real_newpath, par_newpath, this, newloc, &stbuf);
- oldparentpath = dirname (oldpathdup);
-
- op_ret = posix_lstat_with_gfid (this, oldparentpath, &preoldparent);
+ op_ret = posix_pstat (this, oldloc->pargfid, par_oldpath, &preoldparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "pre-operation lstat on parent of %s failed: %s",
- oldloc->path, strerror (op_errno));
+ "pre-operation lstat on parent %s failed: %s",
+ par_oldpath, strerror (op_errno));
goto out;
}
- newpathdup = gf_strdup (real_newpath);
- if (!newpathdup)
- goto out;
-
- newparentpath = dirname (newpathdup);
-
- op_ret = posix_lstat_with_gfid (this, newparentpath, &prenewparent);
+ op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &prenewparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"pre-operation lstat on parent of %s failed: %s",
- newloc->path, strerror (op_errno));
+ par_newpath, strerror (op_errno));
goto out;
}
- op_ret = posix_lstat_with_gfid (this, real_newpath, &stbuf);
+ op_ret = posix_pstat (this, NULL, real_newpath, &stbuf);
if ((op_ret == -1) && (errno == ENOENT)){
was_present = 0;
+ } else {
+ uuid_copy (victim, stbuf.ia_gfid);
+ if (IA_ISDIR (stbuf.ia_type))
+ was_dir = 1;
+ nlink = stbuf.ia_nlink;
}
if (was_present && IA_ISDIR(stbuf.ia_type) && !newloc->inode) {
@@ -1424,17 +1348,32 @@ posix_rename (call_frame_t *frame, xlator_t *this,
goto out;
}
+ if (IA_ISDIR (oldloc->inode->ia_type)) {
+ posix_handle_unset (this, oldloc->inode->gfid, NULL);
+ }
+
op_ret = sys_rename (real_oldpath, real_newpath);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name,
(op_errno == ENOTEMPTY ? GF_LOG_DEBUG : GF_LOG_ERROR),
"rename of %s to %s failed: %s",
- oldloc->path, newloc->path, strerror (op_errno));
+ real_oldpath, real_newpath, strerror (op_errno));
goto out;
}
- op_ret = posix_lstat_with_gfid (this, real_newpath, &stbuf);
+ if (was_dir)
+ posix_handle_unset (this, victim, NULL);
+
+ if (was_present && !was_dir && nlink == 2)
+ posix_handle_unset (this, victim, NULL);
+
+ if (IA_ISDIR (oldloc->inode->ia_type)) {
+ posix_handle_soft (this, real_newpath, newloc,
+ oldloc->inode->gfid, NULL);
+ }
+
+ op_ret = posix_pstat (this, NULL, real_newpath, &stbuf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -1443,33 +1382,27 @@ posix_rename (call_frame_t *frame, xlator_t *this,
goto out;
}
- op_ret = posix_lstat_with_gfid (this, oldparentpath, &postoldparent);
+ op_ret = posix_pstat (this, oldloc->pargfid, par_oldpath, &postoldparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "post-operation lstat on parent of %s failed: %s",
- oldloc->path, strerror (op_errno));
+ "post-operation lstat on parent %s failed: %s",
+ par_oldpath, strerror (op_errno));
goto out;
}
- op_ret = posix_lstat_with_gfid (this, newparentpath, &postnewparent);
+ op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &postnewparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "post-operation lstat on parent of %s failed: %s",
- newloc->path, strerror (op_errno));
+ "post-operation lstat on parent %s failed: %s",
+ par_newpath, strerror (op_errno));
goto out;
}
op_ret = 0;
out:
- if (oldpathdup)
- GF_FREE (oldpathdup);
-
- if (newpathdup)
- GF_FREE (newpathdup);
-
SET_TO_OLD_FS_ID ();
@@ -1493,11 +1426,10 @@ posix_link (call_frame_t *frame, xlator_t *this,
int32_t op_errno = 0;
char *real_oldpath = 0;
char *real_newpath = 0;
+ char *par_newpath = 0;
struct iatt stbuf = {0, };
struct posix_private *priv = NULL;
char was_present = 1;
- char *newpathdup = NULL;
- char *newparentpath = NULL;
struct iatt preparent = {0,};
struct iatt postparent = {0,};
@@ -1512,26 +1444,18 @@ posix_link (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (priv, out);
SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_REAL_PATH (real_oldpath, this, oldloc->path);
- MAKE_REAL_PATH (real_newpath, this, newloc->path);
+ MAKE_INODE_HANDLE (real_oldpath, this, oldloc, &stbuf);
- op_ret = posix_lstat_with_gfid (this, real_newpath, &stbuf);
+ MAKE_ENTRY_HANDLE (real_newpath, par_newpath, this, newloc, &stbuf);
if ((op_ret == -1) && (errno == ENOENT)) {
was_present = 0;
}
- newpathdup = gf_strdup (real_newpath);
- if (!newpathdup) {
- op_errno = ENOMEM;
- goto out;
- }
-
- newparentpath = dirname (newpathdup);
- op_ret = posix_lstat_with_gfid (this, newparentpath, &preparent);
+ op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &preparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR, "lstat failed: %s: %s",
- newparentpath, strerror (op_errno));
+ par_newpath, strerror (op_errno));
goto out;
}
@@ -1551,11 +1475,11 @@ posix_link (call_frame_t *frame, xlator_t *this,
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"link %s to %s failed: %s",
- oldloc->path, newloc->path, strerror (op_errno));
+ real_oldpath, real_newpath, strerror (op_errno));
goto out;
}
- op_ret = posix_lstat_with_gfid (this, real_newpath, &stbuf);
+ op_ret = posix_pstat (this, NULL, real_newpath, &stbuf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -1564,19 +1488,17 @@ posix_link (call_frame_t *frame, xlator_t *this,
goto out;
}
- op_ret = posix_lstat_with_gfid (this, newparentpath, &postparent);
+ op_ret = posix_pstat (this, newloc->pargfid, par_newpath, &postparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR, "lstat failed: %s: %s",
- newparentpath, strerror (op_errno));
+ par_newpath, strerror (op_errno));
goto out;
}
op_ret = 0;
out:
- if (newpathdup)
- GF_FREE (newpathdup);
SET_TO_OLD_FS_ID ();
STACK_UNWIND_STRICT (link, frame, op_ret, op_errno,
@@ -1611,14 +1533,13 @@ posix_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
VALIDATE_OR_GOTO (priv, out);
SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_REAL_PATH (real_path, this, loc->path);
- op_ret = posix_lstat_with_gfid (this, real_path, &prebuf);
+ MAKE_INODE_HANDLE (real_path, this, loc, &prebuf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"pre-operation lstat on %s failed: %s",
- loc->path, strerror (op_errno));
+ real_path, strerror (op_errno));
goto out;
}
@@ -1627,11 +1548,11 @@ posix_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
"truncate on %s failed: %s",
- loc->path, strerror (op_errno));
+ real_path, strerror (op_errno));
goto out;
}
- op_ret = posix_lstat_with_gfid (this, real_path, &postbuf);
+ op_ret = posix_pstat (this, loc->gfid, real_path, &postbuf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR, "lstat on %s failed: %s",
@@ -1651,7 +1572,7 @@ out:
}
-int32_t
+int
posix_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
fd_t *fd, dict_t *params)
@@ -1661,14 +1582,13 @@ posix_create (call_frame_t *frame, xlator_t *this,
int32_t _fd = -1;
int _flags = 0;
char * real_path = NULL;
+ char * par_path = NULL;
struct iatt stbuf = {0, };
struct posix_fd * pfd = NULL;
struct posix_private * priv = NULL;
char was_present = 1;
gid_t gid = 0;
- char *pathdup = NULL;
- char *parentpath = NULL;
struct iatt preparent = {0,};
struct iatt postparent = {0,};
@@ -1683,33 +1603,25 @@ posix_create (call_frame_t *frame, xlator_t *this,
priv = this->private;
VALIDATE_OR_GOTO (priv, out);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf);
gid = frame->root->gid;
- op_ret = setgid_override (this, real_path, &gid);
- if (op_ret < 0) {
- op_errno = -op_ret;
- op_ret = -1;
- goto out;
- }
-
SET_FS_ID (frame->root->uid, gid);
- pathdup = gf_strdup (real_path);
- if (!pathdup)
- goto out;
-
- parentpath = dirname (pathdup);
- op_ret = posix_lstat_with_gfid (this, parentpath, &preparent);
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &preparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "pre-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ "pre-operation lstat on parent %s failed: %s",
+ par_path, strerror (op_errno));
goto out;
}
+ if (preparent.ia_prot.sgid) {
+ gid = preparent.ia_gid;
+ }
+
if (!flags) {
_flags = O_CREAT | O_RDWR | O_EXCL;
}
@@ -1717,7 +1629,7 @@ posix_create (call_frame_t *frame, xlator_t *this,
_flags = flags | O_CREAT;
}
- op_ret = posix_lstat_with_gfid (this, real_path, &stbuf);
+ op_ret = posix_pstat (this, NULL, real_path, &stbuf);
if ((op_ret == -1) && (errno == ENOENT)) {
was_present = 0;
}
@@ -1731,15 +1643,15 @@ posix_create (call_frame_t *frame, xlator_t *this,
op_errno = errno;
op_ret = -1;
gf_log (this->name, GF_LOG_ERROR,
- "open on %s failed: %s", loc->path,
+ "open on %s failed: %s", real_path,
strerror (op_errno));
goto out;
}
- op_ret = posix_gfid_set (this, real_path, params);
+ op_ret = posix_gfid_set (this, real_path, loc, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting gfid on %s failed", loc->path);
+ "setting gfid on %s failed", real_path);
}
#ifndef HAVE_SET_FSID
@@ -1755,18 +1667,18 @@ posix_create (call_frame_t *frame, xlator_t *this,
op_ret = posix_acl_xattr_set (this, real_path, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting ACLs on %s failed (%s)", loc->path,
+ "setting ACLs on %s failed (%s)", real_path,
strerror (errno));
}
op_ret = posix_entry_create_xattr_set (this, real_path, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,
- "setting xattrs on %s failed (%s)", loc->path,
+ "setting xattrs on %s failed (%s)", real_path,
strerror (errno));
}
- op_ret = posix_fstat_with_gfid (this, _fd, &stbuf);
+ op_ret = posix_fdstat (this, _fd, &stbuf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -1774,12 +1686,12 @@ posix_create (call_frame_t *frame, xlator_t *this,
goto out;
}
- op_ret = posix_lstat_with_gfid (this, parentpath, &postparent);
+ op_ret = posix_pstat (this, loc->pargfid, par_path, &postparent);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
- "post-operation lstat on parent of %s failed: %s",
- loc->path, strerror (op_errno));
+ "post-operation lstat on parent %s failed: %s",
+ par_path, strerror (op_errno));
goto out;
}
@@ -1797,7 +1709,7 @@ posix_create (call_frame_t *frame, xlator_t *this,
if (op_ret)
gf_log (this->name, GF_LOG_WARNING,
"failed to set the fd context path=%s fd=%p",
- loc->path, fd);
+ real_path, fd);
LOCK (&priv->lock);
{
@@ -1808,8 +1720,6 @@ posix_create (call_frame_t *frame, xlator_t *this,
op_ret = 0;
out:
- if (pathdup)
- GF_FREE (pathdup);
SET_TO_OLD_FS_ID ();
if ((-1 == op_ret) && (_fd != -1)) {
@@ -1837,7 +1747,6 @@ posix_open (call_frame_t *frame, xlator_t *this,
int32_t _fd = -1;
struct posix_fd *pfd = NULL;
struct posix_private *priv = NULL;
- gid_t gid = 0;
struct iatt stbuf = {0, };
DECLARE_OLD_FS_ID_VAR;
@@ -1851,22 +1760,13 @@ posix_open (call_frame_t *frame, xlator_t *this,
priv = this->private;
VALIDATE_OR_GOTO (priv, out);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_INODE_HANDLE (real_path, this, loc, &stbuf);
- op_ret = setgid_override (this, real_path, &gid);
- if (op_ret < 0) {
- op_errno = -op_ret;
- op_ret = -1;
- goto out;
- }
-
- SET_FS_ID (frame->root->uid, gid);
+ SET_FS_ID (frame->root->uid, frame->root->gid);
if (priv->o_direct)
flags |= O_DIRECT;
- op_ret = posix_lstat_with_gfid (this, real_path, &stbuf);
-
_fd = open (real_path, flags, 0);
if (_fd == -1) {
op_ret = -1;
@@ -1891,30 +1791,7 @@ posix_open (call_frame_t *frame, xlator_t *this,
if (op_ret)
gf_log (this->name, GF_LOG_WARNING,
"failed to set the fd context path=%s fd=%p",
- loc->path, fd);
-
-#ifndef HAVE_SET_FSID
- if (flags & O_CREAT) {
- op_ret = chown (real_path, frame->root->uid, gid);
- if (op_ret == -1) {
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR,
- "chown on %s failed: %s",
- real_path, strerror (op_errno));
- goto out;
- }
- }
-#endif
-
- if (flags & O_CREAT) {
- op_ret = posix_lstat_with_gfid (this, real_path, &stbuf);
- if (op_ret == -1) {
- op_errno = errno;
- gf_log (this->name, GF_LOG_ERROR, "lstat on (%s) "
- "failed: %s", real_path, strerror (op_errno));
- goto out;
- }
- }
+ real_path, fd);
LOCK (&priv->lock);
{
@@ -1945,7 +1822,6 @@ int
posix_readv (call_frame_t *frame, xlator_t *this,
fd_t *fd, size_t size, off_t offset)
{
- uint64_t tmp_pfd = 0;
int32_t op_ret = -1;
int32_t op_errno = 0;
int _fd = -1;
@@ -1965,14 +1841,13 @@ posix_readv (call_frame_t *frame, xlator_t *this,
priv = this->private;
VALIDATE_OR_GOTO (priv, out);
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
op_errno = -ret;
gf_log (this->name, GF_LOG_WARNING,
"pfd is NULL from fd=%p", fd);
goto out;
}
- pfd = (struct posix_fd *)(long)tmp_pfd;
if (!size) {
op_errno = EINVAL;
@@ -2014,7 +1889,7 @@ posix_readv (call_frame_t *frame, xlator_t *this,
* we read from
*/
- op_ret = posix_fstat_with_gfid (this, _fd, &stbuf);
+ op_ret = posix_fdstat (this, _fd, &stbuf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -2142,7 +2017,6 @@ posix_writev (call_frame_t *frame, xlator_t *this,
struct iatt postop = {0,};
int ret = -1;
- uint64_t tmp_pfd = 0;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -2154,18 +2028,17 @@ posix_writev (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (priv, out);
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
gf_log (this->name, GF_LOG_WARNING,
"pfd is NULL from fd=%p", fd);
op_errno = -ret;
goto out;
}
- pfd = (struct posix_fd *)(long)tmp_pfd;
_fd = pfd->fd;
- op_ret = posix_fstat_with_gfid (this, _fd, &preop);
+ op_ret = posix_fdstat (this, _fd, &preop);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -2201,7 +2074,7 @@ posix_writev (call_frame_t *frame, xlator_t *this,
fsync (_fd);
}
- ret = posix_fstat_with_gfid (this, _fd, &postop);
+ ret = posix_fdstat (this, _fd, &postop);
if (ret == -1) {
op_ret = -1;
op_errno = errno;
@@ -2235,7 +2108,7 @@ posix_statfs (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (loc, out);
VALIDATE_OR_GOTO (this->private, out);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_INODE_HANDLE (real_path, this, loc, NULL);
priv = this->private;
@@ -2273,13 +2146,13 @@ posix_flush (call_frame_t *frame, xlator_t *this,
int32_t op_ret = -1;
int32_t op_errno = 0;
int ret = -1;
- uint64_t tmp_pfd = 0;
+ struct posix_fd *pfd = NULL;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (fd, out);
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
op_errno = -ret;
gf_log (this->name, GF_LOG_WARNING,
@@ -2310,7 +2183,7 @@ posix_release (xlator_t *this,
priv = this->private;
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = fd_ctx_del (fd, this, &tmp_pfd);
if (ret < 0) {
gf_log (this->name, GF_LOG_WARNING,
"pfd is NULL from fd=%p", fd);
@@ -2352,7 +2225,6 @@ posix_fsync (call_frame_t *frame, xlator_t *this,
int _fd = -1;
struct posix_fd * pfd = NULL;
int ret = -1;
- uint64_t tmp_pfd = 0;
struct iatt preop = {0,};
struct iatt postop = {0,};
@@ -2370,18 +2242,17 @@ posix_fsync (call_frame_t *frame, xlator_t *this,
goto out;
#endif
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
op_errno = -ret;
gf_log (this->name, GF_LOG_WARNING,
"pfd not found in fd's ctx");
goto out;
}
- pfd = (struct posix_fd *)(long)tmp_pfd;
_fd = pfd->fd;
- op_ret = posix_fstat_with_gfid (this, _fd, &preop);
+ op_ret = posix_fdstat (this, _fd, &preop);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_WARNING,
@@ -2411,7 +2282,7 @@ posix_fsync (call_frame_t *frame, xlator_t *this,
}
}
- op_ret = posix_fstat_with_gfid (this, _fd, &postop);
+ op_ret = posix_fdstat (this, _fd, &postop);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_WARNING,
@@ -2450,7 +2321,7 @@ posix_setxattr (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (loc, out);
VALIDATE_OR_GOTO (dict, out);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_INODE_HANDLE (real_path, this, loc, NULL);
dict_del (dict, GFID_XATTR_KEY);
@@ -2506,13 +2377,13 @@ posix_getxattr (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (loc, out);
SET_FS_ID (frame->root->uid, frame->root->gid);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_INODE_HANDLE (real_path, this, loc, NULL);
priv = this->private;
if (loc->inode && IA_ISDIR(loc->inode->ia_type) && name &&
ZR_FILE_CONTENT_REQUEST(name)) {
- ret = posix_get_file_contents (this, real_path, name,
+ ret = posix_get_file_contents (this, loc->gfid, &name[15],
&file_contents);
if (ret < 0) {
op_errno = -ret;
@@ -2677,7 +2548,6 @@ posix_fgetxattr (call_frame_t *frame, xlator_t *this,
{
int32_t op_ret = -1;
int32_t op_errno = ENOENT;
- uint64_t tmp_pfd = 0;
struct posix_fd * pfd = NULL;
int _fd = -1;
int32_t list_offset = 0;
@@ -2697,14 +2567,13 @@ posix_fgetxattr (call_frame_t *frame, xlator_t *this,
SET_FS_ID (frame->root->uid, frame->root->gid);
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
op_errno = -ret;
gf_log (this->name, GF_LOG_WARNING,
"pfd is NULL from fd=%p", fd);
goto out;
}
- pfd = (struct posix_fd *)(long)tmp_pfd;
_fd = pfd->fd;
@@ -2832,7 +2701,6 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this,
int32_t op_ret = -1;
int32_t op_errno = 0;
struct posix_fd * pfd = NULL;
- uint64_t tmp_pfd = 0;
int _fd = -1;
data_pair_t * trav = NULL;
int ret = -1;
@@ -2845,14 +2713,13 @@ posix_fsetxattr (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (fd, out);
VALIDATE_OR_GOTO (dict, out);
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
op_errno = -ret;
gf_log (this->name, GF_LOG_WARNING,
"pfd is NULL from fd=%p", fd);
goto out;
}
- pfd = (struct posix_fd *)(long)tmp_pfd;
_fd = pfd->fd;
dict_del (dict, GFID_XATTR_KEY);
@@ -2889,13 +2756,14 @@ posix_removexattr (call_frame_t *frame, xlator_t *this,
DECLARE_OLD_FS_ID_VAR;
+ MAKE_INODE_HANDLE (real_path, this, loc, NULL);
+
if (!strcmp (GFID_XATTR_KEY, name)) {
gf_log (this->name, GF_LOG_WARNING, "Remove xattr called"
- " on gfid for file %s", loc->path);
+ " on gfid for file %s", real_path);
goto out;
}
- MAKE_REAL_PATH (real_path, this, loc->path);
SET_FS_ID (frame->root->uid, frame->root->gid);
@@ -2904,7 +2772,7 @@ posix_removexattr (call_frame_t *frame, xlator_t *this,
op_errno = errno;
if (op_errno != ENOATTR && op_errno != EPERM)
gf_log (this->name, GF_LOG_ERROR,
- "removexattr on %s (for %s): %s", loc->path,
+ "removexattr on %s (for %s): %s", real_path,
name, strerror (op_errno));
goto out;
}
@@ -2926,13 +2794,13 @@ posix_fsyncdir (call_frame_t *frame, xlator_t *this,
int32_t op_ret = -1;
int32_t op_errno = 0;
int ret = -1;
- uint64_t tmp_pfd = 0;
+ struct posix_fd *pfd = NULL;
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (fd, out);
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
op_errno = -ret;
gf_log (this->name, GF_LOG_WARNING,
@@ -3006,7 +2874,6 @@ do_xattrop (call_frame_t *frame, xlator_t *this,
int ret = 0;
int _fd = -1;
- uint64_t tmp_pfd = 0;
struct posix_fd *pfd = NULL;
data_pair_t *trav = NULL;
@@ -3021,7 +2888,7 @@ do_xattrop (call_frame_t *frame, xlator_t *this,
trav = xattr->members_list;
if (fd) {
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
gf_log (this->name, GF_LOG_WARNING,
"failed to get pfd from fd=%p",
@@ -3030,15 +2897,14 @@ do_xattrop (call_frame_t *frame, xlator_t *this,
op_errno = EBADFD;
goto out;
}
- pfd = (struct posix_fd *)(long)tmp_pfd;
_fd = pfd->fd;
}
- if (loc && loc->path)
- MAKE_REAL_PATH (real_path, this, loc->path);
+ if (loc && !uuid_is_null (loc->gfid))
+ MAKE_INODE_HANDLE (real_path, this, loc, NULL);
- if (loc) {
- path = gf_strdup (loc->path);
+ if (real_path) {
+ path = gf_strdup (real_path);
inode = loc->inode;
} else if (fd) {
inode = fd->inode;
@@ -3207,13 +3073,13 @@ posix_access (call_frame_t *frame, xlator_t *this,
VALIDATE_OR_GOTO (this, out);
VALIDATE_OR_GOTO (loc, out);
- MAKE_REAL_PATH (real_path, this, loc->path);
+ MAKE_INODE_HANDLE (real_path, this, loc, NULL);
op_ret = access (real_path, mask & 07);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR, "access failed on %s: %s",
- loc->path, strerror (op_errno));
+ real_path, strerror (op_errno));
goto out;
}
op_ret = 0;
@@ -3237,7 +3103,6 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this,
struct iatt postop = {0,};
struct posix_fd *pfd = NULL;
int ret = -1;
- uint64_t tmp_pfd = 0;
struct posix_private *priv = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -3250,18 +3115,17 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this,
priv = this->private;
VALIDATE_OR_GOTO (priv, out);
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
gf_log (this->name, GF_LOG_WARNING,
"pfd is NULL, fd=%p", fd);
op_errno = -ret;
goto out;
}
- pfd = (struct posix_fd *)(long)tmp_pfd;
_fd = pfd->fd;
- op_ret = posix_fstat_with_gfid (this, _fd, &preop);
+ op_ret = posix_fdstat (this, _fd, &preop);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -3280,7 +3144,7 @@ posix_ftruncate (call_frame_t *frame, xlator_t *this,
goto out;
}
- op_ret = posix_fstat_with_gfid (this, _fd, &postop);
+ op_ret = posix_fdstat (this, _fd, &postop);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR,
@@ -3309,7 +3173,6 @@ posix_fstat (call_frame_t *frame, xlator_t *this,
int32_t op_errno = 0;
struct iatt buf = {0,};
struct posix_fd *pfd = NULL;
- uint64_t tmp_pfd = 0;
int ret = -1;
struct posix_private *priv = NULL;
@@ -3323,18 +3186,17 @@ posix_fstat (call_frame_t *frame, xlator_t *this,
priv = this->private;
VALIDATE_OR_GOTO (priv, out);
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
gf_log (this->name, GF_LOG_WARNING,
"pfd is NULL, fd=%p", fd);
op_errno = -ret;
goto out;
}
- pfd = (struct posix_fd *)(long)tmp_pfd;
_fd = pfd->fd;
- op_ret = posix_fstat_with_gfid (this, _fd, &buf);
+ op_ret = posix_fdstat (this, _fd, &buf);
if (op_ret == -1) {
op_errno = errno;
gf_log (this->name, GF_LOG_ERROR, "fstat failed on fd=%p: %s",
@@ -3425,18 +3287,17 @@ posix_fentrylk (call_frame_t *frame, xlator_t *this,
int
-__posix_fill_readdir (DIR *dir, off_t off, size_t size, gf_dirent_t *entries,
- const char *real_path, const char *base_path)
+posix_fill_readdir (fd_t *fd, DIR *dir, off_t off, size_t size,
+ gf_dirent_t *entries)
{
off_t in_case = -1;
size_t filled = 0;
- int ret = 0;
int count = 0;
+ char entrybuf[sizeof(struct dirent) + 256 + 8];
struct dirent *entry = NULL;
int32_t this_size = -1;
gf_dirent_t *this_entry = NULL;
- char hidden_path[PATH_MAX] = {0, };
- struct stat statbuf = {0, };
+ uuid_t rootgfid = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
if (!off) {
rewinddir (dir);
@@ -3455,7 +3316,8 @@ __posix_fill_readdir (DIR *dir, off_t off, size_t size, gf_dirent_t *entries,
}
errno = 0;
- entry = readdir (dir);
+ entry = NULL;
+ readdir_r (dir, (struct dirent *)entrybuf, &entry);
if (!entry) {
if (errno == EBADF) {
@@ -3467,7 +3329,7 @@ __posix_fill_readdir (DIR *dir, off_t off, size_t size, gf_dirent_t *entries,
break;
}
- if ((!strcmp (real_path, base_path))
+ if ((uuid_compare (fd->inode->gfid, rootgfid) == 0)
&& (!strcmp (entry->d_name, GF_REPLICATE_TRASH_DIR)))
continue;
@@ -3480,19 +3342,15 @@ __posix_fill_readdir (DIR *dir, off_t off, size_t size, gf_dirent_t *entries,
* when the cluster/dht xlator decides to distribute
* exended attribute backing file accross storage servers.
*/
- if ((!strcmp(real_path, base_path))
+ if ((uuid_compare (fd->inode->gfid, rootgfid) == 0)
&& (!strcmp(entry->d_name, ".attribute")))
continue;
#endif /* __NetBSD__ */
- if ((!strcmp (real_path, base_path))
+ if ((uuid_compare (fd->inode->gfid, rootgfid) == 0)
&& (!strncmp (GF_HIDDEN_PATH, entry->d_name,
strlen (GF_HIDDEN_PATH)))) {
- snprintf (hidden_path, PATH_MAX, "%s/%s", real_path,
- entry->d_name);
- ret = lstat (hidden_path, &statbuf);
- if (!ret && S_ISDIR (statbuf.st_mode))
- continue;
+ continue;
}
this_size = max (sizeof (gf_dirent_t),
@@ -3533,7 +3391,6 @@ int32_t
posix_do_readdir (call_frame_t *frame, xlator_t *this,
fd_t *fd, size_t size, off_t off, int whichop)
{
- uint64_t tmp_pfd = 0;
struct posix_fd *pfd = NULL;
DIR *dir = NULL;
int ret = -1;
@@ -3541,14 +3398,12 @@ posix_do_readdir (call_frame_t *frame, xlator_t *this,
int32_t op_ret = -1;
int32_t op_errno = 0;
gf_dirent_t entries;
- char *real_path = NULL;
- int real_path_len = -1;
- char *entry_path = NULL;
- int entry_path_len = -1;
struct iatt stbuf = {0, };
- char base_path[PATH_MAX] = {0,};
gf_dirent_t *tmp_entry = NULL;
-
+#ifdef IGNORE_READDIRP_ATTRS
+ uuid_t gfid;
+ ia_type_t entry_type = 0;
+#endif
VALIDATE_OR_GOTO (frame, out);
VALIDATE_OR_GOTO (this, out);
@@ -3556,38 +3411,13 @@ posix_do_readdir (call_frame_t *frame, xlator_t *this,
INIT_LIST_HEAD (&entries.list);
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
gf_log (this->name, GF_LOG_WARNING,
"pfd is NULL, fd=%p", fd);
op_errno = -ret;
goto out;
}
- pfd = (struct posix_fd *)(long)tmp_pfd;
- if (!pfd->path) {
- op_errno = EBADFD;
- gf_log (this->name, GF_LOG_WARNING,
- "pfd does not have path set (possibly file "
- "fd, fd=%p)", fd);
- goto out;
- }
-
- real_path = pfd->path;
- real_path_len = strlen (real_path);
-
- entry_path_len = real_path_len + NAME_MAX;
- entry_path = alloca (entry_path_len);
-
- strncpy(base_path, POSIX_BASE_PATH(this), sizeof(base_path));
- base_path[strlen(base_path)] = '/';
-
- if (!entry_path) {
- op_errno = errno;
- goto out;
- }
-
- strncpy (entry_path, real_path, entry_path_len);
- entry_path[real_path_len] = '/';
dir = pfd->dir;
@@ -3598,23 +3428,30 @@ posix_do_readdir (call_frame_t *frame, xlator_t *this,
goto out;
}
-
- LOCK (&fd->lock);
- {
- count = __posix_fill_readdir (dir, off, size, &entries,
- real_path, base_path);
-
- }
- UNLOCK (&fd->lock);
+ count = posix_fill_readdir (fd, dir, off, size, &entries);
/* pick ENOENT to indicate EOF */
op_errno = errno;
if (whichop == GF_FOP_READDIRP) {
list_for_each_entry (tmp_entry, &entries.list, list) {
- strcpy (entry_path + real_path_len + 1,
- tmp_entry->d_name);
- posix_lstat_with_gfid (this, entry_path, &stbuf);
+#ifdef IGNORE_READDIRP_ATTRS
+ ret = inode_grep_for_gfid (fd->inode->table, fd->inode,
+ tmp_entry->d_name, gfid,
+ &entry_type);
+ if (ret == 0) {
+ memset (&stbuf, 0, sizeof (stbuf));
+ uuid_copy (stbuf.ia_gfid, gfid);
+ posix_fill_ino_from_gfid (this, &stbuf);
+ stbuf.ia_type = entry_type;
+ } else {
+ posix_istat (this, fd->inode->gfid,
+ tmp_entry->d_name, &stbuf);
+ }
+#else
+ posix_istat (this, fd->inode->gfid,
+ tmp_entry->d_name, &stbuf);
+#endif
if (stbuf.ia_ino)
tmp_entry->d_ino = stbuf.ia_ino;
tmp_entry->d_stat = stbuf;
@@ -3690,7 +3527,6 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
char *buf = NULL;
int _fd = -1;
- uint64_t tmp_pfd = 0;
struct posix_fd *pfd = NULL;
@@ -3714,14 +3550,13 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
goto out;
}
- ret = fd_ctx_get (fd, this, &tmp_pfd);
+ ret = posix_fd_ctx_get (fd, this, &pfd);
if (ret < 0) {
gf_log (this->name, GF_LOG_WARNING,
"pfd is NULL, fd=%p", fd);
op_errno = -ret;
goto out;
}
- pfd = (struct posix_fd *)(long) tmp_pfd;
_fd = pfd->fd;
@@ -3809,6 +3644,7 @@ init (xlator_t *this)
uuid_t old_uuid = {0,};
uuid_t dict_uuid = {0,};
uuid_t gfid = {0,};
+ uuid_t rootgfid = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
dir_data = dict_get (this->options, "directory");
@@ -3949,6 +3785,16 @@ init (xlator_t *this)
"%s: failed to fetch gfid (%s)",
dir_data->data, strerror (errno));
goto out;
+ } else {
+ /* First time volume, set the GFID */
+ ret = sys_lsetxattr (dir_data->data, "trusted.gfid", rootgfid,
+ 16, XATTR_CREATE);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "%s: failed to set gfid (%s)",
+ dir_data->data, strerror (errno));
+ goto out;
+ }
}
op_ret = sys_lgetxattr (dir_data->data, "system.posix_acl_access",
@@ -4096,6 +3942,14 @@ init (xlator_t *this)
#endif
this->private = (void *)_private;
+ op_ret = posix_handle_init (this);
+ if (op_ret == -1) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Posix handle setup failed");
+ ret = -1;
+ goto out;
+ }
+
pthread_mutex_init (&_private->janitor_lock, NULL);
pthread_cond_init (&_private->janitor_cond, NULL);
INIT_LIST_HEAD (&_private->janitor_fds);
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
index 1733eadd1..c72adac9e 100644
--- a/xlators/storage/posix/src/posix.h
+++ b/xlators/storage/posix/src/posix.h
@@ -52,6 +52,8 @@
#include "compat.h"
#include "timer.h"
#include "posix-mem-types.h"
+#include "posix-handle.h"
+
/**
* posix_fd - internal structure common to file and directory fd's
@@ -60,9 +62,10 @@
struct posix_fd {
int fd; /* fd returned by the kernel */
int32_t flags; /* flags for open/creat */
- char * path; /* used by setdents/getdents */
DIR * dir; /* handle returned by the kernel */
int flushwrites;
+ int odirect;
+ int op_performed;
struct list_head list; /* to add to the janitor list */
};
@@ -102,12 +105,12 @@ struct posix_private {
gf_boolean_t o_direct; /* always open files in O_DIRECT mode */
-/*
+/*
decide whether posix_unlink does open (file), unlink (file), close (fd)
instead of just unlink (file). with the former approach there is no lockout
of access to parent directory during removal of very large files for the
entire duration of freeing of data blocks.
-*/
+*/
gf_boolean_t background_unlink;
/* janitor thread which cleans up /.trash (created by replicate) */
@@ -116,31 +119,30 @@ struct posix_private {
char * trash_path;
/* lock for brick dir */
DIR *mount_lock;
+
+ struct stat handledir;
+
};
#define POSIX_BASE_PATH(this) (((struct posix_private *)this->private)->base_path)
#define POSIX_BASE_PATH_LEN(this) (((struct posix_private *)this->private)->base_path_length)
-#define MAKE_REAL_PATH(var, this, path) do { \
- var = alloca (strlen (path) + POSIX_BASE_PATH_LEN(this) + 2); \
- strcpy (var, POSIX_BASE_PATH(this)); \
- strcpy (&var[POSIX_BASE_PATH_LEN(this)], path); \
- } while (0)
-
-
/* Helper functions */
-int setgid_override (xlator_t *this, char *real_path, gid_t *gid);
-int posix_gfid_set (xlator_t *this, const char *path, dict_t *xattr_req);
-int posix_fstat_with_gfid (xlator_t *this, int fd, struct iatt *stbuf_p);
-int posix_lstat_with_gfid (xlator_t *this, const char *path, struct iatt *buf);
+int posix_gfid_set (xlator_t *this, const char *path, loc_t *loc,
+ dict_t *xattr_req);
+int posix_fdstat (xlator_t *this, int fd, struct iatt *stbuf_p);
+int posix_istat (xlator_t *this, uuid_t gfid, const char *basename,
+ struct iatt *iatt);
+int posix_pstat (xlator_t *this, uuid_t gfid, const char *real_path,
+ struct iatt *iatt);
dict_t *posix_lookup_xattr_fill (xlator_t *this, const char *path,
loc_t *loc, dict_t *xattr, struct iatt *buf);
int posix_handle_pair (xlator_t *this, const char *real_path,
data_pair_t *trav, int flags);
int posix_fhandle_pair (xlator_t *this, int fd, data_pair_t *trav, int flags);
void posix_spawn_janitor_thread (xlator_t *this);
-int posix_get_file_contents (xlator_t *this, const char *path,
+int posix_get_file_contents (xlator_t *this, uuid_t pargfid,
const char *name, char **contents);
int posix_set_file_contents (xlator_t *this, const char *path,
data_pair_t *trav, int flags);
@@ -149,5 +151,9 @@ int posix_gfid_heal (xlator_t *this, const char *path, dict_t *xattr_req);
int posix_entry_create_xattr_set (xlator_t *this, const char *path,
dict_t *dict);
+int posix_fd_ctx_get (fd_t *fd, xlator_t *this, struct posix_fd **pfd);
+int posix_fd_ctx_get_off (fd_t *fd, xlator_t *this, struct posix_fd **pfd,
+ off_t off);
+void posix_fill_ino_from_gfid (xlator_t *this, struct iatt *buf);
#endif /* _POSIX_H */