256ebe
From 10e9f850017d58fcd813ccce253784280326f1d0 Mon Sep 17 00:00:00 2001
256ebe
From: Anuradha Talur <atalur@commvault.com>
256ebe
Date: Tue, 20 Nov 2018 13:15:26 -0800
256ebe
Subject: [PATCH 152/169] storage/posix: changes with respect to cloudsync
256ebe
256ebe
Main changes include logic to update iatt buf
256ebe
with file size from extended attributes in posix
256ebe
rather than having this logic in cloudsync xlator.
256ebe
256ebe
backport of:https://review.gluster.org/#/c/glusterfs/+/21694/
256ebe
256ebe
> Change-Id: I44f5f8df7a01e496372557fe2f4eff368dbdaa33
256ebe
> fixes: bz#1642168
256ebe
> Signed-off-by: Anuradha Talur <atalur@commvault.com>
256ebe
256ebe
Change-Id: I34880d856fb3add4ce88d64021d08d95405fc1c1
256ebe
Signed-off-by: Susant Palai <spalai@redhat.com>
256ebe
Reviewed-on: https://code.engineering.redhat.com/gerrit/172191
256ebe
Tested-by: RHGS Build Bot <nigelb@redhat.com>
256ebe
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
256ebe
---
256ebe
 xlators/storage/posix/src/posix-entry-ops.c    |   1 +
256ebe
 xlators/storage/posix/src/posix-helpers.c      |  50 +++++++++
256ebe
 xlators/storage/posix/src/posix-inode-fd-ops.c | 139 ++++++++++++++++++++++---
256ebe
 xlators/storage/posix/src/posix.h              |   2 +
256ebe
 4 files changed, 177 insertions(+), 15 deletions(-)
256ebe
256ebe
diff --git a/xlators/storage/posix/src/posix-entry-ops.c b/xlators/storage/posix/src/posix-entry-ops.c
256ebe
index fbd83c4..b24a052 100644
256ebe
--- a/xlators/storage/posix/src/posix-entry-ops.c
256ebe
+++ b/xlators/storage/posix/src/posix-entry-ops.c
256ebe
@@ -272,6 +272,7 @@ posix_lookup(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
256ebe
         }
256ebe
     }
256ebe
 
