linux/fs/udf/lowlevel.c
<<
>>
Prefs
   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 <asm/uaccess.h>
  25
  26#include "udf_sb.h"
  27
  28unsigned int udf_get_last_session(struct super_block *sb)
  29{
  30        struct cdrom_multisession ms_info;
  31        unsigned int vol_desc_start;
  32        struct block_device *bdev = sb->s_bdev;
  33        int i;
  34
  35        vol_desc_start = 0;
  36        ms_info.addr_format = CDROM_LBA;
  37        i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long)&ms_info);
  38
  39        if (i == 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                        vol_desc_start = ms_info.addr.lba;
  44        } else {
  45                udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i);
  46        }
  47        return vol_desc_start;
  48}
  49
  50unsigned long udf_get_last_block(struct super_block *sb)
  51{
  52        struct block_device *bdev = sb->s_bdev;
  53        unsigned long lblock = 0;
  54
  55        /*
  56         * ioctl failed or returned obviously bogus value?
  57         * Try using the device size...
  58         */
  59        if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock) ||
  60            lblock == 0)
  61                lblock = bdev->bd_inode->i_size >> sb->s_blocksize_bits;
  62
  63        if (lblock)
  64                return lblock - 1;
  65        else
  66                return 0;
  67}
  68