lowlevel.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /*
  2. * lowlevel.c
  3. *
  4. * PURPOSE
  5. * Low Level Device Routines for the UDF filesystem
  6. *
  7. * COPYRIGHT
  8. * This file is distributed under the terms of the GNU General Public
  9. * License (GPL). Copies of the GPL can be obtained from:
  10. * ftp://prep.ai.mit.edu/pub/gnu/GPL
  11. * Each contributing author retains all rights to their own work.
  12. *
  13. * (C) 1999-2001 Ben Fennema
  14. *
  15. * HISTORY
  16. *
  17. * 03/26/99 blf Created.
  18. */
  19. #include "udfdecl.h"
  20. #include <linux/blkdev.h>
  21. #include <linux/cdrom.h>
  22. #include <linux/uaccess.h>
  23. #include "udf_sb.h"
  24. unsigned int udf_get_last_session(struct super_block *sb)
  25. {
  26. struct cdrom_device_info *cdi = disk_to_cdi(sb->s_bdev->bd_disk);
  27. struct cdrom_multisession ms_info;
  28. if (!cdi) {
  29. udf_debug("CDROMMULTISESSION not supported.\n");
  30. return 0;
  31. }
  32. ms_info.addr_format = CDROM_LBA;
  33. if (cdrom_multisession(cdi, &ms_info) == 0) {
  34. udf_debug("XA disk: %s, vol_desc_start=%d\n",
  35. ms_info.xa_flag ? "yes" : "no", ms_info.addr.lba);
  36. if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
  37. return ms_info.addr.lba;
  38. }
  39. return 0;
  40. }
  41. unsigned long udf_get_last_block(struct super_block *sb)
  42. {
  43. struct block_device *bdev = sb->s_bdev;
  44. struct cdrom_device_info *cdi = disk_to_cdi(bdev->bd_disk);
  45. unsigned long lblock = 0;
  46. /*
  47. * The cdrom layer call failed or returned obviously bogus value?
  48. * Try using the device size...
  49. */
  50. if (!cdi || cdrom_get_last_written(cdi, &lblock) || lblock == 0)
  51. lblock = i_size_read(bdev->bd_inode) >> sb->s_blocksize_bits;
  52. if (lblock)
  53. return lblock - 1;
  54. return 0;
  55. }