@@ -703,6 +703,24 @@ static int blkdev_get_part(struct block_device *part, blk_mode_t mode)
703
703
return ret ;
704
704
}
705
705
706
+ int bdev_permission (dev_t dev , blk_mode_t mode , void * holder )
707
+ {
708
+ int ret ;
709
+
710
+ ret = devcgroup_check_permission (DEVCG_DEV_BLOCK ,
711
+ MAJOR (dev ), MINOR (dev ),
712
+ ((mode & BLK_OPEN_READ ) ? DEVCG_ACC_READ : 0 ) |
713
+ ((mode & BLK_OPEN_WRITE ) ? DEVCG_ACC_WRITE : 0 ));
714
+ if (ret )
715
+ return ret ;
716
+
717
+ /* Blocking writes requires exclusive opener */
718
+ if (mode & BLK_OPEN_RESTRICT_WRITES && !holder )
719
+ return - EINVAL ;
720
+
721
+ return 0 ;
722
+ }
723
+
706
724
static void blkdev_put_part (struct block_device * part )
707
725
{
708
726
struct block_device * whole = bdev_whole (part );
@@ -795,69 +813,43 @@ static void bdev_yield_write_access(struct block_device *bdev, blk_mode_t mode)
795
813
}
796
814
797
815
/**
798
- * bdev_open_by_dev - open a block device by device number
799
- * @dev: device number of block device to open
816
+ * bdev_open - open a block device
817
+ * @bdev: block device to open
800
818
* @mode: open mode (BLK_OPEN_*)
801
819
* @holder: exclusive holder identifier
802
820
* @hops: holder operations
821
+ * @bdev_file: file for the block device
803
822
*
804
- * Open the block device described by device number @dev. If @holder is not
805
- * %NULL, the block device is opened with exclusive access. Exclusive opens may
806
- * nest for the same @holder.
807
- *
808
- * Use this interface ONLY if you really do not have anything better - i.e. when
809
- * you are behind a truly sucky interface and all you are given is a device
810
- * number. Everything else should use bdev_open_by_path().
823
+ * Open the block device. If @holder is not %NULL, the block device is opened
824
+ * with exclusive access. Exclusive opens may nest for the same @holder.
811
825
*
812
826
* CONTEXT:
813
827
* Might sleep.
814
828
*
815
829
* RETURNS:
816
- * Handle with a reference to the block_device on success, ERR_PTR(-errno) on
817
- * failure.
830
+ * zero on success, -errno on failure.
818
831
*/
819
- struct bdev_handle * bdev_open_by_dev ( dev_t dev , blk_mode_t mode , void * holder ,
820
- const struct blk_holder_ops * hops )
832
+ int bdev_open ( struct block_device * bdev , blk_mode_t mode , void * holder ,
833
+ const struct blk_holder_ops * hops , struct file * bdev_file )
821
834
{
822
- struct bdev_handle * handle = kmalloc (sizeof (struct bdev_handle ),
823
- GFP_KERNEL );
824
- struct block_device * bdev ;
835
+ struct bdev_handle * handle ;
825
836
bool unblock_events = true;
826
- struct gendisk * disk ;
837
+ struct gendisk * disk = bdev -> bd_disk ;
827
838
int ret ;
828
839
840
+ handle = kmalloc (sizeof (struct bdev_handle ), GFP_KERNEL );
829
841
if (!handle )
830
- return ERR_PTR (- ENOMEM );
831
-
832
- ret = devcgroup_check_permission (DEVCG_DEV_BLOCK ,
833
- MAJOR (dev ), MINOR (dev ),
834
- ((mode & BLK_OPEN_READ ) ? DEVCG_ACC_READ : 0 ) |
835
- ((mode & BLK_OPEN_WRITE ) ? DEVCG_ACC_WRITE : 0 ));
836
- if (ret )
837
- goto free_handle ;
838
-
839
- /* Blocking writes requires exclusive opener */
840
- if (mode & BLK_OPEN_RESTRICT_WRITES && !holder ) {
841
- ret = - EINVAL ;
842
- goto free_handle ;
843
- }
844
-
845
- bdev = blkdev_get_no_open (dev );
846
- if (!bdev ) {
847
- ret = - ENXIO ;
848
- goto free_handle ;
849
- }
850
- disk = bdev -> bd_disk ;
842
+ return - ENOMEM ;
851
843
852
844
if (holder ) {
853
845
mode |= BLK_OPEN_EXCL ;
854
846
ret = bd_prepare_to_claim (bdev , holder , hops );
855
847
if (ret )
856
- goto put_blkdev ;
848
+ goto free_handle ;
857
849
} else {
858
850
if (WARN_ON_ONCE (mode & BLK_OPEN_EXCL )) {
859
851
ret = - EIO ;
860
- goto put_blkdev ;
852
+ goto free_handle ;
861
853
}
862
854
}
863
855
@@ -902,19 +894,26 @@ struct bdev_handle *bdev_open_by_dev(dev_t dev, blk_mode_t mode, void *holder,
902
894
handle -> bdev = bdev ;
903
895
handle -> holder = holder ;
904
896
handle -> mode = mode ;
905
- return handle ;
897
+
898
+ bdev_file -> f_flags |= O_LARGEFILE ;
899
+ bdev_file -> f_mode |= FMODE_BUF_RASYNC | FMODE_CAN_ODIRECT ;
900
+ if (bdev_nowait (bdev ))
901
+ bdev_file -> f_mode |= FMODE_NOWAIT ;
902
+ bdev_file -> f_mapping = handle -> bdev -> bd_inode -> i_mapping ;
903
+ bdev_file -> f_wb_err = filemap_sample_wb_err (bdev_file -> f_mapping );
904
+ bdev_file -> private_data = handle ;
905
+
906
+ return 0 ;
906
907
put_module :
907
908
module_put (disk -> fops -> owner );
908
909
abort_claiming :
909
910
if (holder )
910
911
bd_abort_claiming (bdev , holder );
911
912
mutex_unlock (& disk -> open_mutex );
912
913
disk_unblock_events (disk );
913
- put_blkdev :
914
- blkdev_put_no_open (bdev );
915
914
free_handle :
916
915
kfree (handle );
917
- return ERR_PTR ( ret ) ;
916
+ return ret ;
918
917
}
919
918
920
919
/*
@@ -951,29 +950,33 @@ struct file *bdev_file_open_by_dev(dev_t dev, blk_mode_t mode, void *holder,
951
950
const struct blk_holder_ops * hops )
952
951
{
953
952
struct file * bdev_file ;
954
- struct bdev_handle * handle ;
953
+ struct block_device * bdev ;
955
954
unsigned int flags ;
955
+ int ret ;
956
956
957
- handle = bdev_open_by_dev (dev , mode , holder , hops );
958
- if (IS_ERR (handle ))
959
- return ERR_CAST (handle );
957
+ ret = bdev_permission (dev , mode , holder );
958
+ if (ret )
959
+ return ERR_PTR (ret );
960
+
961
+ bdev = blkdev_get_no_open (dev );
962
+ if (!bdev )
963
+ return ERR_PTR (- ENXIO );
960
964
961
965
flags = blk_to_file_flags (mode );
962
- bdev_file = alloc_file_pseudo_noaccount (handle -> bdev -> bd_inode ,
966
+ bdev_file = alloc_file_pseudo_noaccount (bdev -> bd_inode ,
963
967
blockdev_mnt , "" , flags | O_LARGEFILE , & def_blk_fops );
964
968
if (IS_ERR (bdev_file )) {
965
- bdev_release ( handle );
969
+ blkdev_put_no_open ( bdev );
966
970
return bdev_file ;
967
971
}
968
- ihold (handle -> bdev -> bd_inode );
972
+ ihold (bdev -> bd_inode );
969
973
970
- bdev_file -> f_mode |= FMODE_BUF_RASYNC | FMODE_CAN_ODIRECT ;
971
- if (bdev_nowait (handle -> bdev ))
972
- bdev_file -> f_mode |= FMODE_NOWAIT ;
973
-
974
- bdev_file -> f_mapping = handle -> bdev -> bd_inode -> i_mapping ;
975
- bdev_file -> f_wb_err = filemap_sample_wb_err (bdev_file -> f_mapping );
976
- bdev_file -> private_data = handle ;
974
+ ret = bdev_open (bdev , mode , holder , hops , bdev_file );
975
+ if (ret ) {
976
+ blkdev_put_no_open (bdev );
977
+ fput (bdev_file );
978
+ return ERR_PTR (ret );
979
+ }
977
980
return bdev_file ;
978
981
}
979
982
EXPORT_SYMBOL (bdev_file_open_by_dev );
0 commit comments