diff options
Diffstat (limited to 'fs/isofs')
-rw-r--r-- | fs/isofs/dir.c | 7 | ||||
-rw-r--r-- | fs/isofs/file.c | 6 | ||||
-rw-r--r-- | fs/isofs/inode.c | 180 | ||||
-rw-r--r-- | fs/isofs/symlink.c | 7 |
4 files changed, 115 insertions, 85 deletions
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c index 23ca159c7..bc64dfdd5 100644 --- a/fs/isofs/dir.c +++ b/fs/isofs/dir.c @@ -57,11 +57,14 @@ struct inode_operations isofs_dir_inode_operations = NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ + NULL, /* get_block */ NULL, /* readpage */ NULL, /* writepage */ - NULL, /* bmap */ + NULL, /* flushpage */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL /* revalidate */ }; static int isofs_name_translate(char * old, int len, char * new) diff --git a/fs/isofs/file.c b/fs/isofs/file.c index ce85b367a..fd9b124ed 100644 --- a/fs/isofs/file.c +++ b/fs/isofs/file.c @@ -48,10 +48,12 @@ struct inode_operations isofs_file_inode_operations = { NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ - isofs_bmap, /* bmap */ + isofs_get_block, /* get_block */ block_read_full_page, /* readpage */ NULL, /* writepage */ NULL, /* flushpage */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL /* revalidate */ }; diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 01d37a849..1cf86ae63 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -55,7 +55,7 @@ static int isofs_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b); static int isofs_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b); #endif -void isofs_put_super(struct super_block *sb) +static void isofs_put_super(struct super_block *sb) { #ifdef CONFIG_JOLIET if (sb->u.isofs_sb.s_nls_iocharset) { @@ -73,6 +73,9 @@ void isofs_put_super(struct super_block *sb) return; } +static void isofs_read_inode(struct inode *); +static int isofs_statfs (struct super_block *, struct statfs *, int); + static struct super_operations isofs_sops = { isofs_read_inode, NULL, /* write_inode */ @@ -487,8 +490,8 @@ static unsigned int isofs_get_last_session(kdev_t dev,s32 session ) * Note: a check_disk_change() has been done immediately prior * to this call, so we don't need to check again. */ -struct super_block *isofs_read_super(struct super_block *s, void *data, - int silent) +static struct super_block *isofs_read_super(struct super_block *s, void *data, + int silent) { kdev_t dev = s->s_dev; struct buffer_head * bh = NULL, *pri_bh = NULL; @@ -894,7 +897,7 @@ out_unlock: return NULL; } -int isofs_statfs (struct super_block *sb, struct statfs *buf, int bufsiz) +static int isofs_statfs (struct super_block *sb, struct statfs *buf, int bufsiz) { struct statfs tmp; @@ -910,96 +913,115 @@ int isofs_statfs (struct super_block *sb, struct statfs *buf, int bufsiz) return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0; } -static int do_isofs_bmap(struct inode * inode,int block) +/* Life is simpler than for other filesystem since we never + * have to create a new block, only find an existing one. + */ +int isofs_get_block(struct inode *inode, long iblock, + struct buffer_head *bh_result, int create) { - off_t b_off, offset, size; - struct inode *ino; + off_t b_off, offset, sect_size; unsigned int firstext; unsigned long nextino; - int i; + int i, err; - if (block<0) { - printk("_isofs_bmap: block<0"); - return 0; - } + lock_kernel(); - b_off = block << ISOFS_BUFFER_BITS(inode); + err = -EROFS; + if (create) + goto abort_create_attempted; - /* - * If we are beyond the end of this file, don't give out any + err = -EIO; + if (iblock < 0) + goto abort_negative; + + b_off = iblock << ISOFS_BUFFER_BITS(inode); + + /* If we are beyond the end of this file, don't give out any * blocks. */ - 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 ) - { - - printk("_isofs_bmap: block>= EOF(%d, %ld)\n", block, - inode->i_size); - } - return 0; - } + 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; + } + + offset = 0; + firstext = inode->u.isofs_i.i_first_extent; + sect_size = inode->u.isofs_i.i_section_size; + nextino = inode->u.isofs_i.i_next_section_ino; - offset = 0; - firstext = inode->u.isofs_i.i_first_extent; - size = inode->u.isofs_i.i_section_size; - nextino = inode->u.isofs_i.i_next_section_ino; -#ifdef DEBUG - printk("first inode: inode=%x nextino=%x firstext=%u size=%lu\n", - inode->i_ino, nextino, firstext, size); -#endif i = 0; if (nextino) { - while(b_off >= offset + size) { - offset += size; - - if(nextino == 0) return 0; - ino = iget(inode->i_sb, nextino); - if(!ino) return 0; - firstext = ino->u.isofs_i.i_first_extent; - size = ino->u.isofs_i.i_section_size; -#ifdef DEBUG - printk("read inode: inode=%lu ino=%lu nextino=%lu firstext=%u size=%lu\n", - inode->i_ino, nextino, ino->u.isofs_i.i_next_section_ino, firstext, size); -#endif - nextino = ino->u.isofs_i.i_next_section_ino; - iput(ino); - - if(++i > 100) { - printk("isofs_bmap: More than 100 file sections ?!?, aborting...\n"); - printk("isofs_bmap: ino=%lu block=%d firstext=%u size=%u nextino=%lu\n", - inode->i_ino, block, firstext, (unsigned)size, nextino); - return 0; - } + while (b_off >= (offset + sect_size)) { + struct inode *ninode; + + offset += sect_size; + if (nextino == 0) + goto abort; + ninode = iget(inode->i_sb, nextino); + if (!ninode) + goto abort; + firstext = ninode->u.isofs_i.i_first_extent; + sect_size = ninode->u.isofs_i.i_section_size; + nextino = ninode->u.isofs_i.i_next_section_ino; + iput(ninode); + + if (++i > 100) + goto abort_too_many_sections; } } -#ifdef DEBUG - printk("isofs_bmap: mapped inode:block %x:%d to block %lu\n", - inode->i_ino, block, (b_off - offset + firstext) >> ISOFS_BUFFER_BITS(inode)); -#endif - return (b_off - offset + firstext) >> ISOFS_BUFFER_BITS(inode); -} -int isofs_bmap(struct inode * inode,int block) -{ - int retval; + bh_result->b_dev = inode->i_dev; + bh_result->b_blocknr = + (b_off - offset + firstext) >> ISOFS_BUFFER_BITS(inode); + bh_result->b_state |= (1UL << BH_Mapped); + err = 0; - lock_kernel(); - retval = do_isofs_bmap(inode, block); +abort: unlock_kernel(); - return retval; + return err; + +abort_create_attempted: + printk("_isofs_bmap: Kernel tries to allocate a block\n"); + goto abort; + +abort_negative: + printk("_isofs_bmap: block < 0\n"); + goto abort; + +abort_beyond_end: + printk("_isofs_bmap: block >= EOF (%ld, %ld)\n", + iblock, inode->i_size); + goto abort; + +abort_too_many_sections: + printk("isofs_bmap: More than 100 file sections ?!?, aborting...\n"); + printk("isofs_bmap: ino=%lu block=%ld firstext=%u sect_size=%u nextino=%lu\n", + inode->i_ino, iblock, firstext, (unsigned) sect_size, nextino); + goto abort; +} + +int isofs_bmap(struct inode *inode, int block) +{ + struct buffer_head dummy; + int error; + + dummy.b_state = 0; + dummy.b_blocknr = -1000; + error = isofs_get_block(inode, block, &dummy, 0); + if (!error) + return dummy.b_blocknr; + return 0; } static void test_and_set_uid(uid_t *p, uid_t value) @@ -1101,7 +1123,7 @@ out_toomany: goto out; } -void isofs_read_inode(struct inode * inode) +static void isofs_read_inode(struct inode * inode) { struct super_block *sb = inode->i_sb; unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); diff --git a/fs/isofs/symlink.c b/fs/isofs/symlink.c index 5de4a8748..e5a7a2c72 100644 --- a/fs/isofs/symlink.c +++ b/fs/isofs/symlink.c @@ -38,11 +38,14 @@ struct inode_operations isofs_symlink_inode_operations = { NULL, /* rename */ isofs_readlink, /* readlink */ isofs_follow_link, /* follow_link */ + NULL, /* get_block */ NULL, /* readpage */ NULL, /* writepage */ - NULL, /* bmap */ + NULL, /* flushpage */ NULL, /* truncate */ - NULL /* permission */ + NULL, /* permission */ + NULL, /* smap */ + NULL /* revalidate */ }; static int isofs_readlink(struct dentry * dentry, char * buffer, int buflen) |