diff options
author | Rajesh Joseph <rjoseph@redhat.com> | 2016-02-02 04:22:04 +0530 |
---|---|---|
committer | Shyamsundar Ranganathan <srangana@redhat.com> | 2016-02-10 21:46:30 -0800 |
commit | 88d772c05c45c467bfccebfc51f6a0e0ea9ca287 (patch) | |
tree | 363eb8339c04ff38ce3a4482ad24d603adfb85d7 /api/src/glfs.c | |
parent | acfb402414ec4a9ab8c9f9d4fead6b9141c2e934 (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.
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>
Diffstat (limited to 'api/src/glfs.c')
-rw-r--r-- | api/src/glfs.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/api/src/glfs.c b/api/src/glfs.c index d995b7f130c..b151936a6e8 100644 --- a/api/src/glfs.c +++ b/api/src/glfs.c @@ -541,6 +541,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) @@ -555,6 +581,8 @@ glfs_fd_new (struct glfs *fs) INIT_LIST_HEAD (&glfd->openfds); + GF_REF_INIT (glfd, glfs_fd_destroy); + return glfd; } @@ -573,28 +601,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) |