Messages in this thread Patch in this message | | | Date | Wed, 09 Jun 2004 22:23:58 -0500 | From | Paul Serice <> | Subject | Re: [PATCH] iso9660 Inodes Anywhere and NFS |
| |
> Tar uses inode numbers to determine which files are hardlinked. So > if you tar up a tree containing 0-byte files, then untar it > somewhere, all 0-byte files will end up being hardlinked to each > other. The same happens when you use cp -a.
Ahhh! O.k., that changes everything.
> Or take a hybrid approach: use your scheme for directories and my > scheme for files; use bit 0 or bit 31 to indicate what scheme is > used. Then directories have unique inode numbers, and files too as > long as their directory records are in the first 64Gb of the disc.
An incremental patch is attached that should apply cleanly to the latest -mm tree. It's not a hybrid. It is a straight implementation of your suggestion. Hopefully this will make all inode numbers unique for images less than 128GB in size.
Thanks
diff -uprN -X dontdiff linux-2.6.7-rc3-mm1/fs/isofs/dir.c linux-2.6.7-rc3-mm1-isofs.3/fs/isofs/dir.c --- linux-2.6.7-rc3-mm1/fs/isofs/dir.c 2004-06-09 19:30:29.000000000 -0500 +++ linux-2.6.7-rc3-mm1-isofs.3/fs/isofs/dir.c 2004-06-09 19:43:15.000000000 -0500 @@ -106,7 +106,7 @@ static int do_isofs_readdir(struct inode { unsigned long bufsize = ISOFS_BUFFER_SIZE(inode); unsigned char bufbits = ISOFS_BUFFER_BITS(inode); - unsigned long block, offset; + unsigned long block, offset, block_saved, offset_saved; unsigned long inode_number = 0; /* Quiet GCC */ struct buffer_head *bh = NULL; int len; @@ -129,8 +129,6 @@ static int do_isofs_readdir(struct inode } de = (struct iso_directory_record *) (bh->b_data + offset); - if (first_de) - inode_number = isofs_get_ino(de); de_len = *(unsigned char *) de; @@ -147,6 +145,8 @@ static int do_isofs_readdir(struct inode continue; } + block_saved = block; + offset_saved = offset; offset += de_len; /* Make sure we have a full directory entry */ @@ -166,6 +166,15 @@ static int do_isofs_readdir(struct inode de = tmpde; } + if (first_de) { + isofs_normalize_block_and_offset(de, + &block_saved, + &offset_saved); + inode_number = isofs_get_ino(block_saved, + offset_saved, + bufbits); + } + if (de->flags[-sbi->s_high_sierra] & 0x80) { first_de = 0; filp->f_pos += de_len; diff -uprN -X dontdiff linux-2.6.7-rc3-mm1/fs/isofs/inode.c linux-2.6.7-rc3-mm1-isofs.3/fs/isofs/inode.c --- linux-2.6.7-rc3-mm1/fs/isofs/inode.c 2004-06-09 19:30:29.000000000 -0500 +++ linux-2.6.7-rc3-mm1-isofs.3/fs/isofs/inode.c 2004-06-09 19:43:15.000000000 -0500 @@ -7,7 +7,7 @@ * 1995 Mark Dobie - allow mounting of some weird VideoCDs and PhotoCDs. * 1997 Gordon Chaffee - Joliet CDs * 1998 Eric Lammerts - ISO 9660 Level 3 - * 2004 Paul Serice - Comprehensive Inode Scheme + * 2004 Paul Serice - Inode Support pushed out from 4GB to 128GB * 2004 Paul Serice - NFS Export Operations */ @@ -1229,7 +1229,9 @@ static void isofs_read_inode(struct inod de = tmpde; } - inode->i_ino = isofs_get_ino(de); + inode->i_ino = isofs_get_ino(ei->i_iget5_block, + ei->i_iget5_offset, + ISOFS_BUFFER_BITS(inode)); /* Assume it is a normal-format file unless told otherwise */ ei->i_file_format = isofs_file_normal; diff -uprN -X dontdiff linux-2.6.7-rc3-mm1/include/linux/iso_fs.h linux-2.6.7-rc3-mm1-isofs.3/include/linux/iso_fs.h --- linux-2.6.7-rc3-mm1/include/linux/iso_fs.h 2004-06-09 19:30:29.000000000 -0500 +++ linux-2.6.7-rc3-mm1-isofs.3/include/linux/iso_fs.h 2004-06-09 19:43:15.000000000 -0500 @@ -237,19 +237,13 @@ extern struct inode *isofs_iget(struct s /* Because the inode number is no longer relevant to finding the * underlying meta-data for an inode, we are free to choose a more - * convenient 32-bit number as the inode number. Because directories - * and files are block aligned (except in a few very unusual cases) - * and because blocks are limited to 32-bits, I've chosen the starting - * block that holds the file or directory data as the inode number. - * - * One nice side effect of this is that you can use "ls -i" to get the - * inode number which will tell you exactly where you need to start a - * hex dump if you want to see the contents of the directory or - * file. */ -static inline unsigned long isofs_get_ino(struct iso_directory_record *d) + * convenient 32-bit number as the inode number. The inode numbering + * scheme was recommended by Sergey Vlasov and Eric Lammerts. */ +static inline unsigned long isofs_get_ino(unsigned long block, + unsigned long offset, + unsigned long bufbits) { - return (unsigned long)isonum_733(d->extent) - + (unsigned long)isonum_711(d->ext_attr_length); + return (block << (bufbits - 5)) | (offset >> 5); } /* Every directory can have many redundant directory entries scattered | |