diff options
Diffstat (limited to 'xlators/features/locks/src/clear.c')
| -rw-r--r-- | xlators/features/locks/src/clear.c | 117 |
1 files changed, 66 insertions, 51 deletions
diff --git a/xlators/features/locks/src/clear.c b/xlators/features/locks/src/clear.c index a7b2455e3..124b9ad0f 100644 --- a/xlators/features/locks/src/clear.c +++ b/xlators/features/locks/src/clear.c @@ -1,22 +1,12 @@ /* - Copyright (c) 2006-2011 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ + Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ #include <unistd.h> #include <fcntl.h> #include <limits.h> @@ -141,15 +131,15 @@ clrlk_parse_args (const char* cmd, clrlk_args *args) if ((args->type == CLRLK_TYPE_MAX) || (args->kind == CLRLK_KIND_MAX)) goto out; - /*optional args*/ - tok = strtok_r (NULL, ".", &sptr); + /*optional args, neither range nor basename can 'legally' contain + * "/" in them*/ + tok = strtok_r (NULL, "/", &sptr); if (tok) args->opts = gf_strdup (tok); ret = 0; out: - if (free_ptr) - GF_FREE (free_ptr); + GF_FREE (free_ptr); return ret; } @@ -193,8 +183,8 @@ clrlk_clear_posixlk (xlator_t *this, pl_inode_t *pl_inode, clrlk_args *args, F_SETLKW, &plock->user_flock, -1, EAGAIN, NULL); - STACK_UNWIND (plock->frame, -1, EAGAIN, - &plock->user_flock); + STACK_UNWIND_STRICT (lk, plock->frame, -1, EAGAIN, + &plock->user_flock, NULL); } else { gcount++; @@ -204,6 +194,7 @@ clrlk_clear_posixlk (xlator_t *this, pl_inode_t *pl_inode, clrlk_args *args, } pthread_mutex_unlock (&pl_inode->mutex); grant_blocked_locks (this, pl_inode); + ret = 0; out: *blkd = bcount; *granted = gcount; @@ -222,7 +213,9 @@ clrlk_clear_inodelk (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom, int bcount = 0; int gcount = 0; gf_boolean_t chk_range = _gf_false; + struct list_head released; + INIT_LIST_HEAD (&released); if (clrlk_get_lock_range (args->opts, &ulock, &chk_range)) { *op_errno = EINVAL; goto out; @@ -246,17 +239,23 @@ blkd: continue; bcount++; - list_del_init (&ilock->list); - pl_trace_out (this, ilock->frame, NULL, NULL, F_SETLKW, - &ilock->user_flock, -1, EAGAIN, - ilock->volume); - STACK_UNWIND_STRICT (inodelk, ilock->frame, -1, - EAGAIN); - GF_FREE (ilock); + list_del_init (&ilock->blocked_locks); + list_add (&ilock->blocked_locks, &released); } } pthread_mutex_unlock (&pl_inode->mutex); + list_for_each_entry_safe (ilock, tmp, &released, blocked_locks) { + list_del_init (&ilock->blocked_locks); + pl_trace_out (this, ilock->frame, NULL, NULL, F_SETLKW, + &ilock->user_flock, -1, EAGAIN, + ilock->volume); + STACK_UNWIND_STRICT (inodelk, ilock->frame, -1, + EAGAIN, NULL); + //No need to take lock as the locks are only in one list + __pl_inodelk_unref (ilock); + } + if (!(args->kind & CLRLK_GRANTED)) { ret = 0; goto out; @@ -275,14 +274,20 @@ granted: gcount++; list_del_init (&ilock->list); - GF_FREE (ilock); + list_add (&ilock->list, &released); } } pthread_mutex_unlock (&pl_inode->mutex); - grant_blocked_inode_locks (this, pl_inode, dom); + list_for_each_entry_safe (ilock, tmp, &released, list) { + list_del_init (&ilock->list); + //No need to take lock as the locks are only in one list + __pl_inodelk_unref (ilock); + } + ret = 0; out: + grant_blocked_inode_locks (this, pl_inode, dom); *blkd = bcount; *granted = gcount; return ret; @@ -295,11 +300,13 @@ clrlk_clear_entrylk (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom, { pl_entry_lock_t *elock = NULL; pl_entry_lock_t *tmp = NULL; - struct list_head removed = {0}; int bcount = 0; int gcount = 0; int ret = -1; + struct list_head removed; + struct list_head released; + INIT_LIST_HEAD (&released); if (args->kind & CLRLK_BLOCKED) goto blkd; @@ -311,21 +318,31 @@ blkd: { list_for_each_entry_safe (elock, tmp, &dom->blocked_entrylks, blocked_locks) { - if (args->opts && - strncmp (elock->basename, args->opts, - strlen (elock->basename))) - continue; + if (args->opts) { + if (!elock->basename || + strcmp (elock->basename, args->opts)) + continue; + } bcount++; - list_del_init (&elock->domain_list); - STACK_UNWIND_STRICT (entrylk, elock->frame, -1, - EAGAIN); - GF_FREE ((char *) elock->basename); - GF_FREE (elock); + + list_del_init (&elock->blocked_locks); + list_add_tail (&elock->blocked_locks, &released); } } pthread_mutex_unlock (&pl_inode->mutex); + list_for_each_entry_safe (elock, tmp, &released, blocked_locks) { + list_del_init (&elock->blocked_locks); + entrylk_trace_out (this, elock->frame, elock->volume, NULL, NULL, + elock->basename, ENTRYLK_LOCK, elock->type, + -1, EAGAIN); + STACK_UNWIND_STRICT (entrylk, elock->frame, -1, EAGAIN, NULL); + GF_FREE ((char *) elock->basename); + GF_FREE (elock->connection_id); + GF_FREE (elock); + } + if (!(args->kind & CLRLK_GRANTED)) { ret = 0; goto out; @@ -337,13 +354,11 @@ granted: { list_for_each_entry_safe (elock, tmp, &dom->entrylk_list, domain_list) { - if (!elock->basename) - continue; - - if (args->opts && - strncmp (elock->basename, args->opts, - strlen (elock->basename))) - continue; + if (args->opts) { + if (!elock->basename || + strcmp (elock->basename, args->opts)) + continue; + } gcount++; list_del_init (&elock->domain_list); @@ -365,8 +380,8 @@ out: int clrlk_clear_lks_in_all_domains (xlator_t *this, pl_inode_t *pl_inode, - clrlk_args *args, int *blkd, int *granted, - int *op_errno) + clrlk_args *args, int *blkd, int *granted, + int *op_errno) { pl_dom_list_t *dom = NULL; int ret = -1; |
