diff options
Diffstat (limited to 'kernel/fs/udf/lowlevel.c')
-rw-r--r-- | kernel/fs/udf/lowlevel.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/kernel/fs/udf/lowlevel.c b/kernel/fs/udf/lowlevel.c new file mode 100644 index 000000000..6ad5a453a --- /dev/null +++ b/kernel/fs/udf/lowlevel.c @@ -0,0 +1,67 @@ +/* + * lowlevel.c + * + * PURPOSE + * Low Level Device Routines for the UDF filesystem + * + * COPYRIGHT + * This file is distributed under the terms of the GNU General Public + * License (GPL). Copies of the GPL can be obtained from: + * ftp://prep.ai.mit.edu/pub/gnu/GPL + * Each contributing author retains all rights to their own work. + * + * (C) 1999-2001 Ben Fennema + * + * HISTORY + * + * 03/26/99 blf Created. + */ + +#include "udfdecl.h" + +#include <linux/blkdev.h> +#include <linux/cdrom.h> +#include <linux/uaccess.h> + +#include "udf_sb.h" + +unsigned int udf_get_last_session(struct super_block *sb) +{ + struct cdrom_multisession ms_info; + unsigned int vol_desc_start; + struct block_device *bdev = sb->s_bdev; + int i; + + vol_desc_start = 0; + ms_info.addr_format = CDROM_LBA; + i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long)&ms_info); + + if (i == 0) { + udf_debug("XA disk: %s, vol_desc_start=%d\n", + ms_info.xa_flag ? "yes" : "no", ms_info.addr.lba); + if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */ + vol_desc_start = ms_info.addr.lba; + } else { + udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i); + } + return vol_desc_start; +} + +unsigned long udf_get_last_block(struct super_block *sb) +{ + struct block_device *bdev = sb->s_bdev; + unsigned long lblock = 0; + + /* + * ioctl failed or returned obviously bogus value? + * Try using the device size... + */ + if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock) || + lblock == 0) + lblock = bdev->bd_inode->i_size >> sb->s_blocksize_bits; + + if (lblock) + return lblock - 1; + else + return 0; +} |