aboutsummaryrefslogtreecommitdiffstats
path: root/fs/kernfs/kernfs-internal.h
diff options
context:
space:
mode:
authorTejun Heo <[email protected]>2014-01-10 13:57:18 +0000
committerGreg Kroah-Hartman <[email protected]>2014-01-10 21:44:25 +0000
commitd92d2e6bd72b653f9811e0c9c46307c743b3fc58 (patch)
tree3d9f3207bf1debe9fef016aea5e9eb23af91d8d6 /fs/kernfs/kernfs-internal.h
parentfirmware_class: Fix the file size check (diff)
downloadkernel-d92d2e6bd72b653f9811e0c9c46307c743b3fc58.tar.gz
kernel-d92d2e6bd72b653f9811e0c9c46307c743b3fc58.zip
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 <[email protected]> Cc: Sasha Levin <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
Diffstat (limited to 'fs/kernfs/kernfs-internal.h')
0 files changed, 0 insertions, 0 deletions