256ebe
+    posix_update_iatt_buf(&buf, -1, real_path, xdata);
256ebe
     if (priv->update_pgfid_nlinks) {
256ebe
         if (!gf_uuid_is_null(loc->pargfid) && !IA_ISDIR(buf.ia_type)) {
256ebe
             MAKE_PGFID_XATTR_KEY(pgfid_xattr_key, PGFID_XATTR_KEY_PREFIX,
256ebe
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
256ebe
index 37e33a9..d0fd45a 100644
256ebe
--- a/xlators/storage/posix/src/posix-helpers.c
256ebe
+++ b/xlators/storage/posix/src/posix-helpers.c
256ebe
@@ -3453,3 +3453,53 @@ posix_check_dev_file(xlator_t *this, inode_t *inode, char *fop, int *op_errno)
256ebe
 out:
256ebe
     return ret;
256ebe
 }
256ebe
+
256ebe
+void
256ebe
+posix_update_iatt_buf(struct iatt *buf, int fd, char *loc, dict_t *xattr_req)
256ebe
+{
256ebe
+    int ret = 0;
256ebe
+    char val[4096] = {
256ebe
+        0,
256ebe
+    };
256ebe
+
256ebe
+    if (!xattr_req)
256ebe
+        return;
256ebe
+
256ebe
+    if (!(dict_getn(xattr_req, GF_CS_OBJECT_STATUS,
256ebe
+                    strlen(GF_CS_OBJECT_STATUS))))
256ebe
+        return;
256ebe
+
256ebe
+    if (fd != -1) {
256ebe
+        ret = sys_fgetxattr(fd, GF_CS_OBJECT_SIZE, &val, sizeof(val));
256ebe
+        if (ret > 0) {
256ebe
+            buf->ia_size = atoll(val);
256ebe
+        } else {
256ebe
+            /* Safe to assume that the other 2 xattrs are also not set*/
256ebe
+            return;
256ebe
+        }
256ebe
+        ret = sys_fgetxattr(fd, GF_CS_BLOCK_SIZE, &val, sizeof(val));
256ebe
+        if (ret > 0) {
256ebe
+            buf->ia_blksize = atoll(val);
256ebe
+        }
256ebe
+        ret = sys_fgetxattr(fd, GF_CS_NUM_BLOCKS, &val, sizeof(val));
256ebe
+        if (ret > 0) {
256ebe
+            buf->ia_blocks = atoll(val);
256ebe
+        }
256ebe
+    } else {
256ebe
+        ret = sys_lgetxattr(loc, GF_CS_OBJECT_SIZE, &val, sizeof(val));
256ebe
+        if (ret > 0) {
256ebe
+            buf->ia_size = atoll(val);
256ebe
+        } else {
256ebe
+            /* Safe to assume that the other 2 xattrs are also not set*/
256ebe
+            return;
256ebe
+        }
256ebe
+        ret = sys_lgetxattr(loc, GF_CS_BLOCK_SIZE, &val, sizeof(val));
256ebe
+        if (ret > 0) {
256ebe
+            buf->ia_blksize = atoll(val);
256ebe
+        }
256ebe
+        ret = sys_lgetxattr(loc, GF_CS_NUM_BLOCKS, &val, sizeof(val));
256ebe
+        if (ret > 0) {
256ebe
+            buf->ia_blocks = atoll(val);
256ebe
+        }
256ebe
+    }
256ebe
+}
256ebe
diff --git a/xlators/storage/posix/src/posix-inode-fd-ops.c b/xlators/storage/posix/src/posix-inode-fd-ops.c
256ebe
index 7dbbd3d..065fced 100644
256ebe
--- a/xlators/storage/posix/src/posix-inode-fd-ops.c
256ebe
+++ b/xlators/storage/posix/src/posix-inode-fd-ops.c
256ebe
@@ -108,6 +108,63 @@ extern char *marker_xattrs[];
256ebe
 static char *disallow_removexattrs[] = {GF_XATTR_VOL_ID_KEY, GFID_XATTR_KEY,
256ebe
                                         NULL};
256ebe
 
256ebe
+void
256ebe
+posix_cs_build_xattr_rsp(xlator_t *this, dict_t **rsp, dict_t *req, int fd,
256ebe
+                         char *loc)
256ebe
+{
256ebe
+    int ret = 0;
256ebe
+    uuid_t uuid;
256ebe
+
256ebe
+    if (!(dict_getn(req, GF_CS_OBJECT_STATUS, strlen(GF_CS_OBJECT_STATUS))))
256ebe
+        return;
256ebe
+
256ebe
+    if (!(*rsp)) {
256ebe
+        *rsp = dict_new();
256ebe
+        if (!(*rsp)) {
256ebe
+            return;
256ebe
+        }
256ebe
+    }
256ebe
+
256ebe
+    if (fd != -1) {
256ebe
+        if (dict_getn(req, GF_CS_XATTR_ARCHIVE_UUID,
256ebe
+                      strlen(GF_CS_XATTR_ARCHIVE_UUID))) {
256ebe
+            ret = sys_fgetxattr(fd, GF_CS_XATTR_ARCHIVE_UUID, uuid, 16);
256ebe
+            if (ret > 0) {
256ebe
+                ret = dict_set_gfuuid(*rsp, GF_CS_XATTR_ARCHIVE_UUID, uuid,
256ebe
+                                      true);
256ebe
+                if (ret) {
256ebe
+                    gf_msg(this->name, GF_LOG_WARNING, 0, P_MSG_DICT_SET_FAILED,
256ebe
+                           "%s: Failed to set "
256ebe
+                           "dictionary value for %s for fd %d",
256ebe
+                           uuid_utoa(uuid), GF_CS_XATTR_ARCHIVE_UUID, fd);
256ebe
+                }
256ebe
+            } else {
256ebe
+                gf_msg_debug(this->name, 0, "getxattr failed on %s for fd %d",
256ebe
+                             GF_CS_XATTR_ARCHIVE_UUID, fd);
256ebe
+            }
256ebe
+        }
256ebe
+    } else {
256ebe
+        if (dict_getn(req, GF_CS_XATTR_ARCHIVE_UUID,
256ebe
+                      strlen(GF_CS_XATTR_ARCHIVE_UUID))) {
256ebe
+            ret = sys_lgetxattr(loc, GF_CS_XATTR_ARCHIVE_UUID, uuid, 16);
256ebe
+            if (ret > 0) {
256ebe
+                ret = dict_set_gfuuid(*rsp, GF_CS_XATTR_ARCHIVE_UUID, uuid,
256ebe
+                                      true);
256ebe
+                if (ret) {
256ebe
+                    gf_msg(this->name, GF_LOG_WARNING, 0, P_MSG_DICT_SET_FAILED,
256ebe
+                           "%s: Failed to set "
256ebe
+                           "dictionary value for %s for loc %s",
256ebe
+                           uuid_utoa(uuid), GF_CS_XATTR_ARCHIVE_UUID, loc);
256ebe
+                }
256ebe
+            } else {
256ebe
+                gf_msg_debug(this->name, 0, "getxattr failed on %s for %s",
256ebe
+                             GF_CS_XATTR_ARCHIVE_UUID, loc);
256ebe
+            }
256ebe
+        }
256ebe
+    }
256ebe
+    return;
256ebe
+}
256ebe
+
256ebe
 int32_t
256ebe
 posix_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
256ebe
 {
256ebe
@@ -150,8 +207,11 @@ posix_stat(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata)
256ebe
 
256ebe
         posix_cs_maintenance(this, NULL, loc, NULL, &buf, real_path, xdata,
256ebe
                              &xattr_rsp, _gf_true);
256ebe
+
256ebe
+        posix_cs_build_xattr_rsp(this, &xattr_rsp, xdata, -1, real_path);
256ebe
     }
256ebe
 
256ebe
+    posix_update_iatt_buf(&buf, -1, real_path, xdata);
256ebe
     op_ret = 0;
256ebe
 
256ebe
 out:
256ebe
@@ -422,6 +482,8 @@ posix_setattr(call_frame_t *frame, xlator_t *this, loc_t *loc,
256ebe
     if (xdata)
256ebe
         xattr_rsp = posix_xattr_fill(this, real_path, loc, NULL, -1, xdata,
256ebe
                                      &statpost);
256ebe
+    posix_update_iatt_buf(&statpre, -1, real_path, xdata);
256ebe
+    posix_update_iatt_buf(&statpost, -1, real_path, xdata);
256ebe
     op_ret = 0;
256ebe
 
256ebe
 out:
256ebe
@@ -898,6 +960,7 @@ posix_do_zerofill(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
256ebe
         }
256ebe
     }
256ebe
 
256ebe
+    posix_update_iatt_buf(statpre, pfd->fd, NULL, xdata);
256ebe
     /* See if we can use FALLOC_FL_ZERO_RANGE to perform the zero fill.
256ebe
      * If it fails, fall back to _posix_do_zerofill() and an optional fsync.
256ebe
      */
256ebe
@@ -1366,6 +1429,7 @@ posix_truncate(call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset,
256ebe
         }
256ebe
     }
256ebe
 
256ebe
+    posix_update_iatt_buf(&prebuf, -1, real_path, xdata);
256ebe
     op_ret = sys_truncate(real_path, offset);
256ebe
     if (op_ret == -1) {
256ebe
         op_errno = errno;
256ebe
@@ -1405,6 +1469,10 @@ posix_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
256ebe
     int32_t _fd = -1;
256ebe
     struct posix_fd *pfd = NULL;
256ebe
     struct posix_private *priv = NULL;
256ebe
+    struct iatt preop = {
256ebe
+        0,
256ebe
+    };
256ebe
+    dict_t *rsp_xdata = NULL;
256ebe
     struct iatt stbuf = {
256ebe
         0,
256ebe
     };
256ebe
@@ -1471,6 +1539,18 @@ posix_open(call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t flags,
256ebe
     pfd->flags = flags;
256ebe
     pfd->fd = _fd;
256ebe
 
256ebe
+    if (xdata) {
256ebe
+        op_ret = posix_fdstat(this, fd->inode, pfd->fd, &preop);
256ebe
+        if (op_ret == -1) {
256ebe
+            gf_msg(this->name, GF_LOG_ERROR, errno, P_MSG_FSTAT_FAILED,
256ebe
+                   "pre-operation fstat failed on fd=%p", fd);
256ebe
+            goto out;
256ebe
+        }
256ebe
+
256ebe
+        posix_cs_maintenance(this, fd, NULL, &pfd->fd, &preop, NULL, xdata,
256ebe
+                             &rsp_xdata, _gf_true);
256ebe
+    }
256ebe
+
256ebe
     op_ret = fd_ctx_set(fd, this, (uint64_t)(long)pfd);
256ebe
     if (op_ret)
256ebe
         gf_msg(this->name, GF_LOG_WARNING, 0, P_MSG_FD_PATH_SETTING_FAILED,
256ebe
@@ -1488,7 +1568,7 @@ out:
256ebe
 
256ebe
     SET_TO_OLD_FS_ID();
256ebe
 
256ebe
-    STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, fd, NULL);
256ebe
+    STACK_UNWIND_STRICT(open, frame, op_ret, op_errno, fd, rsp_xdata);
256ebe
 
256ebe
     return 0;
256ebe
 }
256ebe
@@ -1573,6 +1653,7 @@ posix_readv(call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
256ebe
         }
256ebe
     }
256ebe
 
256ebe
+    posix_update_iatt_buf(&preop, _fd, NULL, xdata);
256ebe
     op_ret = sys_pread(_fd, iobuf->ptr, size, offset);
256ebe
     if (op_ret == -1) {
256ebe
         op_errno = errno;
256ebe
@@ -1878,6 +1959,7 @@ posix_writev(call_frame_t *frame, xlator_t *this, fd_t *fd,
256ebe
         }
256ebe
     }
256ebe
 
256ebe
+    posix_update_iatt_buf(&preop, _fd, NULL, xdata);
256ebe
     if (locked && write_append) {
256ebe
         if (preop.ia_size == offset || (fd->flags & O_APPEND))
256ebe
             is_append = 1;
256ebe
@@ -2531,10 +2613,8 @@ posix_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
256ebe
         0,
256ebe
     };
256ebe
     data_t *tdata = NULL;
256ebe
-    char stime[4096];
256ebe
-    char sxattr[4096];
256ebe
+    char *cs_var = NULL;
256ebe
     gf_cs_obj_state state = -1;
256ebe
-    char remotepath[4096] = {0};
256ebe
     int i = 0;
256ebe
     int len;
256ebe
 
256ebe
@@ -2588,10 +2668,11 @@ posix_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
256ebe
                 goto unlock;
256ebe
             }
