diff options
author | Soumya Koduri <skoduri@redhat.com> | 2017-04-21 16:30:20 +0530 |
---|---|---|
committer | Jeff Darcy <jeff@pl.atyp.us> | 2017-05-02 23:33:13 +0000 |
commit | 41000cd0b57a81c4ace4a1d3da0fcc352a11f146 (patch) | |
tree | b8bebcf014eca1e2c1c493316ce7634c2f3a292a /api/src/glfs.h | |
parent | 316e3300cfaa646b7fa45fcc7f57b81c7bb15a0e (diff) |
gfapi/handleops: Introducing glfs_xreaddirplus_r() fop for handleops
Its known that readdirplus operation fetches stat as well for each of the
dirents. But often applications may need extra information, like for eg.,
NFS-Ganesha which operates on handles needs handles for each of those
dirents returned. So this would require extra calls to the backend, in this
case LOOKUP (which is very expensive operation) resulting in very low
readdir performance.
To address that introducing this new API using which applications can
make request for any extra information to be returned as part of
readdirplus response.
Currently this new api returns stat and handles as demanded by application.
The synopsis of the API is noted in glfs.h.
@todo:
* Enhance test script using this new API
Below were the perf results on single brick volume with and without
these changes -
Dataset used -
10*100 directories and each directory containing 100 empty files.
I used NFS-Ganesha application to test these changes -
>for i in {1..5}; do systemctl restart nfs-ganesha; sleep 10; mount -t nfs -o vers=4 localhost:/brick_vol /mnt; cd /mnt; echo "ITERATION$i"; date; find . > tmp-nfs.log; date; cd /; umount /mnt; sleep 2; done;
Without these changes -
ITERATION1
Mon Mar 20 17:22:26 IST 2017
Mon Mar 20 17:23:18 IST 2017
ITERATION2
Mon Mar 20 17:23:39 IST 2017
Mon Mar 20 17:24:28 IST 2017
ITERATION3
Mon Mar 20 17:24:49 IST 2017
Mon Mar 20 17:25:36 IST 2017
ITERATION4
Mon Mar 20 17:30:57 IST 2017
Mon Mar 20 17:31:37 IST 2017
ITERATION5
Mon Mar 20 17:31:57 IST 2017
Mon Mar 20 17:32:40 IST 2017
[root@dhcp35-197 /]#
On an average ~46.2 sec
With these changes applied -
ITERATION1
Mon Mar 20 17:35:03 IST 2017
Mon Mar 20 17:35:15 IST 2017
ITERATION2
Mon Mar 20 17:35:36 IST 2017
Mon Mar 20 17:35:46 IST 2017
ITERATION3
Mon Mar 20 17:36:06 IST 2017
Mon Mar 20 17:36:17 IST 2017
ITERATION4
Mon Mar 20 17:41:38 IST 2017
Mon Mar 20 17:41:49 IST 2017
ITERATION5
Mon Mar 20 17:42:10 IST 2017
Mon Mar 20 17:42:20 IST 2017
On an average ~10.8 sec
Updates #174
BUG: 1442950
Change-Id: I0f74f74dc62085ca4c4a23c38e3edc84bd850876
Signed-off-by: Soumya Koduri <skoduri@redhat.com>
Reviewed-on: https://review.gluster.org/15663
Smoke: Gluster Build System <jenkins@build.gluster.org>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Niels de Vos <ndevos@redhat.com>
CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
Diffstat (limited to 'api/src/glfs.h')
-rw-r--r-- | api/src/glfs.h | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/api/src/glfs.h b/api/src/glfs.h index 68fcf4ddcd9..4e535bda168 100644 --- a/api/src/glfs.h +++ b/api/src/glfs.h @@ -41,6 +41,7 @@ #include <sys/cdefs.h> #include <dirent.h> #include <sys/statvfs.h> +#include <inttypes.h> #if defined(HAVE_SYS_ACL_H) || (defined(USE_POSIX_ACLS) && USE_POSIX_ACLS) #include <sys/acl.h> @@ -790,6 +791,71 @@ int glfs_sysrq (glfs_t *fs, char sysrq) __THROW /* + * Structure returned as part of xreaddirplus + */ +struct glfs_xreaddirp_stat; + +/* Request flags to be used in XREADDIRP operation */ +#define GFAPI_XREADDIRP_NULL 0x00000000 /* by default, no stat will be fetched */ +#define GFAPI_XREADDIRP_STAT 0x00000001 /* Get stat */ +#define GFAPI_XREADDIRP_HANDLE 0x00000002 /* Get object handle */ + +/* + * This stat structure returned gets freed as part of glfs_free(xstat) + */ +struct stat* +glfs_xreaddirplus_get_stat (struct glfs_xreaddirp_stat *xstat) __THROW + GFAPI_PUBLIC(glfs_xreaddirplus_get_stat, 3.11.0); + +/* + * SYNOPSIS + * + * glfs_xreaddirplus_r: Extended Readirplus operation + * + * DESCRIPTION + * + * This API does readdirplus operation, but along with stat it can fetch other + * extra information like object handles etc for each of the dirents returned + * based on requested flags. On success it returns the set of flags successfully + * processed. + * + * Note that there are chances that some of the requested information may not be + * available or returned (for example if reached EOD). Ensure to validate the + * returned value to determine what flags have been successfully processed + * & set. + * + * PARAMETERS + * + * INPUT: + * @glfd: GFAPI file descriptor of the directory + * @flags: Flags determining xreaddirp_stat requested + * Current available values are: + * GFAPI_XREADDIRP_NULL + * GFAPI_XREADDIRP_STAT + * GFAPI_XREADDIRP_HANDLE + * @ext: Dirent struture to copy the values to + * (though optional recommended to be allocated by application + * esp., in multi-threaded environement) + * + * OUTPUT: + * @res: to store the next dirent value. If NULL and return value is '0', + * it means it reached end of the directory. + * @xstat_p: Pointer to contain all the requested data returned + * for that dirent. Application should make use of glfs_free() API + * to free this pointer and the variables returned by + * glfs_xreaddirplus_get_*() APIs. + * + * RETURN VALUE: + * >=0: SUCCESS (value contains the flags successfully processed) + * -1: FAILURE + */ +int +glfs_xreaddirplus_r (struct glfs_fd *glfd, uint32_t flags, + struct glfs_xreaddirp_stat **xstat_p, + struct dirent *ext, struct dirent **res); + GFAPI_PUBLIC(glfs_xreaddirplus_r, 3.11.0); + +/* * Nobody needs this call at all yet except for the test script. */ int glfs_ipc (glfs_fd_t *fd, int cmd, void *xd_in, void **xd_out) __THROW |