summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmar Tumballi <amar@gluster.com>2012-02-15 17:20:40 +0530
committerAnand Avati <avati@redhat.com>2012-02-16 22:48:57 -0800
commit47e748fe60c46d543c87f3228eb59d6580db8cf1 (patch)
treef5b244d4e1e0f5fd595e3235985b7bc921c8f330
parent4cc4e47f6cad1127ad425cc0ab10bc42ab1411c8 (diff)
posix: handle some internal behavior in posix_mknod()
assume a case of link() systemcall, which is handled in distribute by creating a 'linkfile' in hashed subvolume, if the 'oldloc' is present in different subvolume. we have same 'gfid' for the linkfile as that of file for consistency. Now, a file with multiple hardlinks, we may end up with 'hardlinked' linkfiles. dht create linkfile using 'mknod()' fop, and as now posix_mknod() is not equipped to handle this situation. this patch fixes the situation by looking at the 'internal' key set in the dictionary to differentiate the call which originates from inside with regular system calls. Change-Id: Ibff7c31f8e0c8bdae035c705c93a295f080ff985 BUG: 763844 Signed-off-by: Amar Tumballi <amar@gluster.com> Reviewed-on: http://review.gluster.com/2755 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@redhat.com>
-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,