From ed42fe059389daa35a2aa10ec832e9f8d0a9e59e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 22 Jan 2016 19:47:47 -0500 Subject: orangefs: hopefully saner op refcounting and locking * create with refcount 1 * make op_release() decrement and free if zero (i.e. old put_op() has become that). * mark when submitter has given up waiting; from that point nobody else can move between the lists, change state, etc. * have daemon read/write_iter grab a reference when picking op and *always* give it up in the end * don't put into hash until we know it's been successfully passed to daemon * move op->lock _lower_ than htab_in_progress_lock (and make sure to take it in purge_inprogress_ops()) Signed-off-by: Al Viro Signed-off-by: Mike Marshall --- fs/orangefs/waitqueue.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) (limited to 'fs/orangefs/waitqueue.c') diff --git a/fs/orangefs/waitqueue.c b/fs/orangefs/waitqueue.c index a257891dd3ea..2e9468f57981 100644 --- a/fs/orangefs/waitqueue.c +++ b/fs/orangefs/waitqueue.c @@ -279,25 +279,6 @@ retry_servicing: return ret; } -static inline void remove_op_from_request_list(struct orangefs_kernel_op_s *op) -{ - struct list_head *tmp = NULL; - struct list_head *tmp_safe = NULL; - struct orangefs_kernel_op_s *tmp_op = NULL; - - spin_lock(&orangefs_request_list_lock); - list_for_each_safe(tmp, tmp_safe, &orangefs_request_list) { - tmp_op = list_entry(tmp, - struct orangefs_kernel_op_s, - list); - if (tmp_op && (tmp_op == op)) { - list_del(&tmp_op->list); - break; - } - } - spin_unlock(&orangefs_request_list_lock); -} - static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s *op) { /* @@ -334,6 +315,7 @@ static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s } spin_lock(&op->lock); + op->op_state |= OP_VFS_STATE_GIVEN_UP; if (op_state_waiting(op)) { /* @@ -341,7 +323,9 @@ static void orangefs_clean_up_interrupted_operation(struct orangefs_kernel_op_s * list. */ spin_unlock(&op->lock); - remove_op_from_request_list(op); + spin_lock(&orangefs_request_list_lock); + list_del(&op->list); + spin_unlock(&orangefs_request_list_lock); gossip_debug(GOSSIP_WAIT_DEBUG, "Interrupted: Removed op %p from request_list\n", op); -- cgit