summaryrefslogtreecommitdiffstats
path: root/fs/orangefs/orangefs-sysfs.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2016-01-22 19:47:47 -0500
committerMike Marshall <hubcap@omnibond.com>2016-01-23 13:03:12 -0500
commited42fe059389daa35a2aa10ec832e9f8d0a9e59e (patch)
tree778e6ebb516e7a6301305b077e31ee40d9fe96c2 /fs/orangefs/orangefs-sysfs.c
parentfee25ce12504ff071254fd213055c3f1d3004622 (diff)
downloadlinux-ed42fe059389daa35a2aa10ec832e9f8d0a9e59e.tar.gz
linux-ed42fe059389daa35a2aa10ec832e9f8d0a9e59e.tar.bz2
linux-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/orangefs-sysfs.c')
-rw-r--r--fs/orangefs/orangefs-sysfs.c28
1 files changed, 7 insertions, 21 deletions
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;