patch-2.3.9 linux/fs/isofs/inode.c

Next file: linux/fs/isofs/symlink.c
Previous file: linux/fs/isofs/file.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.8/linux/fs/isofs/inode.c linux/fs/isofs/inode.c
@@ -55,7 +55,7 @@
 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 @@
 	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 @@
  * 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 @@
 	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 @@
 	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;
+		while (b_off >= (offset + sect_size)) {
+			struct inode *ninode;
 
-			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;
-			}
+			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 @@
 	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);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)