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:
@@ -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");
|
||||
|
Reference in New Issue
Block a user