diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-05-19 10:03:07 +0300 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-06-01 10:27:38 +0300 |
commit | 4cc987eaff9144182cde88d6d132420c28d3f81b (patch) | |
tree | 15cf7d432599e1e09446462968ef01c4d10a087e /drivers/target/target_core_file.c | |
parent | adf653f92f38e80a78bb77e912d49bcc8055330f (diff) | |
download | linux-4cc987eaff9144182cde88d6d132420c28d3f81b.tar.xz |
target: Drop lun_sep_lock for se_lun->lun_se_dev RCU usage
With se_port and t10_alua_tg_pt_gp_member being absored into se_lun,
there is no need for an extra lock to protect se_lun->lun_se_dev
assignment.
This patch also converts backend drivers to use call_rcu() release
to allow any se_device readers to complete. The call_rcu() instead
of kfree_rcu() is required here because se_device is embedded into
the backend driver specific structure.
Also, convert se_lun->lun_stats to use atomic_long_t within the
target_complete_ok_work() completion callback, and add FIXME for
transport_lookup_tmr_lun() with se_lun->lun_ref.
Finally, update sbp_update_unit_directory() special case usage with
proper rcu_dereference_raw() and configfs symlink comment.
Reported-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Chris Boot <bootc@bootc.net>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/target_core_file.c')
-rw-r--r-- | drivers/target/target_core_file.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 948b61f59a55..238e3a256d04 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -241,6 +241,14 @@ fail: return ret; } +static void fd_dev_call_rcu(struct rcu_head *p) +{ + struct se_device *dev = container_of(p, struct se_device, rcu_head); + struct fd_dev *fd_dev = FD_DEV(dev); + + kfree(fd_dev); +} + static void fd_free_device(struct se_device *dev) { struct fd_dev *fd_dev = FD_DEV(dev); @@ -249,8 +257,7 @@ static void fd_free_device(struct se_device *dev) filp_close(fd_dev->fd_file, NULL); fd_dev->fd_file = NULL; } - - kfree(fd_dev); + call_rcu(&dev->rcu_head, fd_dev_call_rcu); } static int fd_do_rw(struct se_cmd *cmd, struct file *fd, |