diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-01-22 19:47:47 -0500 |
---|---|---|
committer | Mike Marshall <hubcap@omnibond.com> | 2016-01-23 13:03:12 -0500 |
commit | ed42fe059389daa35a2aa10ec832e9f8d0a9e59e (patch) | |
tree | 778e6ebb516e7a6301305b077e31ee40d9fe96c2 /fs/orangefs/file.c | |
parent | fee25ce12504ff071254fd213055c3f1d3004622 (diff) | |
download | linux-stable-ed42fe059389daa35a2aa10ec832e9f8d0a9e59e.tar.gz linux-stable-ed42fe059389daa35a2aa10ec832e9f8d0a9e59e.tar.bz2 linux-stable-ed42fe059389daa35a2aa10ec832e9f8d0a9e59e.zip |
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>
Diffstat (limited to 'fs/orangefs/file.c')
-rw-r--r-- | fs/orangefs/file.c | 17 |
1 files changed, 5 insertions, 12 deletions
diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 171013ae0036..df3404ba60af 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -105,10 +105,9 @@ static ssize_t wait_for_direct_io(enum ORANGEFS_io_type type, struct inode *inod ssize_t ret; new_op = op_alloc(ORANGEFS_VFS_OP_FILE_IO); - if (!new_op) { - ret = -ENOMEM; - goto out; - } + if (!new_op) + return -ENOMEM; + /* synchronous I/O */ new_op->upcall.req.io.async_vfs_io = ORANGEFS_VFS_SYNC_IO; new_op->upcall.req.io.readahead_size = readahead_size; @@ -234,12 +233,9 @@ populate_shared_memory: /* * tell the device file owner waiting on I/O that this read has - * completed and it can return now. in this exact case, on - * wakeup the daemon will free the op, so we *cannot* touch it - * after this. + * completed and it can return now. */ wake_up_daemon_for_return(new_op); - new_op = NULL; out: if (buffer_index >= 0) { @@ -249,10 +245,7 @@ out: __func__, handle, buffer_index); buffer_index = -1; } - if (new_op) { - op_release(new_op); - new_op = NULL; - } + op_release(new_op); return ret; } |