summaryrefslogtreecommitdiffstats
path: root/api/src/glfs.c
diff options
context:
space:
mode:
authorRajesh Joseph <rjoseph@redhat.com>2016-02-02 04:22:04 +0530
committerNiels de Vos <ndevos@redhat.com>2016-03-30 07:23:20 -0700
commite761050fb44b28c0641dd87f5fbc9d1511bed92b (patch)
tree06c271b829a58daf1087db37f1c3632b890d51ee /api/src/glfs.c
parent450a853f0059a7ed076253caa982913b08d0485b (diff)
libgfapi: glfd close is not correctly handled for async fop
There is chance that before the async fop is complete client can send a close. libgfapi destroys glfd on close. Therefore it can lead to crash or unexpected behaviour when the pening fop reaches libgfapi layer. Currently we don't provide any api to cancel these outstanding fops neither we check if the glfd is already closed or not. Therefore as a fix provided refcount for glfd. Each fop (sync or async) will take a ref and once the fop is complete it will unref the refcount. We should not call the registered callback function if glfd is already closed. To achieve this we maintain state of glfd so that we can safely take a call if the fd is closed or not. Backport of commit 88d772c05c45c467bfccebfc51f6a0e0ea9ca287: > Change-Id: Ibe71b2225312db3f1be66b244fcf8826c70c357d > BUG: 1303995 > Signed-off-by: Rajesh Joseph <rjoseph@redhat.com> > Reviewed-on: http://review.gluster.org/13340 > Smoke: Gluster Build System <jenkins@build.gluster.com> > CentOS-regression: Gluster Build System <jenkins@build.gluster.com> > Reviewed-by: Shyamsundar Ranganathan <srangana@redhat.com> > NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Change-Id: I1e01690ea72f34c12465eb084d7a1aa9de0d7b83 BUG: 1311578 Signed-off-by: Rajesh Joseph <rjoseph@redhat.com> Reviewed-on: http://review.gluster.org/13512 NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Niels de Vos <ndevos@redhat.com> Smoke: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'api/src/glfs.c')
-rw-r--r--api/src/glfs.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/api/src/glfs.c b/api/src/glfs.c
index 10658ef3819..1fc1a30ac4c 100644
--- a/api/src/glfs.c
+++ b/api/src/glfs.c
@@ -516,6 +516,32 @@ pub_glfs_from_glfd (struct glfs_fd *glfd)
GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_from_glfd, 3.4.0);
+void
+glfs_fd_destroy (void *data)
+{
+ struct glfs_fd *glfd = NULL;
+
+ if (!data)
+ return;
+
+ glfd = (struct glfs_fd *)data;
+
+ glfs_lock (glfd->fs);
+ {
+ list_del_init (&glfd->openfds);
+ }
+ glfs_unlock (glfd->fs);
+
+ if (glfd->fd) {
+ fd_unref (glfd->fd);
+ glfd->fd = NULL;
+ }
+
+ GF_FREE (glfd->readdirbuf);
+
+ GF_FREE (glfd);
+}
+
struct glfs_fd *
glfs_fd_new (struct glfs *fs)
@@ -530,6 +556,8 @@ glfs_fd_new (struct glfs *fs)
INIT_LIST_HEAD (&glfd->openfds);
+ GF_REF_INIT (glfd, glfs_fd_destroy);
+
return glfd;
}
@@ -548,28 +576,6 @@ glfs_fd_bind (struct glfs_fd *glfd)
glfs_unlock (fs);
}
-void
-glfs_fd_destroy (struct glfs_fd *glfd)
-{
- if (!glfd)
- return;
-
- glfs_lock (glfd->fs);
- {
- list_del_init (&glfd->openfds);
- }
- glfs_unlock (glfd->fs);
-
- if (glfd->fd) {
- fd_unref (glfd->fd);
- glfd->fd = NULL;
- }
-
- GF_FREE (glfd->readdirbuf);
-
- GF_FREE (glfd);
-}
-
static void *
glfs_poller (void *data)