diff options
author | Susant Palai <spalai@redhat.com> | 2016-04-17 10:17:42 +0530 |
---|---|---|
committer | Niels de Vos <ndevos@redhat.com> | 2016-05-01 18:04:36 -0700 |
commit | 90a8d15ea9778b5089521767137b14cb52b9a2b3 (patch) | |
tree | 3f9d562aefbc67ac3973c15ca60279bd3c055803 /xlators | |
parent | 2cca000fcc2adbffbb3f5258c57ae564b9e2d51f (diff) |
posix/lock: add getactivelk () fop
Change-Id: I99e41a80854d6f90572df755e14757099ae1236f
BUG: 1326085
Signed-off-by: Susant Palai <spalai@redhat.com>
Reviewed-on: http://review.gluster.org/13995
Reviewed-by: Niels de Vos <ndevos@redhat.com>
Smoke: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/features/locks/src/common.c | 15 | ||||
-rw-r--r-- | xlators/features/locks/src/locks.h | 11 | ||||
-rw-r--r-- | xlators/features/locks/src/posix.c | 97 |
3 files changed, 123 insertions, 0 deletions
diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c index 1c43ef16179..c6db18f6ba8 100644 --- a/xlators/features/locks/src/common.c +++ b/xlators/features/locks/src/common.c @@ -469,6 +469,13 @@ new_posix_lock (struct gf_flock *flock, client_t *client, pid_t client_pid, lock->fl_end = flock->l_start + flock->l_len - 1; lock->client = client; + + lock->client_uid = gf_strdup (client->client_uid); + if (lock->client_uid == NULL) { + GF_FREE (lock); + goto out; + } + lock->fd_num = fd_to_fdnum (fd); lock->fd = fd; lock->client_pid = client_pid; @@ -783,6 +790,7 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock) posix_lock_t *sum = NULL; int i = 0; struct _values v = { .locks = {0, 0, 0} }; + client_t *client = NULL; list_for_each_entry_safe (conf, t, &pl_inode->ext_list, list) { if (conf->blocked) @@ -796,6 +804,9 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock) sum->fl_type = lock->fl_type; sum->client = lock->client; + client = sum->client; + sum->client_uid = + gf_strdup (client->client_uid); sum->fd_num = lock->fd_num; sum->client_pid = lock->client_pid; sum->owner = lock->owner; @@ -814,6 +825,10 @@ __insert_and_merge (pl_inode_t *pl_inode, posix_lock_t *lock) sum->fl_type = conf->fl_type; sum->client = conf->client; + client = sum->client; + sum->client_uid = + gf_strdup (client->client_uid); + sum->fd_num = conf->fd_num; sum->client_pid = conf->client_pid; sum->owner = conf->owner; diff --git a/xlators/features/locks/src/locks.h b/xlators/features/locks/src/locks.h index df42cf560fd..3480027c4c9 100644 --- a/xlators/features/locks/src/locks.h +++ b/xlators/features/locks/src/locks.h @@ -42,6 +42,16 @@ struct __posix_lock { across nodes */ void *client; /* to identify client node */ + + /* This field uniquely identifies the client the lock belongs to. As + * lock migration is handled by rebalance, the client_t object will be + * overwritten by rebalance and can't be deemed as the owner of the + * lock on destination. Hence, the below field is migrated from + * source to destination by lock_migration_info_t and updated on the + * destination. So that on client-server disconnection, server can + * cleanup the locks proper;y. */ + + char *client_uid; gf_lkowner_t owner; pid_t client_pid; /* pid of client process */ }; @@ -145,6 +155,7 @@ struct __pl_inode { inode_t *inode; /* pointer to be used for ref and unref of inode_t as long as there are locks on it */ + gf_boolean_t migrated; }; typedef struct __pl_inode pl_inode_t; diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index 1bebdc568a8..2f3ad957540 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -2278,6 +2278,102 @@ pl_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size, return 0; } +lock_migration_info_t * +gf_mig_info_for_lock (posix_lock_t *lock) +{ + lock_migration_info_t *new = NULL; + + new = GF_CALLOC (1, sizeof (lock_migration_info_t), + gf_common_mt_lock_mig); + if (new == NULL) { + goto out; + } + + INIT_LIST_HEAD (&new->list); + + posix_lock_to_flock (lock, &new->flock); + + new->client_uid = gf_strdup (lock->client_uid); + +out: + return new; +} + +int +pl_fill_active_locks (pl_inode_t *pl_inode, lock_migration_info_t *lmi) +{ + posix_lock_t *temp = NULL; + lock_migration_info_t *newlock = NULL; + int count = 0; + + pthread_mutex_lock (&pl_inode->mutex); + { + if (list_empty (&pl_inode->ext_list)) { + count = 0; + goto out; + } + + list_for_each_entry (temp, &pl_inode->ext_list, list) { + + if (temp->blocked) + continue; + + newlock = gf_mig_info_for_lock (temp); + if (!newlock) { + gf_msg (THIS->name, GF_LOG_ERROR, 0, 0, + "lock_dup failed"); + count = -1; + goto out; + } + + list_add_tail (&newlock->list, &lmi->list); + count++; + } + + /*TODO: Need to implement meta lock/unlock. meta-unlock should + * set this flag. Tracking BZ: 1331720*/ + pl_inode->migrated = _gf_true; + } + +out: + pthread_mutex_unlock (&pl_inode->mutex); + return count; +} + +/* This function reads only active locks */ +static int +pl_getactivelk (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *xdata) +{ + pl_inode_t *pl_inode = NULL; + lock_migration_info_t locks; + int op_ret = 0; + int op_errno = 0; + int count = 0; + + INIT_LIST_HEAD (&locks.list); + + pl_inode = pl_inode_get (this, loc->inode); + if (!pl_inode) { + gf_msg (this->name, GF_LOG_ERROR, 0, 0, + "pl_inode_get failed"); + + op_ret = -1; + op_errno = ENOMEM; + goto out; + } + + count = pl_fill_active_locks (pl_inode, &locks); + + op_ret = count; + +out: + STACK_UNWIND_STRICT (getactivelk, frame, op_ret, op_errno, &locks, + NULL); + + gf_free_mig_locks (&locks); + + return 0; +} void pl_dump_lock (char *str, int size, struct gf_flock *flock, @@ -2869,6 +2965,7 @@ struct xlator_fops fops = { .fgetxattr = pl_fgetxattr, .fsetxattr = pl_fsetxattr, .rename = pl_rename, + .getactivelk = pl_getactivelk, }; struct xlator_dumpops dumpops = { |