Blob Blame History Raw
From 92c24d2db7e0633f2a3cd17932cb152b1b4feb17 Mon Sep 17 00:00:00 2001
From: Poornima G <pgurusid@redhat.com>
Date: Thu, 25 Aug 2016 10:09:20 +0530
Subject: [PATCH 130/141] upcall: Mark the clients as accessed on readdirp entries

Currently when a client performs a readdirp it is not stored
in upcall, as one of the clients that have accessed the files.
Hence, when any other client modifies the file, the client that
had performed readdirp will not get any notifications.

Fix this by adding the clients to upcall database when they
perform readdirp.

Change-Id: I7767f1e26bf1bd1f67702a6d01f8aa64526ccc46
BUG: 1284873
Signed-off-by: Poornima G <pgurusid@redhat.com>
Reviewed-on: http://review.gluster.org/15313
Smoke: Gluster Build System <jenkins@build.gluster.org>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Reviewed-by: soumya k <skoduri@redhat.com>
Reviewed-by: Niels de Vos <ndevos@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/87043
Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>
Tested-by: Rajesh Joseph <rjoseph@redhat.com>
---
 tests/bugs/upcall/bug-1369430.t      |   43 ++++++++++++++++++++++++++++++++++
 xlators/features/upcall/src/upcall.c |   43 +++++++++++++++++++++++++++++++++-
 2 files changed, 85 insertions(+), 1 deletions(-)
 create mode 100755 tests/bugs/upcall/bug-1369430.t

diff --git a/tests/bugs/upcall/bug-1369430.t b/tests/bugs/upcall/bug-1369430.t
new file mode 100755
index 0000000..f53c17a
--- /dev/null
+++ b/tests/bugs/upcall/bug-1369430.t
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+. $(dirname $0)/../../volume.rc
+
+cleanup;
+
+## 1. Start glusterd
+TEST glusterd;
+
+## 2. Lets create volume
+TEST $CLI volume create $V0 $H0:$B0/${V0}{1,2,3};
+
+## 3. Start the volume
+TEST $CLI volume start $V0
+
+## 4. Enable the upcall xlator, and increase the md-cache timeout to max
+TEST $CLI volume set $V0 features.cache-invalidation on
+TEST $CLI volume set $V0 features.cache-invalidation-timeout 600
+TEST $CLI volume set $V0 performance.cache-invalidation on
+TEST $CLI volume set $V0 performance.md-cache-timeout 600
+TEST $CLI volume set $V0 performance.cache-samba-metadata on
+
+## 8. Create two gluster mounts
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M1
+
+## 10. Create directory and files from the M0
+TEST mkdir $M0/dir1
+TEST touch $M0/dir1/file{1..5}
+
+## 12. Access the files via readdirp, from M1
+TEST ls -l $M1/dir1/
+
+# Change the stat of one of the files from M0 and wait for it to
+# invalidate the md-cache of another mount M0
+echo "hello" > $M0/dir1/file2
+sleep 2;
+
+## 13. Expct non zero size when stat from M1
+EXPECT_NOT "0" stat -c %s $M1/dir1/file2
+
+cleanup;
diff --git a/xlators/features/upcall/src/upcall.c b/xlators/features/upcall/src/upcall.c
index 41189c9..db4aa19 100644
--- a/xlators/features/upcall/src/upcall.c
+++ b/xlators/features/upcall/src/upcall.c
@@ -1304,6 +1304,47 @@ err:
 }
 
 int32_t
+up_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+                 int32_t op_ret, int32_t op_errno, gf_dirent_t *entries,
+                 dict_t *xdata)
+{
+        client_t         *client        = NULL;
+        uint32_t         flags          = 0;
+        upcall_local_t   *local         = NULL;
+        gf_dirent_t      *entry         = NULL;
+
+        EXIT_IF_UPCALL_OFF (this, out);
+
+        client = frame->root->client;
+        local = frame->local;
+
+        if ((op_ret < 0) || !local) {
+                goto out;
+        }
+        flags = UP_UPDATE_CLIENT;
+        upcall_cache_invalidate (frame, this, client, local->inode, flags,
+                                 NULL, NULL, NULL, NULL);
+
+        /* upcall_cache_invalidate optimises, by not calling inode_ctx_get
+         * if local->upcall_inode_ctx is set. Hence before processing
+         * the readdir entries unset this */
+        local->upcall_inode_ctx = NULL;
+        list_for_each_entry (entry, &entries->list, list) {
+                if (entry->inode == NULL) {
+                        continue;
+                }
+                upcall_cache_invalidate (frame, this, client, entry->inode,
+                                         flags, &entry->d_stat, NULL, NULL,
+                                         NULL);
+        }
+
+out:
+        UPCALL_STACK_UNWIND (readdirp, frame, op_ret, op_errno, entries, xdata);
+
+        return 0;
+}
+
+int32_t
 up_readdirp (call_frame_t *frame, xlator_t *this,
              fd_t *fd, size_t size, off_t off, dict_t *dict)
 {
@@ -1319,7 +1360,7 @@ up_readdirp (call_frame_t *frame, xlator_t *this,
         }
 
 out:
-        STACK_WIND (frame, up_readdir_cbk,
+        STACK_WIND (frame, up_readdirp_cbk,
                     FIRST_CHILD(this), FIRST_CHILD(this)->fops->readdirp,
                     fd, size, off, dict);
 
-- 
1.7.1