256ebe
 
256ebe
-            sprintf(stime, "%" PRId64, tmp_stbuf.ia_mtime);
256ebe
+            cs_var = alloca(4096);
256ebe
+            sprintf(cs_var, "%" PRId64, tmp_stbuf.ia_mtime);
256ebe
 
256ebe
             /*TODO: may be should consider nano-second also */
256ebe
-            if (strncmp(stime, tdata->data, tdata->len) != 0) {
256ebe
+            if (strncmp(cs_var, tdata->data, tdata->len) > 0) {
256ebe
                 gf_msg(this->name, GF_LOG_ERROR, 0, 0,
256ebe
                        "mtime "
256ebe
                        "passed is different from seen by file now."
256ebe
@@ -2601,31 +2682,54 @@ posix_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
256ebe
                 goto unlock;
256ebe
             }
256ebe
 
256ebe
-            len = sprintf(sxattr, "%" PRIu64, tmp_stbuf.ia_size);
256ebe
+            len = sprintf(cs_var, "%" PRIu64, tmp_stbuf.ia_size);
256ebe
 
256ebe
-            ret = sys_lsetxattr(real_path, GF_CS_OBJECT_SIZE, sxattr, len,
256ebe
+            ret = sys_lsetxattr(real_path, GF_CS_OBJECT_SIZE, cs_var, len,
256ebe
                                 flags);
256ebe
             if (ret) {
256ebe
+                op_errno = errno;
256ebe
                 gf_msg(this->name, GF_LOG_ERROR, 0, 0,
256ebe
                        "setxattr failed. key %s err %d", GF_CS_OBJECT_SIZE,
256ebe
                        ret);
256ebe
+                goto unlock;
256ebe
+            }
256ebe
+
256ebe
+            len = sprintf(cs_var, "%" PRIu64, tmp_stbuf.ia_blocks);
256ebe
+
256ebe
+            ret = sys_lsetxattr(real_path, GF_CS_NUM_BLOCKS, cs_var, len,
256ebe
+                                flags);
256ebe
+            if (ret) {
256ebe
                 op_errno = errno;
256ebe
+                gf_msg(this->name, GF_LOG_ERROR, 0, 0,
256ebe
+                       "setxattr failed. key %s err %d", GF_CS_NUM_BLOCKS, ret);
256ebe
                 goto unlock;
256ebe
             }
256ebe
 
256ebe
+            len = sprintf(cs_var, "%" PRIu32, tmp_stbuf.ia_blksize);
256ebe
+
256ebe
+            ret = sys_lsetxattr(real_path, GF_CS_BLOCK_SIZE, cs_var, len,
256ebe
+                                flags);
256ebe
+            if (ret) {
256ebe
+                op_errno = errno;
256ebe
+                gf_msg(this->name, GF_LOG_ERROR, 0, 0,
256ebe
+                       "setxattr failed. key %s err %d", GF_CS_BLOCK_SIZE, ret);
256ebe
+                goto unlock;
256ebe
+            }
256ebe
+
256ebe
+            memset(cs_var, 0, 4096);
256ebe
             if (loc->path[0] == '/') {
256ebe
                 for (i = 1; i < strlen(loc->path); i++) {
256ebe
-                    remotepath[i - 1] = loc->path[i];
256ebe
+                    cs_var[i - 1] = loc->path[i];
256ebe
                 }
256ebe
 
256ebe
-                remotepath[i] = '\0';
256ebe
-                gf_msg_debug(this->name, GF_LOG_ERROR, "remotepath %s",
256ebe
-                             remotepath);
256ebe
+                cs_var[i] = '\0';
256ebe
+                gf_msg_debug(this->name, GF_LOG_ERROR, "remotepath %s", cs_var);
256ebe
             }
256ebe
 
256ebe
-            ret = sys_lsetxattr(real_path, GF_CS_OBJECT_REMOTE, remotepath,
256ebe
-                                strlen(loc->path), flags);
256ebe
+            ret = sys_lsetxattr(real_path, GF_CS_OBJECT_REMOTE, cs_var,
256ebe
+                                strlen(cs_var), flags);
256ebe
             if (ret) {
256ebe
+                op_errno = errno;
256ebe
                 gf_log("POSIX", GF_LOG_ERROR,
256ebe
                        "setxattr failed - %s"
256ebe
                        " %d",
256ebe
@@ -2635,13 +2739,14 @@ posix_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
256ebe
 
256ebe
             ret = sys_truncate(real_path, 0);
256ebe
             if (ret) {
256ebe
+                op_errno = errno;
256ebe
                 gf_log("POSIX", GF_LOG_ERROR,
256ebe
                        "truncate failed - %s"
256ebe
                        " %d",
256ebe
                        GF_CS_OBJECT_SIZE, ret);
256ebe
-                op_errno = errno;
256ebe
                 ret = sys_lremovexattr(real_path, GF_CS_OBJECT_REMOTE);
256ebe
                 if (ret) {
256ebe
+                    op_errno = errno;
256ebe
                     gf_log("POSIX", GF_LOG_ERROR,
256ebe
                            "removexattr "
256ebe
                            "failed post processing- %s"
256ebe
@@ -2659,6 +2764,7 @@ posix_setxattr(call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
256ebe
         }
256ebe
     unlock:
256ebe
         UNLOCK(&loc->inode->lock);
256ebe
+        op_ret = ret;
256ebe
         goto out;
256ebe
     }
256ebe
 
256ebe
@@ -4927,6 +5033,7 @@ posix_ftruncate(call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset,
256ebe
         }
256ebe
     }
256ebe
 
256ebe
+    posix_update_iatt_buf(&preop, _fd, NULL, xdata);
256ebe
     op_ret = sys_ftruncate(_fd, offset);
256ebe
 
256ebe
     if (op_ret == -1) {
256ebe
@@ -5008,8 +5115,10 @@ posix_fstat(call_frame_t *frame, xlator_t *this, fd_t *fd, dict_t *xdata)
256ebe
             gf_msg(this->name, GF_LOG_ERROR, 0, 0,
256ebe
                    "file state check failed, fd %p", fd);
256ebe
         }
256ebe
+        posix_cs_build_xattr_rsp(this, &xattr_rsp, xdata, _fd, NULL);
256ebe
     }
256ebe
 
256ebe
+    posix_update_iatt_buf(&buf, _fd, NULL, xdata);
256ebe
     op_ret = 0;
256ebe
 
256ebe
 out:
256ebe
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
256ebe
index d5ba08c..1da4d01 100644
256ebe
--- a/xlators/storage/posix/src/posix.h
256ebe
+++ b/xlators/storage/posix/src/posix.h
256ebe
@@ -664,4 +664,6 @@ posix_check_dev_file(xlator_t *this, inode_t *inode, char *fop, int *op_errno);
256ebe
 int
256ebe
 posix_spawn_ctx_janitor_thread(xlator_t *this);
256ebe
 
256ebe
+void
256ebe
+posix_update_iatt_buf(struct iatt *buf, int fd, char *loc, dict_t *xdata);
256ebe
 #endif /* _POSIX_H */
256ebe
-- 
256ebe
1.8.3.1
256ebe