patch-2.4.14 linux/fs/isofs/inode.c
Next file: linux/fs/isofs/rock.c
Previous file: linux/fs/isofs/compress.c
Back to the patch index
Back to the overall index
- Lines: 283
- Date:
Thu Oct 25 13:53:53 2001
- Orig file:
v2.4.13/linux/fs/isofs/inode.c
- Orig date:
Tue Oct 23 22:48:53 2001
diff -u --recursive --new-file v2.4.13/linux/fs/isofs/inode.c linux/fs/isofs/inode.c
@@ -32,6 +32,8 @@
#include <asm/system.h>
#include <asm/uaccess.h>
+#include "zisofs.h"
+
/*
* We have no support for "multi volume" CDs, but more and more disks carry
* wrong information within the volume descriptors.
@@ -109,6 +111,7 @@
char joliet;
char cruft;
char unhide;
+ char nocompress;
unsigned char check;
unsigned int blocksize;
mode_t mode;
@@ -278,6 +281,7 @@
popt->cruft = 'n';
popt->unhide = 'n';
popt->check = 'u'; /* unset */
+ popt->nocompress = 0;
popt->blocksize = 1024;
popt->mode = S_IRUGO | S_IXUGO; /* r-x for all. The disc could
be shared with DOS machines so
@@ -311,6 +315,10 @@
popt->utf8 = 1;
continue;
}
+ if (strncmp(this_char,"nocompress",10) == 0) {
+ popt->nocompress = 1;
+ continue;
+ }
if ((value = strchr(this_char,'=')) != NULL)
*value++ = 0;
@@ -758,6 +766,7 @@
s->u.isofs_sb.s_uid = opt.uid;
s->u.isofs_sb.s_gid = opt.gid;
s->u.isofs_sb.s_utf8 = opt.utf8;
+ s->u.isofs_sb.s_nocompress = opt.nocompress;
/*
* It would be incredibly stupid to allow people to mark every file
* on the disk as suid, so we merely allow them to set the default
@@ -874,93 +883,108 @@
return 0;
}
-/* Life is simpler than for other filesystem since we never
- * have to create a new block, only find an existing one.
+/*
+ * Get a set of blocks; filling in buffer_heads if already allocated
+ * or getblk() if they are not. Returns the number of blocks inserted
+ * (0 == error.)
*/
-static int isofs_get_block(struct inode *inode, long iblock,
- struct buffer_head *bh_result, int create)
+int isofs_get_blocks(struct inode *inode, long iblock,
+ struct buffer_head **bh_result, unsigned long nblocks)
{
unsigned long b_off;
unsigned offset, sect_size;
unsigned int firstext;
unsigned long nextino;
- int i, err;
+ int section, rv;
+ unsigned int blocksize = inode->i_sb->s_blocksize;
lock_kernel();
- err = -EROFS;
- if (create)
- goto abort_create_attempted;
-
- err = -EIO;
- if (iblock < 0)
- goto abort_negative;
+ rv = 0;
+ if (iblock < 0) {
+ printk("isofs_get_blocks: block < 0\n");
+ goto abort;
+ }
b_off = iblock;
-
- /* 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 + 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 >> ISOFS_BUFFER_BITS(inode);
nextino = inode->u.isofs_i.i_next_section_ino;
+ section = 0;
- i = 0;
- if (nextino) {
- 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)
+ while ( nblocks ) {
+ /* 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 + PAGE_CACHE_SIZE - 1) >> ISOFS_BUFFER_BITS(inode))) {
+ printk("isofs_get_blocks: block >= EOF (%ld, %ld)\n",
+ iblock, (unsigned long) inode->i_size);
+ goto abort;
+ }
+
+ if (nextino) {
+ 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 (++section > 100) {
+ printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n");
+ printk("isofs_get_blocks: ino=%lu block=%ld firstext=%u sect_size=%u nextino=%lu\n",
+ inode->i_ino, iblock, firstext, (unsigned) sect_size, nextino);
+ goto abort;
+ }
+ }
+ }
+
+ if ( *bh_result ) {
+ (*bh_result)->b_dev = inode->i_dev;
+ (*bh_result)->b_blocknr = firstext + b_off - offset;
+ (*bh_result)->b_state |= (1UL << BH_Mapped);
+ } else {
+ *bh_result = getblk(inode->i_dev, firstext+b_off-offset, blocksize);
+ if ( !*bh_result )
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;
}
+ bh_result++; /* Next buffer head */
+ b_off++; /* Next buffer offset */
+ nblocks--;
+ rv++;
}
- bh_result->b_dev = inode->i_dev;
- bh_result->b_blocknr = firstext + b_off - offset;
- bh_result->b_state |= (1UL << BH_Mapped);
- err = 0;
abort:
unlock_kernel();
- return err;
+ return rv;
+}
-abort_create_attempted:
- printk("isofs_get_block: Kernel tries to allocate a block\n");
- goto abort;
-
-abort_negative:
- printk("isofs_get_block: block < 0\n");
- goto abort;
-
-abort_beyond_end:
- printk("isofs_get_block: block >= EOF (%ld, %ld)\n",
- iblock, (unsigned long) inode->i_size);
- goto abort;
-
-abort_too_many_sections:
- printk("isofs_get_block: More than 100 file sections ?!?, aborting...\n");
- printk("isofs_get_block: ino=%lu block=%ld firstext=%u sect_size=%u nextino=%lu\n",
- inode->i_ino, iblock, firstext, (unsigned) sect_size, nextino);
- goto abort;
+/*
+ * Used by the standard interfaces.
+ */
+static int isofs_get_block(struct inode *inode, long iblock,
+ struct buffer_head *bh_result, int create)
+{
+ if ( create ) {
+ printk("isofs_get_block: Kernel tries to allocate a block\n");
+ return -EROFS;
+ }
+
+ return isofs_get_blocks(inode, iblock, &bh_result, 1) ? 0 : -EIO;
}
static int isofs_bmap(struct inode *inode, int block)
@@ -1151,6 +1175,9 @@
de = tmpde;
}
+ /* Assume it is a normal-format file unless told otherwise */
+ inode->u.isofs_i.i_file_format = isofs_file_normal;
+
if (de->flags[-high_sierra] & 2) {
inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
inode->i_nlink = 1; /* Set to 1. We know there are 2, but
@@ -1237,6 +1264,10 @@
inode->u.isofs_i.i_first_extent = (isonum_733 (de->extent) +
isonum_711 (de->ext_attr_length));
+ /* Set the number of blocks for stat() - should be done before RR */
+ inode->i_blksize = PAGE_CACHE_SIZE; /* For stat() only */
+ inode->i_blocks = (inode->i_size + 511) >> 9;
+
/*
* Now test for possible Rock Ridge extensions which will override
* some of these numbers in the inode structure.
@@ -1276,7 +1307,16 @@
{
if (S_ISREG(inode->i_mode)) {
inode->i_fop = &generic_ro_fops;
- inode->i_data.a_ops = &isofs_aops;
+ switch ( inode->u.isofs_i.i_file_format ) {
+#ifdef CONFIG_ZISOFS
+ case isofs_file_compressed:
+ inode->i_data.a_ops = &zisofs_aops;
+ break;
+#endif
+ default:
+ inode->i_data.a_ops = &isofs_aops;
+ break;
+ }
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = &isofs_dir_inode_operations;
inode->i_fop = &isofs_dir_operations;
@@ -1336,15 +1376,27 @@
static int __init init_iso9660_fs(void)
{
+#ifdef CONFIG_ZISOFS
+ int err;
+
+ err = zisofs_init();
+ if ( err )
+ return err;
+#endif
return register_filesystem(&iso9660_fs_type);
}
static void __exit exit_iso9660_fs(void)
{
unregister_filesystem(&iso9660_fs_type);
+#ifdef CONFIG_ZISOFS
+ zisofs_cleanup();
+#endif
}
EXPORT_NO_SYMBOLS;
module_init(init_iso9660_fs)
module_exit(exit_iso9660_fs)
+MODULE_LICENSE("GPL");
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)