diff options
Diffstat (limited to 'api')
| -rw-r--r-- | api/src/gfapi-messages.h | 4 | ||||
| -rw-r--r-- | api/src/gfapi.aliases | 1 | ||||
| -rw-r--r-- | api/src/gfapi.map | 2 | ||||
| -rw-r--r-- | api/src/glfs-fops.c | 128 | ||||
| -rw-r--r-- | api/src/glfs.h | 44 | 
5 files changed, 147 insertions, 32 deletions
diff --git a/api/src/gfapi-messages.h b/api/src/gfapi-messages.h index 3eedfa7d071..f231ce99a47 100644 --- a/api/src/gfapi-messages.h +++ b/api/src/gfapi-messages.h @@ -73,7 +73,9 @@ GLFS_MSGID(API,          API_MSG_CREATE_HANDLE_FAILED,          API_MSG_INODE_LINK_FAILED,          API_MSG_STATEDUMP_FAILED, -        API_MSG_XREADDIRP_R_FAILED +        API_MSG_XREADDIRP_R_FAILED, +        API_MSG_LOCK_INSERT_MERGE_FAILED, +        API_MSG_SETTING_LOCK_TYPE_FAILED  );  #endif /* !_GFAPI_MESSAGES_H__ */ diff --git a/api/src/gfapi.aliases b/api/src/gfapi.aliases index 41a01f842fd..88d361dc329 100644 --- a/api/src/gfapi.aliases +++ b/api/src/gfapi.aliases @@ -169,3 +169,4 @@ _pub_glfs_upcall_register _glfs_upcall_register$GFAPI_3.13.0  _pub_glfs_upcall_unregister _glfs_upcall_unregister$GFAPI_3.13.0  _pub_glfs_setfsleaseid _glfs_setfsleaseid$GFAPI_4.0.0 +_pub_glfs_file_lock _glfs_file_lock$GFAPI_4.0.0 diff --git a/api/src/gfapi.map b/api/src/gfapi.map index aa30286c01b..fc47a3b8f42 100644 --- a/api/src/gfapi.map +++ b/api/src/gfapi.map @@ -222,5 +222,7 @@ GFAPI_3.13.0 {  } GFAPI_PRIVATE_3.12.0;  GFAPI_4.0.0 { +        global:                  glfs_setfsleaseid; +                glfs_file_lock;  } GFAPI_3.13.0; 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); diff --git a/api/src/glfs.h b/api/src/glfs.h index 42cbfe7ab6c..5ffed1e0853 100644 --- a/api/src/glfs.h +++ b/api/src/glfs.h @@ -774,6 +774,50 @@ char *glfs_realpath (glfs_t *fs, const char *path, char *resolved_path) __THROW  int glfs_posix_lock (glfs_fd_t *fd, int cmd, struct flock *flock) __THROW          GFAPI_PUBLIC(glfs_posix_lock, 3.4.0); +/* +  SYNOPSIS + +  glfs_file_lock: Request extended byte range lock on a file + +  DESCRIPTION + +  This function is capable of requesting either advisory or mandatory type +  byte range locks on a file. + +  Note: To set a unique owner key for locks based on a particular file +  descriptor, make use of glfs_fd_set_lkowner() api to do so before +  requesting lock via this api. This owner key will be further consumed +  by other incoming data modifying file operations via the same file +  descriptor. + +  PARAMETERS + +  @fd: File descriptor + +  @cmd: As specified in man fcntl(2). + +  @flock: As specified in man fcntl(2). + +  @lk_mode: Required lock type from options available with the +            enum glfs_lock_mode_t defined below. + +  RETURN VALUES + +  0   : Success. Lock has been granted. +  -1  : Failure. @errno will be set indicating the type of failure. + + */ + +/* Lock modes used by glfs_file_lock() */ +enum glfs_lock_mode_t { +        GLFS_LK_ADVISORY = 0, +        GLFS_LK_MANDATORY +}; + +int glfs_file_lock (glfs_fd_t *fd, int cmd, struct flock *flock, +                    enum glfs_lock_mode_t lk_mode) __THROW +        GFAPI_PUBLIC(glfs_file_lock, 3.13.0); +  glfs_fd_t *glfs_dup (glfs_fd_t *fd) __THROW          GFAPI_PUBLIC(glfs_dup, 3.4.0);  | 
