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/orangefs-sysfs.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'fs/orangefs/orangefs-sysfs.c') diff --git a/fs/orangefs/orangefs-sysfs.c b/fs/orangefs/orangefs-sysfs.c index 3d360383ea22..83f4053bd11b 100644 --- a/fs/orangefs/orangefs-sysfs.c +++ b/fs/orangefs/orangefs-sysfs.c @@ -773,10 +773,8 @@ static int sysfs_service_op_show(char *kobj_id, char *buf, void *attr) op_alloc_type = ORANGEFS_VFS_OP_PERF_COUNT; new_op = op_alloc(op_alloc_type); - if (!new_op) { - rc = -ENOMEM; - goto out; - } + if (!new_op) + return -ENOMEM; /* Can't do a service_operation if the client is not running... */ rc = is_daemon_in_service(); @@ -931,11 +929,7 @@ out: } } - /* - * if we got ENOMEM, then op_alloc probably failed... - */ - if (rc != -ENOMEM) - op_release(new_op); + op_release(new_op); return rc; @@ -1039,10 +1033,8 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) kobj_id); new_op = op_alloc(ORANGEFS_VFS_OP_PARAM); - if (!new_op) { - rc = -ENOMEM; - goto out; - } + if (!new_op) + return -EINVAL; /* sic */ /* Can't do a service_operation if the client is not running... */ rc = is_daemon_in_service(); @@ -1269,15 +1261,9 @@ static int sysfs_service_op_store(char *kobj_id, const char *buf, void *attr) } out: - /* - * if we got ENOMEM, then op_alloc probably failed... - */ - if (rc == -ENOMEM) - rc = 0; - else - op_release(new_op); + op_release(new_op); - if (rc == 0) + if (rc == -ENOMEM || rc == 0) rc = -EINVAL; return rc; -- cgit