summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/glusterfs.h2
-rw-r--r--xlators/cluster/dht/src/dht-linkfile.c5
-rw-r--r--xlators/storage/posix/src/posix-handle.c17
-rw-r--r--xlators/storage/posix/src/posix-handle.h3
-rw-r--r--xlators/storage/posix/src/posix.c20
5 files changed, 47 insertions, 0 deletions
diff --git a/libglusterfs/src/glusterfs.h b/libglusterfs/src/glusterfs.h
index 8360077ec..ccfdc11dc 100644
--- a/libglusterfs/src/glusterfs.h
+++ b/libglusterfs/src/glusterfs.h
@@ -84,6 +84,8 @@
#define GF_XATTR_LINKINFO_KEY "trusted.distribute.linkinfo"
#define GFID_XATTR_KEY "trusted.gfid"
+#define GLUSTERFS_INTERNAL_FOP_KEY "glusterfs-internal-fop"
+
#define ZR_FILE_CONTENT_STR "glusterfs.file."
#define ZR_FILE_CONTENT_STRLEN 15
diff --git a/xlators/cluster/dht/src/dht-linkfile.c b/xlators/cluster/dht/src/dht-linkfile.c
index 2186b064a..d8ce49ddf 100644
--- a/xlators/cluster/dht/src/dht-linkfile.c
+++ b/xlators/cluster/dht/src/dht-linkfile.c
@@ -74,6 +74,11 @@ dht_linkfile_create (call_frame_t *frame, fop_mknod_cbk_t linkfile_cbk,
"%s: gfid set failed", loc->path);
}
+ ret = dict_set_str (dict, GLUSTERFS_INTERNAL_FOP_KEY, "yes");
+ if (ret)
+ gf_log ("dht-linkfile", GF_LOG_INFO,
+ "%s: internal-fop set failed", loc->path);
+
ret = dict_set_str (dict, "trusted.glusterfs.dht.linkto",
tovol->name);
diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c
index b0693324d..9b6df445e 100644
--- a/xlators/storage/posix/src/posix-handle.c
+++ b/xlators/storage/posix/src/posix-handle.c
@@ -619,3 +619,20 @@ posix_handle_unset (xlator_t *this, uuid_t gfid, const char *basename)
return ret;
}
+
+int
+posix_create_link_if_gfid_exists (xlator_t *this, uuid_t gfid,
+ char *real_path)
+{
+ int ret = -1;
+ struct stat stbuf = {0,};
+ char *newpath = NULL;
+
+ MAKE_HANDLE_PATH (newpath, this, gfid, NULL);
+ ret = lstat (newpath, &stbuf);
+ if (!ret) {
+ ret = link (newpath, real_path);
+ }
+
+ return ret;
+}
diff --git a/xlators/storage/posix/src/posix-handle.h b/xlators/storage/posix/src/posix-handle.h
index b22149f63..a8fd9228a 100644
--- a/xlators/storage/posix/src/posix-handle.h
+++ b/xlators/storage/posix/src/posix-handle.h
@@ -145,4 +145,7 @@ int posix_handle_mkdir_hashes (xlator_t *this, const char *newpath);
int posix_handle_init (xlator_t *this);
+int posix_create_link_if_gfid_exists (xlator_t *this, uuid_t gfid,
+ char *real_path);
+
#endif /* !_POSIX_HANDLE_H */
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 24dd536e4..9e003a76a 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -722,6 +722,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
gid_t gid = 0;
struct iatt preparent = {0,};
struct iatt postparent = {0,};
+ void * uuid_req = NULL;
DECLARE_OLD_FS_ID_VAR;
@@ -751,6 +752,24 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
gid = preparent.ia_gid;
}
+ /* Check if the 'gfid' already exists, because this mknod may be an
+ internal call from distribute for creating 'linkfile', and that
+ linkfile may be for a hardlinked file */
+ if (dict_get (params, GLUSTERFS_INTERNAL_FOP_KEY)) {
+ op_ret = dict_get_ptr (params, "gfid-req", &uuid_req);
+ if (op_ret) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "failed to get the gfid from dict for %s",
+ loc->path);
+ goto real_op;
+ }
+ op_ret = posix_create_link_if_gfid_exists (this, uuid_req,
+ real_path);
+ if (!op_ret)
+ goto post_op;
+ }
+
+real_op:
#ifdef __NetBSD__
if (S_ISFIFO(mode))
op_ret = mkfifo (real_path, mode);
@@ -797,6 +816,7 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
}
#endif
+post_op:
op_ret = posix_acl_xattr_set (this, real_path, params);
if (op_ret) {
gf_log (this->name, GF_LOG_ERROR,