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 <viro@zeniv.linux.org.uk>
Signed-off-by: Mike Marshall <hubcap@omnibond.com>
This commit is contained in:
Al Viro 2016-01-22 19:47:47 -05:00 committed by Mike Marshall
parent fee25ce125
commit ed42fe0593
8 changed files with 107 additions and 143 deletions

View file

@ -120,7 +120,7 @@ struct orangefs_kernel_op_s *op_alloc(__s32 type)
init_waitqueue_head(&new_op->waitq);
init_waitqueue_head(&new_op->io_completion_waitq);
atomic_set(&new_op->ref_count, 0);
atomic_set(&new_op->ref_count, 1);
orangefs_op_initialize(new_op);
@ -149,14 +149,13 @@ struct orangefs_kernel_op_s *op_alloc(__s32 type)
return new_op;
}
void op_release(struct orangefs_kernel_op_s *orangefs_op)
void __op_release(struct orangefs_kernel_op_s *orangefs_op)
{
if (orangefs_op) {
gossip_debug(GOSSIP_CACHE_DEBUG,
"Releasing OP (%p: %llu)\n",
orangefs_op,
llu(orangefs_op->tag));
orangefs_op_initialize(orangefs_op);
kmem_cache_free(op_cache, orangefs_op);
} else {
gossip_err("NULL pointer in op_release\n");