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 20 #include "udfdecl.h" 21 22 #include <linux/blkdev.h> 23 #include <linux/cdrom.h> 24 #include <linux/uaccess.h> 25 26 #include "udf_sb.h" 27 28 unsigned int udf_get_last_session(struct super_block *sb) 29 { 30 struct cdrom_device_info *cdi = disk_to_cdi(sb->s_bdev->bd_disk); 31 struct cdrom_multisession ms_info; 32 33 if (!cdi) { 34 udf_debug("CDROMMULTISESSION not supported.\n"); 35 return 0; 36 } 37 38 ms_info.addr_format = CDROM_LBA; 39 if (cdrom_multisession(cdi, &ms_info) == 0) { 40 udf_debug("XA disk: %s, vol_desc_start=%d\n", 41 ms_info.xa_flag ? "yes" : "no", ms_info.addr.lba); 42 if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */ 43 return ms_info.addr.lba; 44 } 45 return 0; 46 } 47 48 unsigned long udf_get_last_block(struct super_block *sb) 49 { 50 struct block_device *bdev = sb->s_bdev; 51 struct cdrom_device_info *cdi = disk_to_cdi(bdev->bd_disk); 52 unsigned long lblock = 0; 53 54 /* 55 * The cdrom layer call failed or returned obviously bogus value? 56 * Try using the device size... 57 */ 58 if (!cdi || cdrom_get_last_written(cdi, &lblock) || lblock == 0) 59 lblock = i_size_read(bdev->bd_inode) >> sb->s_blocksize_bits; 60 61 if (lblock) 62 return lblock - 1; 63 return 0; 64 } 65