diff options
| author | Anoop C S <anoopcs@redhat.com> | 2016-01-19 14:35:18 +0530 | 
|---|---|---|
| committer | Niels de Vos <ndevos@redhat.com> | 2018-01-22 09:54:02 +0000 | 
| commit | ec3df9e65a3a2e1005cd4d50d06a8819fd3ab5f6 (patch) | |
| tree | 847ac98b10927e4e1081ba35260beb4b18996d47 /api/src/glfs-fops.c | |
| parent | 10d74166f17fa44c06bd1357e0a4b0b052265425 (diff) | |
libgfapi: Add new api for supporting mandatory-locks
The current API for byte-range locks [glfs_posix_lock()] doesn't
allow applications to specify whether it is advisory or mandatory
type locks. This particular change is to introduce an extended
byte-range lock API with an additional argument for including
the byte-range lock mode to be one among advisory(default) or
mandatory. Patch also includes a gfapi test case which make use
of this new api to acquire mandatory locks.
Ref: https://github.com/gluster/glusterfs-specs/blob/master/done/GlusterFS%203.8/Mandatory%20Locks.md
Change-Id: Ia09042c755d891895d96da857321abc4ce03e20c
Updates #393
Signed-off-by: Anoop C S <anoopcs@redhat.com>
Diffstat (limited to 'api/src/glfs-fops.c')
| -rw-r--r-- | api/src/glfs-fops.c | 128 | 
1 files changed, 97 insertions, 31 deletions
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c index 287326c4e4a..833ff336634 100644 --- a/api/src/glfs-fops.c +++ b/api/src/glfs-fops.c @@ -4250,36 +4250,46 @@ gf_flock_from_flock (struct gf_flock *gf_flock, struct flock *flock)  	gf_flock->l_pid    = flock->l_pid;  } - -int -pub_glfs_posix_lock (struct glfs_fd *glfd, int cmd, struct flock *flock) +static int +glfs_lock_common (struct glfs_fd *glfd, int cmd, struct flock *flock, +                  dict_t *xdata)  { -	int              ret = -1; -	xlator_t        *subvol = NULL; -	struct gf_flock  gf_flock = {0, }; -	struct gf_flock  saved_flock = {0, }; -	fd_t            *fd = NULL; +        int              ret = -1; +        xlator_t        *subvol = NULL; +        struct gf_flock  gf_flock = {0, }; +        struct gf_flock  saved_flock = {0, }; +        fd_t            *fd = NULL;          DECLARE_OLD_THIS; -	__GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs); +        __GLFS_ENTRY_VALIDATE_FD (glfd, invalid_fs); + +        if (!flock) { +                errno = EINVAL; +                goto out; +        }          GF_REF_GET (glfd); -	subvol = glfs_active_subvol (glfd->fs); -	if (!subvol) { -		ret = -1; -		errno = EIO; -		goto out; -	} +        subvol = glfs_active_subvol (glfd->fs); +        if (!subvol) { +                ret = -1; +                errno = EIO; +                goto out; +        } -	fd = glfs_resolve_fd (glfd->fs, subvol, glfd); -	if (!fd) { -		ret = -1; -		errno = EBADFD; -		goto out; -	} +        fd = glfs_resolve_fd (glfd->fs, subvol, glfd); +        if (!fd) { +                ret = -1; +                errno = EBADFD; +                goto out; +        } + +        /* Generate glusterfs flock structure from client flock +         * structure to be processed by server */ +        gf_flock_from_flock (&gf_flock, flock); -	gf_flock_from_flock (&gf_flock, flock); -	gf_flock_from_flock (&saved_flock, flock); +        /* Keep another copy of flock for split/merge of locks +         * at client side */ +        gf_flock_from_flock (&saved_flock, flock);          if (glfd->lk_owner.len != 0) {                  ret = syncopctx_setfslkowner (&glfd->lk_owner); @@ -4288,24 +4298,80 @@ pub_glfs_posix_lock (struct glfs_fd *glfd, int cmd, struct flock *flock)                          goto out;          } -	ret = syncop_lk (subvol, fd, cmd, &gf_flock, NULL, NULL); +        ret = syncop_lk (subvol, fd, cmd, &gf_flock, xdata, NULL);          DECODE_SYNCOP_ERR (ret); -	gf_flock_to_flock (&gf_flock, flock); -	if (ret == 0 && (cmd == F_SETLK || cmd == F_SETLKW)) -		fd_lk_insert_and_merge (fd, cmd, &saved_flock); +        /* Convert back from gf_flock to flock as expected by application */ +        gf_flock_to_flock (&gf_flock, flock); + +        if (ret == 0 && (cmd == F_SETLK || cmd == F_SETLKW)) { +                ret = fd_lk_insert_and_merge (fd, cmd, &saved_flock); +                if (ret) { +                        gf_msg (THIS->name, GF_LOG_ERROR, 0, +                                API_MSG_LOCK_INSERT_MERGE_FAILED, +                                "Lock insertion and splitting/merging failed " +                                "on gfid %s", uuid_utoa (fd->inode->gfid)); +                        ret = 0; +                } +        } +  out: -	if (fd) -		fd_unref (fd); +        if (fd) +                fd_unref (fd);          if (glfd)                  GF_REF_PUT (glfd); -	glfs_subvol_done (glfd->fs, subvol); +        glfs_subvol_done (glfd->fs, subvol);          __GLFS_EXIT_FS;  invalid_fs: -	return ret; +        return ret; +} + +int +pub_glfs_file_lock (struct glfs_fd *glfd, int cmd, struct flock *flock, +                    enum glfs_lock_mode_t lk_mode) +{ +        int              ret            = -1; +        dict_t          *xdata_in       = NULL; + +        if (lk_mode == GLFS_LK_MANDATORY) { +                /* Create a new dictionary */ +                xdata_in = dict_new (); +                if (xdata_in == NULL) { +                        ret = -1; +                        errno = ENOMEM; +                        goto out; +                } + +                /* Set GF_LK_MANDATORY internally within dictionary to map +                 * GLFS_LK_MANDATORY */ +                ret = dict_set_uint32 (xdata_in, GF_LOCK_MODE, GF_LK_MANDATORY); +                if (ret) { +                        gf_msg (THIS->name, GF_LOG_ERROR, 0, +                                API_MSG_SETTING_LOCK_TYPE_FAILED, +                                "Setting lock type failed"); +                        ret = -1; +                        errno = ENOMEM; +                        goto out; +                } +        } + +        ret = glfs_lock_common (glfd, cmd, flock, xdata_in); +out: +        if (xdata_in) +                dict_unref (xdata_in); + +        return ret; +} + +GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_file_lock, 4.0.0); + +int +pub_glfs_posix_lock (struct glfs_fd *glfd, int cmd, struct flock *flock) +{ +        return glfs_lock_common (glfd, cmd, flock, NULL);  }  GFAPI_SYMVER_PUBLIC_DEFAULT(glfs_posix_lock, 3.4.0);  | 
