Blob Blame History Raw
From 8de304e787f6d0da7c3481e6c8b3d8e7e7f32824 Mon Sep 17 00:00:00 2001
From: Ravishankar N <ravishankar@redhat.com>
Date: Tue, 8 Aug 2017 21:42:03 +0530
Subject: [PATCH 596/601] posix: add null gfid checks

Patch in master: https://review.gluster.org/17975
Patch in release-3.12: https://review.gluster.org/#/c/17996/

...in file/dir creation and lookup codepaths. The check is relaxed for
fops coming from trash xlator at the moment until trash has client side
logic to send the create fops with gfid-req.

Also fixed the missing trash pid assignment in creates sent by trash
xlator. Without this, truncated files won't be moved to .trashcan.

Change-Id: I52dcdb2058371d8de1fb1d77a82ee8086b18200d
BUG: 1474178
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/114760
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
---
 xlators/features/trash/src/trash.c        |  7 +++++++
 xlators/storage/posix/src/posix-helpers.c |  6 ++++++
 xlators/storage/posix/src/posix.c         |  8 ++++++++
 xlators/storage/posix/src/posix.h         | 29 +++++++++++++++++++++++++++++
 4 files changed, 50 insertions(+)

diff --git a/xlators/features/trash/src/trash.c b/xlators/features/trash/src/trash.c
index fd5507f..e0726fe 100644
--- a/xlators/features/trash/src/trash.c
+++ b/xlators/features/trash/src/trash.c
@@ -1306,6 +1306,8 @@ trash_truncate_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
         local = frame->local;
         GF_VALIDATE_OR_GOTO ("trash", local, out);
 
+        TRASH_UNSET_PID (frame, local);
+
         /* Checks whether path is present in trash directory or not */
 
         if ((op_ret == -1) && (op_errno == ENOENT)) {
@@ -1480,6 +1482,9 @@ trash_truncate_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
                         strcat (real_path, local->origpath);
                         /* Call create again once directory structure
                            is created. */
+
+                        TRASH_SET_PID (frame, local);
+
                         STACK_WIND (frame, trash_truncate_create_cbk,
                                     FIRST_CHILD(this),
                                     FIRST_CHILD(this)->fops->create,
@@ -1683,6 +1688,8 @@ trash_truncate_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
 
         flags = O_CREAT|O_EXCL|O_WRONLY;
 
+        TRASH_SET_PID (frame, local);
+
         STACK_WIND (frame, trash_truncate_create_cbk,
                     FIRST_CHILD(this),
                     FIRST_CHILD(this)->fops->create,
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
index fb6b7d0..ad3639a 100644
--- a/xlators/storage/posix/src/posix-helpers.c
+++ b/xlators/storage/posix/src/posix-helpers.c
@@ -880,6 +880,12 @@ posix_gfid_set (xlator_t *this, const char *path, loc_t *loc, dict_t *xattr_req)
                         loc->path);
                 goto out;
         }
+        if (gf_uuid_is_null (uuid_req)) {
+                gf_msg (this->name, GF_LOG_ERROR, EINVAL, P_MSG_NULL_GFID,
+                        "gfid is null for %s", loc ? loc->path : "");
+                ret = -1;
+                goto out;
+        }
 
         ret = sys_lsetxattr (path, GFID_XATTR_KEY, uuid_req, 16, XATTR_CREATE);
         if (ret == -1) {
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 1486d40..331461c 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -1272,6 +1272,8 @@ posix_mknod (call_frame_t *frame, xlator_t *this,
 
         priv = this->private;
         VALIDATE_OR_GOTO (priv, out);
+        GFID_NULL_CHECK_AND_GOTO (frame, this, loc, xdata, op_ret, op_errno,
+                                  out);
 
         MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, NULL);
 
@@ -1478,6 +1480,8 @@ posix_mkdir (call_frame_t *frame, xlator_t *this,
 
         priv = this->private;
         VALIDATE_OR_GOTO (priv, out);
+        GFID_NULL_CHECK_AND_GOTO (frame, this, loc, xdata, op_ret, op_errno,
+                                  out);
 
         MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, NULL);
         if (!real_path || !par_path) {
@@ -2269,6 +2273,8 @@ posix_symlink (call_frame_t *frame, xlator_t *this,
 
         priv = this->private;
         VALIDATE_OR_GOTO (priv, out);
+        GFID_NULL_CHECK_AND_GOTO (frame, this, loc, xdata, op_ret, op_errno,
+                                  out);
 
         MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf);
 
@@ -2879,6 +2885,8 @@ posix_create (call_frame_t *frame, xlator_t *this,
 
         priv = this->private;
         VALIDATE_OR_GOTO (priv, out);
+        GFID_NULL_CHECK_AND_GOTO (frame, this, loc, xdata, op_ret, op_errno,
+                                  out);
 
         MAKE_ENTRY_HANDLE (real_path, par_path, this, loc, &stbuf);
 
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
index febd432..40ce4cd 100644
--- a/xlators/storage/posix/src/posix.h
+++ b/xlators/storage/posix/src/posix.h
@@ -76,6 +76,35 @@ struct posix_fd {
         struct list_head list; /* to add to the janitor list */
 };
 
+#define GFID_NULL_CHECK_AND_GOTO(frame, this, loc, xattr_req, op_ret,         \
+                                 op_errno, out)                               \
+        do {                                                                  \
+                void *_uuid_req = NULL;                                       \
+                int _ret = 0;                                                 \
+                /* TODO: Remove pid check once trash implements client side   \
+                 * logic to assign gfid for entry creations inside .trashcan  \
+                 */                                                           \
+                if (frame->root->pid == GF_SERVER_PID_TRASH)                  \
+                        break;                                                \
+                _ret = dict_get_ptr (xattr_req, "gfid-req", &_uuid_req);      \
+                if (_ret) {                                                   \
+                        gf_msg (this->name, GF_LOG_ERROR, EINVAL,             \
+                               P_MSG_NULL_GFID, "failed to get the gfid from" \
+                               " dict for %s", loc->path);                    \
+                        op_ret = -1;                                          \
+                        op_errno = EINVAL;                                    \
+                        goto out;                                             \
+                }                                                             \
+                if (gf_uuid_is_null (_uuid_req)) {                            \
+                        gf_msg (this->name, GF_LOG_ERROR, EINVAL,             \
+                                P_MSG_NULL_GFID, "gfid is null for %s",       \
+                                loc->path);                                   \
+                        op_ret = -1;                                          \
+                        op_errno = EINVAL;                                    \
+                        goto out;                                             \
+                }                                                             \
+        } while (0)
+
 
 struct posix_private {
 	char   *base_path;
-- 
1.8.3.1