summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/features/locks/src/common.c15
-rw-r--r--xlators/features/locks/src/locks.h11
-rw-r--r--xlators/features/locks/src/posix.c97
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 = {