patch-1.3.54 linux/fs/isofs/file.c
Next file: linux/fs/minix/file.c
Previous file: linux/fs/inode.c
Back to the patch index
Back to the overall index
- Lines: 233
- Date:
Thu Jan 4 20:26:24 1996
- Orig file:
v1.3.53/linux/fs/isofs/file.c
- Orig date:
Tue Dec 26 04:45:38 1995
diff -u --recursive --new-file v1.3.53/linux/fs/isofs/file.c linux/fs/isofs/file.c
@@ -15,27 +15,16 @@
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/locks.h>
-
-#include <asm/segment.h>
-#include <asm/system.h>
-
-#define NBUF 32
-
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-
#include <linux/fs.h>
#include <linux/iso_fs.h>
-static int isofs_file_read(struct inode *, struct file *, char *, int);
-
/*
* We have mostly NULL's here: the current defaults are ok for
* the isofs filesystem.
*/
static struct file_operations isofs_file_operations = {
NULL, /* lseek - default */
- isofs_file_read, /* read */
+ generic_file_read, /* read */
NULL, /* write */
NULL, /* readdir - bad */
NULL, /* select - default */
@@ -59,202 +48,9 @@
NULL, /* rename */
NULL, /* readlink */
NULL, /* follow_link */
- NULL, /* readpage */
+ generic_readpage, /* readpage */
NULL, /* writepage */
isofs_bmap, /* bmap */
NULL, /* truncate */
NULL /* permission */
};
-
-/* This is a heuristic to determine if a file is text of binary. If it
- * is text, then we translate all 0x0d characters to spaces. If the 0x0d
- * character is not preceded or followed by a 0x0a, then we turn it into
- * a 0x0a. A control-Z is also turned into a linefeed.
- */
-
-static inline void unixify_to_fs(char * outbuf, char * buffer, int chars,
- int mode)
-{
- char outchar;
-
- while(chars--){
- outchar = *buffer;
- if(outchar == 0x1a) outchar = 0x0a;
- if(outchar == 0x0d){
- if(mode == ISOFS_FILE_TEXT_M) outchar = 0x0a;
- if(mode == ISOFS_FILE_TEXT) outchar = ' ';
- }
- put_user(outchar, outbuf++);
- buffer++;
- }
-}
-
-/*This function determines if a given file has a DOS-like text format or not*/
-
-static void isofs_determine_filetype(struct inode * inode)
-{
- int block;
- int result, i;
- struct buffer_head * bh;
- unsigned char * pnt;
-
- block = isofs_bmap(inode,0);
- if (block && (bh = bread(inode->i_dev,block, ISOFS_BUFFER_SIZE(inode)))) {
- pnt = (unsigned char *) bh->b_data;
- result = ISOFS_FILE_TEXT_M;
- for(i=0;i<(inode->i_size < ISOFS_BUFFER_SIZE(inode) ? inode->i_size : ISOFS_BUFFER_SIZE(inode));
- i++,pnt++){
- if(*pnt & 0x80) {result = ISOFS_FILE_BINARY; break;};
- if(*pnt >= 0x20 || *pnt == 0x1a) continue;
- if(*pnt == 0x0a) {result = ISOFS_FILE_TEXT; continue;};
- if(*pnt >= 0x9 && *pnt <= 0x0d) continue;
- result = ISOFS_FILE_BINARY;
- break;
- }
- brelse(bh);
- inode->u.isofs_i.i_file_format = result;
- }
-}
-
-static int isofs_file_read(struct inode * inode, struct file * filp, char * buf, int count)
-{
- int read,left,chars;
- int block, blocks, offset, total_blocks;
- int bhrequest;
- int ra_blocks, max_block, nextblock;
- struct buffer_head ** bhb, ** bhe;
- struct buffer_head * bhreq[NBUF];
- struct buffer_head * buflist[NBUF];
-
- if (!inode) {
- printk("isofs_file_read: inode = NULL\n");
- return -EINVAL;
- }
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) {
- printk("isofs_file_read: mode = %07o\n",inode->i_mode);
- return -EINVAL;
- }
- if (inode->u.isofs_i.i_file_format == ISOFS_FILE_UNKNOWN)
- isofs_determine_filetype(inode);
- if (filp->f_pos > inode->i_size)
- left = 0;
- else
- left = inode->i_size - filp->f_pos;
- if (left > count)
- left = count;
- if (left <= 0)
- return 0;
- read = 0;
- block = filp->f_pos >> ISOFS_BUFFER_BITS(inode);
- offset = (inode->u.isofs_i.i_first_extent + filp->f_pos)
- & (ISOFS_BUFFER_SIZE(inode)-1);
- blocks = (left + offset + ISOFS_BUFFER_SIZE(inode) - 1) / ISOFS_BUFFER_SIZE(inode);
- bhb = bhe = buflist;
-
- ra_blocks = read_ahead[MAJOR(inode->i_dev)] / (BLOCK_SIZE >> 9);
- if(ra_blocks > blocks) blocks = ra_blocks;
-
- /*
- * this is for stopping read ahead at EOF. It's important for
- * reading PhotoCD's, because they have many small data tracks instead
- * of one big. And between two data-tracks are some unreadable sectors.
- * A read ahead after a EOF may try to read such an unreadable sector.
- * kraxel@cs.tu-berlin.de (Gerd Knorr)
- */
- total_blocks = (inode->i_size + (1 << ISOFS_BUFFER_BITS(inode)) - 1)
- >> ISOFS_BUFFER_BITS(inode);
- if (block + blocks > total_blocks)
- blocks = total_blocks - block;
-
- max_block = (inode->i_size + BLOCK_SIZE - 1)/BLOCK_SIZE;
- nextblock = -1;
-
- /* We do this in a two stage process. We first try and request
- as many blocks as we can, then we wait for the first one to
- complete, and then we try and wrap up as many as are actually
- done. This routine is rather generic, in that it can be used
- in a filesystem by substituting the appropriate function in
- for getblk.
-
- This routine is optimized to make maximum use of the various
- buffers and caches. */
-
- do {
- bhrequest = 0;
- while (blocks) {
- int uptodate;
- --blocks;
- *bhb = getblk(inode->i_dev,isofs_bmap(inode, block++), ISOFS_BUFFER_SIZE(inode));
- uptodate = 1;
- if (*bhb && !buffer_uptodate(*bhb)) {
- uptodate = 0;
- bhreq[bhrequest++] = *bhb;
- };
-
- if (++bhb == &buflist[NBUF])
- bhb = buflist;
-
- /* If the block we have on hand is uptodate, go ahead
- and complete processing. */
- if(uptodate) break;
-
- if (bhb == bhe)
- break;
- }
-
- /* Now request them all */
- if (bhrequest)
- ll_rw_block(READ, bhrequest, bhreq);
-
- do{ /* Finish off all I/O that has actually completed */
- if (*bhe) {/* test for valid buffer */
- wait_on_buffer(*bhe);
- if (!buffer_uptodate(*bhe)) {
- brelse(*bhe);
- if (++bhe == &buflist[NBUF])
- bhe = buflist;
- left = 0;
- break;
- }
- }
-
- if (left < ISOFS_BUFFER_SIZE(inode) - offset)
- chars = left;
- else
- chars = ISOFS_BUFFER_SIZE(inode) - offset;
- filp->f_pos += chars;
- left -= chars;
- read += chars;
- if (*bhe) {
- if (inode->u.isofs_i.i_file_format == ISOFS_FILE_TEXT ||
- inode->u.isofs_i.i_file_format == ISOFS_FILE_TEXT_M)
- unixify_to_fs(buf, offset+(*bhe)->b_data, chars,
- inode->u.isofs_i.i_file_format);
- else
- memcpy_tofs(buf,offset+(*bhe)->b_data,chars);
- brelse(*bhe);
- buf += chars;
- } else {
- while (chars-->0)
- put_user(0,buf++);
- }
- offset = 0;
- if (++bhe == &buflist[NBUF])
- bhe = buflist;
- } while( bhe != bhb && (*bhe == 0 || !buffer_locked(*bhe)) &&
- (left > 0));
- } while (left > 0);
-
-/* Release the read-ahead blocks */
- while (bhe != bhb) {
- if (*bhe) brelse(*bhe);
- if (++bhe == &buflist[NBUF])
- bhe = buflist;
- };
-
- filp->f_reada = 1;
-
- if (!read)
- return -EIO;
- return read;
-}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this