summaryrefslogtreecommitdiffstats
path: root/fs/isofs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-05 06:47:02 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-05 06:47:02 +0000
commit99a7e12f34b3661a0d1354eef83a0eef4df5e34c (patch)
tree3560aca9ca86792f9ab7bd87861ea143a1b3c7a3 /fs/isofs
parente73a04659c0b8cdee4dd40e58630e2cf63afb316 (diff)
Merge with Linux 2.3.38.
Diffstat (limited to 'fs/isofs')
-rw-r--r--fs/isofs/inode.c134
1 files changed, 54 insertions, 80 deletions
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 84aa2ec30..d14c18071 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -425,71 +425,54 @@ static int parse_options(char *options, struct iso9660_options * popt)
*/
#define WE_OBEY_THE_WRITTEN_STANDARDS 1
-static unsigned int isofs_get_last_session(kdev_t dev,s32 session )
+static unsigned int isofs_get_last_session(struct super_block *sb,s32 session )
{
- struct cdrom_multisession ms_info;
- unsigned int vol_desc_start;
- struct inode inode_fake;
- struct file_operations *fops;
- extern struct file_operations * get_blkfops(unsigned int);
- int i;
-
- vol_desc_start=0;
- fops = get_blkfops(MAJOR(dev));
- if (fops && fops->ioctl)
- {
- /* Whoops. We must save the old FS, since otherwise
- * we would destroy the kernels idea about FS on root
- * mount in read_super... [chexum]
- */
- mm_segment_t old_fs=get_fs();
- inode_fake.i_rdev=dev;
- init_waitqueue_head(&inode_fake.i_wait);
- ms_info.addr_format=CDROM_LBA;
- /* If a minor device was explicitly opened, set session to the
- * minor number. For instance, if /dev/hdc1 is mounted, session
- * 1 on the CD-ROM is selected. CD_PART_MAX gives access to
- * a max of 64 sessions on IDE. SCSI drives must still use
- * the session option to mount.
- */
- if ((MINOR(dev) % CD_PART_MAX) && (MAJOR(dev) != SCSI_CDROM_MAJOR))
+ struct cdrom_multisession ms_info;
+ unsigned int vol_desc_start;
+ struct block_device *bdev = sb->s_bdev;
+ kdev_t dev = sb->s_dev;
+ int i;
+
+ vol_desc_start=0;
+ ms_info.addr_format=CDROM_LBA;
+ /* If a minor device was explicitly opened, set session to the
+ * minor number. For instance, if /dev/hdc1 is mounted, session
+ * 1 on the CD-ROM is selected. CD_PART_MAX gives access to
+ * a max of 64 sessions on IDE. SCSI drives must still use
+ * the session option to mount.
+ */
+ if ((MINOR(dev) % CD_PART_MAX) && (MAJOR(dev) != SCSI_CDROM_MAJOR))
session = MINOR(dev) % CD_PART_MAX;
- set_fs(KERNEL_DS);
- if(session >= 0 && session <= 99) {
- struct cdrom_tocentry Te;
- Te.cdte_track=session;
- Te.cdte_format=CDROM_LBA;
- i=get_blkfops(MAJOR(dev))->ioctl(&inode_fake,
- NULL,
- CDROMREADTOCENTRY,
- (unsigned long) &Te);
- set_fs(old_fs);
- if(!i) printk(KERN_ERR"Session %d start %d type %d\n",session,Te.cdte_addr.lba,Te.cdte_ctrl&CDROM_DATA_TRACK);
- if(i || (Te.cdte_ctrl&CDROM_DATA_TRACK) != 4)
- printk(KERN_ERR"Invalid session number or type of track\n");
- else return Te.cdte_addr.lba;
- }
- i=get_blkfops(MAJOR(dev))->ioctl(&inode_fake,
- NULL,
- CDROMMULTISESSION,
- (unsigned long) &ms_info);
- set_fs(old_fs);
- if(session > 0) printk(KERN_ERR"Invalid session number\n");
+ if(session >= 0 && session <= 99) {
+ struct cdrom_tocentry Te;
+ Te.cdte_track=session;
+ Te.cdte_format=CDROM_LBA;
+ i = ioctl_by_bdev(bdev, CDROMREADTOCENTRY, (unsigned long) &Te);
+ if (!i) {
+ printk(KERN_DEBUG "Session %d start %d type %d\n",
+ session, Te.cdte_addr.lba,
+ Te.cdte_ctrl&CDROM_DATA_TRACK);
+ if ((Te.cdte_ctrl&CDROM_DATA_TRACK) == 4)
+ return Te.cdte_addr.lba;
+ }
+
+ printk(KERN_ERR "Invalid session number or type of track\n");
+ }
+ i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info);
+ if(session > 0) printk(KERN_ERR "Invalid session number\n");
#if 0
- printk("isofs.inode: CDROMMULTISESSION: rc=%d\n",i);
- if (i==0)
- {
- printk("isofs.inode: XA disk: %s\n", ms_info.xa_flag ? "yes":"no");
- printk("isofs.inode: vol_desc_start = %d\n", ms_info.addr.lba);
+ printk("isofs.inode: CDROMMULTISESSION: rc=%d\n",i);
+ if (i==0) {
+ printk("isofs.inode: XA disk: %s\n",ms_info.xa_flag?"yes":"no");
+ printk("isofs.inode: vol_desc_start = %d\n", ms_info.addr.lba);
}
#endif
- if (i==0)
+ if (i==0)
#if WE_OBEY_THE_WRITTEN_STANDARDS
if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
#endif
- vol_desc_start=ms_info.addr.lba;
- }
- return vol_desc_start;
+ vol_desc_start=ms_info.addr.lba;
+ return vol_desc_start;
}
/*
@@ -569,7 +552,7 @@ static struct super_block *isofs_read_super(struct super_block *s, void *data,
s->u.isofs_sb.s_high_sierra = high_sierra = 0; /* default is iso9660 */
vol_desc_start = (opt.sbsector != -1) ?
- opt.sbsector : isofs_get_last_session(dev,opt.session);
+ opt.sbsector : isofs_get_last_session(s,opt.session);
for (iso_blknum = vol_desc_start+16;
iso_blknum < vol_desc_start+100; iso_blknum++)
@@ -927,7 +910,8 @@ static int isofs_statfs (struct super_block *sb, struct statfs *buf, int bufsiz)
int isofs_get_block(struct inode *inode, long iblock,
struct buffer_head *bh_result, int create)
{
- off_t b_off, offset, sect_size;
+ unsigned long b_off;
+ unsigned offset, sect_size;
unsigned int firstext;
unsigned long nextino;
int i, err;
@@ -942,30 +926,21 @@ int isofs_get_block(struct inode *inode, long iblock,
if (iblock < 0)
goto abort_negative;
- b_off = iblock << ISOFS_BUFFER_BITS(inode);
+ b_off = iblock;
- /* If we are beyond the end of this file, don't give out any
- * blocks.
+ /* If we are *way* beyond the end of the file, print a message.
+ * Access beyond the end of the file up to the next page boundary
+ * is normal, however because of the way the page cache works.
+ * In this case, we just return 0 so that we can properly fill
+ * the page with useless information without generating any
+ * I/O errors.
*/
- if (b_off > inode->i_size) {
- off_t max_legal_read_offset;
-
- /* If we are *way* beyond the end of the file, print a message.
- * Access beyond the end of the file up to the next page boundary
- * is normal, however because of the way the page cache works.
- * In this case, we just return 0 so that we can properly fill
- * the page with useless information without generating any
- * I/O errors.
- */
- max_legal_read_offset = (inode->i_size + PAGE_SIZE - 1)
- & ~(PAGE_SIZE - 1);
- if (b_off >= max_legal_read_offset)
- goto abort_beyond_end;
- }
+ if (b_off > ((inode->i_size + PAGE_SIZE - 1) >> ISOFS_BUFFER_BITS(inode)))
+ goto abort_beyond_end;
offset = 0;
firstext = inode->u.isofs_i.i_first_extent;
- sect_size = inode->u.isofs_i.i_section_size;
+ sect_size = inode->u.isofs_i.i_section_size >> ISOFS_BUFFER_BITS(inode);
nextino = inode->u.isofs_i.i_next_section_ino;
i = 0;
@@ -990,8 +965,7 @@ int isofs_get_block(struct inode *inode, long iblock,
}
bh_result->b_dev = inode->i_dev;
- bh_result->b_blocknr = firstext +
- ((b_off - offset) >> ISOFS_BUFFER_BITS(inode));
+ bh_result->b_blocknr = firstext + b_off - offset;
bh_result->b_state |= (1UL << BH_Mapped);
err = 0;