3604df
From 92c24d2db7e0633f2a3cd17932cb152b1b4feb17 Mon Sep 17 00:00:00 2001
3604df
From: Poornima G <pgurusid@redhat.com>
3604df
Date: Thu, 25 Aug 2016 10:09:20 +0530
3604df
Subject: [PATCH 130/141] upcall: Mark the clients as accessed on readdirp entries
3604df
3604df
Currently when a client performs a readdirp it is not stored
3604df
in upcall, as one of the clients that have accessed the files.
3604df
Hence, when any other client modifies the file, the client that
3604df
had performed readdirp will not get any notifications.
3604df
3604df
Fix this by adding the clients to upcall database when they
3604df
perform readdirp.
3604df
3604df
Change-Id: I7767f1e26bf1bd1f67702a6d01f8aa64526ccc46
3604df
BUG: 1284873
3604df
Signed-off-by: Poornima G <pgurusid@redhat.com>
3604df
Reviewed-on: http://review.gluster.org/15313
3604df
Smoke: Gluster Build System <jenkins@build.gluster.org>
3604df
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
3604df
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
3604df
Reviewed-by: soumya k <skoduri@redhat.com>
3604df
Reviewed-by: Niels de Vos <ndevos@redhat.com>
3604df
Reviewed-on: https://code.engineering.redhat.com/gerrit/87043
3604df
Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>
3604df
Tested-by: Rajesh Joseph <rjoseph@redhat.com>
3604df
---
3604df
 tests/bugs/upcall/bug-1369430.t      |   43 ++++++++++++++++++++++++++++++++++
3604df
 xlators/features/upcall/src/upcall.c |   43 +++++++++++++++++++++++++++++++++-
3604df
 2 files changed, 85 insertions(+), 1 deletions(-)
3604df
 create mode 100755 tests/bugs/upcall/bug-1369430.t
3604df
3604df
diff --git a/tests/bugs/upcall/bug-1369430.t b/tests/bugs/upcall/bug-1369430.t
3604df
new file mode 100755
3604df
index 0000000..f53c17a
3604df
--- /dev/null
3604df
+++ b/tests/bugs/upcall/bug-1369430.t
3604df
@@ -0,0 +1,43 @@
3604df
+#!/bin/bash
3604df
+
3604df
+. $(dirname $0)/../../include.rc
3604df
+. $(dirname $0)/../../volume.rc
3604df
+
3604df
+cleanup;
3604df
+
3604df
+## 1. Start glusterd
3604df
+TEST glusterd;
3604df
+
3604df
+## 2. Lets create volume
3604df
+TEST $CLI volume create $V0 $H0:$B0/${V0}{1,2,3};
3604df
+
3604df
+## 3. Start the volume
3604df
+TEST $CLI volume start $V0
3604df
+
3604df
+## 4. Enable the upcall xlator, and increase the md-cache timeout to max
3604df
+TEST $CLI volume set $V0 features.cache-invalidation on
3604df
+TEST $CLI volume set $V0 features.cache-invalidation-timeout 600
3604df
+TEST $CLI volume set $V0 performance.cache-invalidation on
3604df
+TEST $CLI volume set $V0 performance.md-cache-timeout 600
3604df
+TEST $CLI volume set $V0 performance.cache-samba-metadata on
3604df
+
3604df
+## 8. Create two gluster mounts
3604df
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0
3604df
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M1
3604df
+
3604df
+## 10. Create directory and files from the M0
3604df
+TEST mkdir $M0/dir1
3604df
+TEST touch $M0/dir1/file{1..5}
3604df
+
3604df
+## 12. Access the files via readdirp, from M1
3604df
+TEST ls -l $M1/dir1/
3604df
+
3604df
+# Change the stat of one of the files from M0 and wait for it to
3604df
+# invalidate the md-cache of another mount M0
3604df
+echo "hello" > $M0/dir1/file2
3604df
+sleep 2;
3604df
+
3604df
+## 13. Expct non zero size when stat from M1
3604df
+EXPECT_NOT "0" stat -c %s $M1/dir1/file2
3604df
+
3604df
+cleanup;
3604df
diff --git a/xlators/features/upcall/src/upcall.c b/xlators/features/upcall/src/upcall.c
3604df
index 41189c9..db4aa19 100644
3604df
--- a/xlators/features/upcall/src/upcall.c
3604df
+++ b/xlators/features/upcall/src/upcall.c
3604df
@@ -1304,6 +1304,47 @@ err:
3604df
 }
3604df
 
3604df
 int32_t
3604df
+up_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
+                 int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
3604df
+                 dict_t *xdata)
3604df
+{
3604df
+        client_t         *client        = NULL;
3604df
+        uint32_t         flags          = 0;
3604df
+        upcall_local_t   *local         = NULL;
3604df
+        gf_dirent_t      *entry         = NULL;
3604df
+
3604df
+        EXIT_IF_UPCALL_OFF (this, out);
3604df
+
3604df
+        client = frame->root->client;
3604df
+        local = frame->local;
3604df
+
3604df
+        if ((op_ret < 0) || !local) {
3604df
+                goto out;
3604df
+        }
3604df
+        flags = UP_UPDATE_CLIENT;
3604df
+        upcall_cache_invalidate (frame, this, client, local->inode, flags,
3604df
+                                 NULL, NULL, NULL, NULL);
3604df
+
3604df
+        /* upcall_cache_invalidate optimises, by not calling inode_ctx_get
3604df
+         * if local->upcall_inode_ctx is set. Hence before processing
3604df
+         * the readdir entries unset this */
3604df
+        local->upcall_inode_ctx = NULL;
3604df
+        list_for_each_entry (entry, &entries->list, list) {
3604df
+                if (entry->inode == NULL) {
3604df
+                        continue;
3604df
+                }
3604df
+                upcall_cache_invalidate (frame, this, client, entry->inode,
3604df
+                                         flags, &entry->d_stat, NULL, NULL,
3604df
+                                         NULL);
3604df
+        }
3604df
+
3604df
+out:
3604df
+        UPCALL_STACK_UNWIND (readdirp, frame, op_ret, op_errno, entries, xdata);
3604df
+
3604df
+        return 0;
3604df
+}
3604df
+
3604df
+int32_t
3604df
 up_readdirp (call_frame_t *frame, xlator_t *this,
3604df
              fd_t *fd, size_t size, off_t off, dict_t *dict)
3604df
 {
3604df
@@ -1319,7 +1360,7 @@ up_readdirp (call_frame_t *frame, xlator_t *this,
3604df
         }
3604df
 
3604df
 out:
3604df
-        STACK_WIND (frame, up_readdir_cbk,
3604df
+        STACK_WIND (frame, up_readdirp_cbk,
3604df
                     FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp,
3604df
                     fd, size, off, dict);
3604df
 
3604df
-- 
3604df
1.7.1
3604df