summaryrefslogtreecommitdiffstats
path: root/fs/isofs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/isofs')
-rw-r--r--fs/isofs/dir.c7
-rw-r--r--fs/isofs/file.c6
-rw-r--r--fs/isofs/inode.c180
-rw-r--r--fs/isofs/symlink.c7
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)