alistair23-linux/fs/kernfs
Tejun Heo d92d2e6bd7 kernfs: fix get_active failure handling in kernfs_seq_*()
When kernfs_seq_start() fails to obtain an active reference, it
returns ERR_PTR(-ENODEV).  kernfs_seq_stop() is then invoked with the
error pointer value; however, it still proceeds to invoke
kernfs_put_active() on the node leading to unbalanced put.

If kernfs_seq_stop() is called even after active ref failure, it
should skip invocation of @ops->seq_stop() and put_active.
Unfortunately, this is a bit complicated because active ref failure
isn't the only thing which may fail with ERR_PTR(-ENODEV).
@ops->seq_start/next() may also fail with the error value and
kernfs_seq_stop() doesn't have a way to tell apart those failures.

Work it around by factoring out the active part of kernfs_seq_stop()
into kernfs_seq_stop_active() and invoking it directly if
@ops->seq_start/next() fail with ERR_PTR(-ENODEV) and updating
kernfs_seq_stop() to skip kernfs_seq_stop_active() on
ERR_PTR(-ENODEV).  This is a bit nasty but ensures that the active put
is skipped iff get_active failed in kernfs_seq_start().

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2014-01-10 13:44:25 -08:00
..
dir.c kernfs: add kernfs_dir_ops 2013-12-17 08:59:15 -08:00
file.c kernfs: fix get_active failure handling in kernfs_seq_*() 2014-01-10 13:44:25 -08:00
inode.c kernfs: s/sysfs/kernfs/ in internal functions and whatever is left 2013-12-11 17:39:20 -08:00
kernfs-internal.h kernfs: mark static names with KERNFS_STATIC_NAME 2013-12-17 08:59:15 -08:00
Makefile
mount.c kernfs: s/sysfs/kernfs/ in internal functions and whatever is left 2013-12-11 17:39:20 -08:00
symlink.c kernfs: s/sysfs/kernfs/ in internal functions and whatever is left 2013-12-11 17:39:20 -08:00