lowlevel.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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_multisession ms_info;
  27. unsigned int vol_desc_start;
  28. struct block_device *bdev = sb->s_bdev;
  29. int i;
  30. vol_desc_start = 0;
  31. ms_info.addr_format = CDROM_LBA;
  32. i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long)&ms_info);
  33. if (i == 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. vol_desc_start = ms_info.addr.lba;
  38. } else {
  39. udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i);
  40. }
  41. return vol_desc_start;
  42. }
  43. unsigned long udf_get_last_block(struct super_block *sb)
  44. {
  45. struct block_device *bdev = sb->s_bdev;
  46. unsigned long lblock = 0;
  47. /*
  48. * ioctl failed or returned obviously bogus value?
  49. * Try using the device size...
  50. */
  51. if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock) ||
  52. lblock == 0)
  53. lblock = i_size_read(bdev->bd_inode) >> sb->s_blocksize_bits;
  54. if (lblock)
  55. return lblock - 1;
  56. else
  57. return 0;
  58. }