lowlevel.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * lowlevel.c
  4. *
  5. * PURPOSE
  6. * Low Level Device Routines for the UDF filesystem
  7. *
  8. * COPYRIGHT
  9. * (C) 1999-2001 Ben Fennema
  10. *
  11. * HISTORY
  12. *
  13. * 03/26/99 blf Created.
  14. */
  15. #include "udfdecl.h"
  16. #include <linux/blkdev.h>
  17. #include <linux/cdrom.h>
  18. #include <linux/uaccess.h>
  19. #include "udf_sb.h"
  20. unsigned int udf_get_last_session(struct super_block *sb)
  21. {
  22. struct cdrom_device_info *cdi = disk_to_cdi(sb->s_bdev->bd_disk);
  23. struct cdrom_multisession ms_info;
  24. if (!cdi) {
  25. udf_debug("CDROMMULTISESSION not supported.\n");
  26. return 0;
  27. }
  28. ms_info.addr_format = CDROM_LBA;
  29. if (cdrom_multisession(cdi, &ms_info) == 0) {
  30. udf_debug("XA disk: %s, vol_desc_start=%d\n",
  31. ms_info.xa_flag ? "yes" : "no", ms_info.addr.lba);
  32. if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
  33. return ms_info.addr.lba;
  34. }
  35. return 0;
  36. }
  37. udf_pblk_t udf_get_last_block(struct super_block *sb)
  38. {
  39. struct cdrom_device_info *cdi = disk_to_cdi(sb->s_bdev->bd_disk);
  40. unsigned long lblock = 0;
  41. /*
  42. * The cdrom layer call failed or returned obviously bogus value?
  43. * Try using the device size...
  44. */
  45. if (!cdi || cdrom_get_last_written(cdi, &lblock) || lblock == 0) {
  46. if (sb_bdev_nr_blocks(sb) > ~(udf_pblk_t)0)
  47. return 0;
  48. lblock = sb_bdev_nr_blocks(sb);
  49. }
  50. if (lblock)
  51. return lblock - 1;
  52. return 0;
  53. }