2011-07-31 04:52:43 +04:00
/*
* linux / fs / nfs / blocklayout / blocklayoutdm . c
*
* Module for the NFSv4 .1 pNFS block layout driver .
*
* Copyright ( c ) 2007 The Regents of the University of Michigan .
* All rights reserved .
*
* Fred Isaman < iisaman @ umich . edu >
* Andy Adamson < andros @ citi . umich . edu >
*
* permission is granted to use , copy , create derivative works and
* redistribute this software and such derivative works for any purpose ,
* so long as the name of the university of michigan is not used in
* any advertising or publicity pertaining to the use or distribution
* of this software without specific , written prior authorization . if
* the above copyright notice or any other identification of the
* university of michigan is included in any copy of any portion of
* this software , then the disclaimer below must also be included .
*
* this software is provided as is , without representation from the
* university of michigan as to its fitness for any purpose , and without
* warranty by the university of michigan of any kind , either express
* or implied , including without limitation the implied warranties of
* merchantability and fitness for a particular purpose . the regents
* of the university of michigan shall not be liable for any damages ,
* including special , indirect , incidental , or consequential damages ,
* with respect to any claim arising out or in connection with the use
* of the software , even if it has been or is hereafter advised of the
* possibility of such damages .
*/
# include <linux/genhd.h> /* gendisk - used in a dprintk*/
# include <linux/sched.h>
# include <linux/hash.h>
# include "blocklayout.h"
# define NFSDBG_FACILITY NFSDBG_PNFS_LD
2012-01-10 17:04:24 +04:00
static void dev_remove ( struct net * net , dev_t dev )
2011-07-31 04:52:43 +04:00
{
2012-03-11 18:20:31 +04:00
struct bl_pipe_msg bl_pipe_msg ;
struct rpc_pipe_msg * msg = & bl_pipe_msg . msg ;
2011-07-31 04:52:43 +04:00
struct bl_dev_msg bl_umount_request ;
struct bl_msg_hdr bl_msg = {
. type = BL_DEVICE_UMOUNT ,
. totallen = sizeof ( bl_umount_request ) ,
} ;
uint8_t * dataptr ;
DECLARE_WAITQUEUE ( wq , current ) ;
2012-01-10 17:04:24 +04:00
struct nfs_net * nn = net_generic ( net , nfs_net_id ) ;
2011-07-31 04:52:43 +04:00
dprintk ( " Entering %s \n " , __func__ ) ;
2012-03-11 18:20:31 +04:00
bl_pipe_msg . bl_wq = & nn - > bl_wq ;
2012-03-13 21:18:48 +04:00
memset ( msg , 0 , sizeof ( * msg ) ) ;
2013-03-21 05:15:30 +04:00
msg - > len = sizeof ( bl_msg ) + bl_msg . totallen ;
msg - > data = kzalloc ( msg - > len , GFP_NOFS ) ;
2012-03-11 18:20:31 +04:00
if ( ! msg - > data )
2011-07-31 04:52:43 +04:00
goto out ;
memset ( & bl_umount_request , 0 , sizeof ( bl_umount_request ) ) ;
bl_umount_request . major = MAJOR ( dev ) ;
bl_umount_request . minor = MINOR ( dev ) ;
2012-03-11 18:20:31 +04:00
memcpy ( msg - > data , & bl_msg , sizeof ( bl_msg ) ) ;
dataptr = ( uint8_t * ) msg - > data ;
2011-07-31 04:52:43 +04:00
memcpy ( & dataptr [ sizeof ( bl_msg ) ] , & bl_umount_request , sizeof ( bl_umount_request ) ) ;
2012-03-11 18:20:31 +04:00
add_wait_queue ( & nn - > bl_wq , & wq ) ;
if ( rpc_queue_upcall ( nn - > bl_device_pipe , msg ) < 0 ) {
remove_wait_queue ( & nn - > bl_wq , & wq ) ;
2011-07-31 04:52:43 +04:00
goto out ;
}
set_current_state ( TASK_UNINTERRUPTIBLE ) ;
schedule ( ) ;
__set_current_state ( TASK_RUNNING ) ;
2012-03-11 18:20:31 +04:00
remove_wait_queue ( & nn - > bl_wq , & wq ) ;
2011-07-31 04:52:43 +04:00
out :
2012-03-11 18:20:31 +04:00
kfree ( msg - > data ) ;
2011-07-31 04:52:43 +04:00
}
/*
* Release meta device
*/
static void nfs4_blk_metadev_release ( struct pnfs_block_dev * bdev )
{
int rv ;
dprintk ( " %s Releasing \n " , __func__ ) ;
rv = nfs4_blkdev_put ( bdev - > bm_mdev ) ;
if ( rv )
2012-01-26 22:32:23 +04:00
printk ( KERN_ERR " NFS: %s nfs4_blkdev_put returns %d \n " ,
2011-07-31 04:52:43 +04:00
__func__ , rv ) ;
2012-01-10 17:04:24 +04:00
dev_remove ( bdev - > net , bdev - > bm_mdev - > bd_dev ) ;
2011-07-31 04:52:43 +04:00
}
void bl_free_block_dev ( struct pnfs_block_dev * bdev )
{
if ( bdev ) {
if ( bdev - > bm_mdev ) {
dprintk ( " %s Removing DM device: %d:%d \n " ,
__func__ ,
MAJOR ( bdev - > bm_mdev - > bd_dev ) ,
MINOR ( bdev - > bm_mdev - > bd_dev ) ) ;
nfs4_blk_metadev_release ( bdev ) ;
}
kfree ( bdev ) ;
}
}