diff options
| author | Rajesh Joseph <rjoseph@redhat.com> | 2016-02-02 04:22:04 +0530 |
|---|---|---|
| committer | Niels de Vos <ndevos@redhat.com> | 2016-03-30 07:23:20 -0700 |
| commit | e761050fb44b28c0641dd87f5fbc9d1511bed92b (patch) | |
| tree | 06c271b829a58daf1087db37f1c3632b890d51ee /api/src/glfs-internal.h | |
| parent | 450a853f0059a7ed076253caa982913b08d0485b (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-internal.h')
| -rw-r--r-- | api/src/glfs-internal.h | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h index dbf17918888..e1b8c8ac5f2 100644 --- a/api/src/glfs-internal.h +++ b/api/src/glfs-internal.h @@ -16,6 +16,7 @@ #include "glusterfs.h" #include "upcall-utils.h" #include "glfs-handles.h" +#include "refcount.h" #define GLFS_SYMLINK_MAX_FOLLOW 2048 @@ -208,9 +209,20 @@ struct glfs { uint32_t pthread_flags; /* GLFS_INIT_* # defines set this flag */ }; +/* This enum is used to maintain the state of glfd. In case of async fops + * fd might be closed before the actual fop is complete. Therefore we need + * to track whether the fd is closed or not, instead actually closing it.*/ +enum glfs_fd_state { + GLFD_INIT, + GLFD_OPEN, + GLFD_CLOSE +}; + struct glfs_fd { struct list_head openfds; + GF_REF_DECL; struct glfs *fs; + enum glfs_fd_state state; off_t offset; fd_t *fd; /* Currently guared by @fs->mutex. TODO: per-glfd lock */ struct list_head entries; @@ -269,7 +281,8 @@ do { \ #define __GLFS_ENTRY_VALIDATE_FD(glfd, label) \ do { \ - if (!glfd || !glfd->fd || !glfd->fd->inode) { \ + if (!glfd || !glfd->fd || !glfd->fd->inode || \ + glfd->state != GLFD_OPEN) { \ errno = EBADF; \ goto label; \ } \ @@ -308,9 +321,6 @@ glfs_unlock (struct glfs *fs) pthread_mutex_unlock (&fs->mutex); } - -void glfs_fd_destroy (struct glfs_fd *glfd); - struct glfs_fd *glfs_fd_new (struct glfs *fs); void glfs_fd_bind (struct glfs_fd *glfd); |
