From 19fe3906c13ad360c07bb94db6b7f63024b30ef1 Mon Sep 17 00:00:00 2001 From: Soumya Koduri Date: Tue, 17 Oct 2017 16:12:06 +0530 Subject: gfapi: set lkowner in glfd We need a provision to be able to set lkowner (which is used to distinguish locks maintained by server) in gfapi. Since the same lk_owner need to be used to be able to flush the lock while closing the fd, store the lkowner in the glfd structure itself. A new API has been added to be able to set lkowner in glfd. This is backport of below mainline fix - https://review.gluster.org/#/c/18429 https://review.gluster.org/#/c/18522/ Change-Id: I67591d6b9a89c20b9617d52616513ff9e6c06b47 BUG: 1501956 Signed-off-by: Soumya Koduri --- api/src/gfapi.aliases | 1 + api/src/gfapi.map | 7 ++++++- api/src/glfs-fops.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ api/src/glfs-internal.h | 1 + api/src/glfs.h | 28 +++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 1 deletion(-) (limited to 'api') diff --git a/api/src/gfapi.aliases b/api/src/gfapi.aliases index b0facb717b3..85e8448982d 100644 --- a/api/src/gfapi.aliases +++ b/api/src/gfapi.aliases @@ -156,6 +156,7 @@ _pub_glfs_upcall_inode_get_oldpstat _glfs_upcall_inode_get_oldpstat$GFAPI_3.7.16 _pub_glfs_realpath _glfs_realpath$GFAPI_3.7.17 _pub_glfs_sysrq _glfs_sysrq$GFAPI_3.10.0 +_pub_glfs_fd_set_lkowner _glfs_fd_set_lkowner$GFAPI_3.10.7 _pub_glfs_xreaddirplus_r _glfs_xreaddirplus_r$GFAPI_3.11.0 _pub_glfs_xreaddirplus_r_get_stat _glfs_xreaddirplus_r_get_stat$GFAPI_3.11.0 diff --git a/api/src/gfapi.map b/api/src/gfapi.map index 7f19e1ee4f9..88673007d25 100644 --- a/api/src/gfapi.map +++ b/api/src/gfapi.map @@ -198,12 +198,17 @@ GFAPI_3.10.0 { glfs_sysrq; } GFAPI_3.7.17; +GFAPI_3.10.7 { + global: + glfs_fd_set_lkowner; +} GFAPI_3.10.0; + GFAPI_3.11.0 { glfs_xreaddirplus_r; glfs_xreaddirplus_r_get_stat; glfs_xreaddirplus_r_get_object; glfs_object_copy; -} GFAPI_3.10.0; +} GFAPI_3.10.7; GFAPI_PRIVATE_3.12.0 { global: diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c index c8ddeea196e..7fb86fc859f 100644 --- a/api/src/glfs-fops.c +++ b/api/src/glfs-fops.c @@ -267,6 +267,12 @@ pub_glfs_close (struct glfs_fd *glfd) goto out; } + if (glfd->lk_owner.len != 0) { + ret = syncopctx_setfslkowner (&glfd->lk_owner); + if (ret) + goto out; + } + ret = syncop_flush (subvol, fd, NULL, NULL); DECODE_SYNCOP_ERR (ret); out: @@ -4272,6 +4278,14 @@ pub_glfs_posix_lock (struct glfs_fd *glfd, int cmd, struct flock *flock) gf_flock_from_flock (&gf_flock, flock); gf_flock_from_flock (&saved_flock, flock); + + if (glfd->lk_owner.len != 0) { + ret = syncopctx_setfslkowner (&glfd->lk_owner); + + if (ret) + goto out; + } + ret = syncop_lk (subvol, fd, cmd, &gf_flock, NULL, NULL); DECODE_SYNCOP_ERR (ret); gf_flock_to_flock (&gf_flock, flock); @@ -4294,6 +4308,43 @@ invalid_fs: GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_posix_lock, 3.4.0); +int +pub_glfs_fd_set_lkowner (glfs_fd_t *glfd, void *data, int len) +{ + int ret = -1; + + DECLARE_OLD_THIS; + __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs); + + if (!GF_REF_GET (glfd)) { + goto invalid_fs; + } + + GF_VALIDATE_OR_GOTO (THIS->name, data, out); + + if ((len <= 0) || (len > GFAPI_MAX_LOCK_OWNER_LEN)) { + errno = EINVAL; + gf_msg (THIS->name, GF_LOG_ERROR, errno, + LG_MSG_INVALID_ARG, + "Invalid lk_owner len (%d)", len); + goto out; + } + + glfd->lk_owner.len = len; + + memcpy (glfd->lk_owner.data, data, len); + + ret = 0; +out: + if (glfd) + GF_REF_PUT (glfd); + + __GLFS_EXIT_FS; + +invalid_fs: + return ret; +} +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_fd_set_lkowner, 3.10.7); struct glfs_fd * pub_glfs_dup (struct glfs_fd *glfd) diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h index 180981830d7..c94fcd9078d 100644 --- a/api/src/glfs-internal.h +++ b/api/src/glfs-internal.h @@ -215,6 +215,7 @@ struct glfs_fd { struct list_head entries; gf_dirent_t *next; struct dirent *readdirbuf; + gf_lkowner_t lk_owner; }; /* glfs object handle introduced for the alternate gfapi implementation based diff --git a/api/src/glfs.h b/api/src/glfs.h index 5420a1dde66..ec3258d083a 100644 --- a/api/src/glfs.h +++ b/api/src/glfs.h @@ -855,6 +855,34 @@ glfs_xreaddirplus_r (struct glfs_fd *glfd, uint32_t flags, struct dirent *ext, struct dirent **res); GFAPI_PUBLIC(glfs_xreaddirplus_r, 3.11.0); +#define GFAPI_MAX_LOCK_OWNER_LEN 255 + +/* + * + * DESCRIPTION + * + * This API allows application to set lk_owner on a fd. + * A glfd can be associated with only single lk_owner. In case if there + * is need to set another lk_owner, applications can make use of + * 'glfs_dup' to get duplicate glfd and set new lk_owner on that second + * glfd. + * + * Also its not recommended to override or clear lk_owner value as the + * same shall be used to flush any outstanding locks while closing the fd. + * + * PARAMETERS + * + * INPUT: + * @glfd: GFAPI file descriptor + * @len: Size of lk_owner buffer. Max value can be GFAPI_MAX_LOCK_OWNER_LEN + * @data: lk_owner data buffer. + * + * OUTPUT: + * 0: SUCCESS + * -1: FAILURE + */ +int glfs_fd_set_lkowner (glfs_fd_t *glfd, void *data, int len); + GFAPI_PUBLIC(glfs_fd_set_lkowner, 3.10.7); __END_DECLS #endif /* !_GLFS_H */ -- cgit