lkml.org 
[lkml]   [2006]   [Feb]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: cramfs mounts provide corrupted content since 2.6.15
Olaf Hering writes:
> On Sat, Feb 25, Dave Johnson wrote:
>
> > Looking at your output it's definitely getting inodes confused with
> > each other so the checks in cramfs_iget5_test() aren't working.
> >
> > Can you stat the files in question to make sure they are actually
> > inode #1 on a working as well as non-working kernel? If your mkcramfs
> > isn't using #1 for empty files/links/dirs that'd be the problem.
>
> Another try, and different results again:

Is it the same files every time you mount/umount the image?


I think I've spotted an issue.

Both ifind() and find_inode() will call the test function on inodes
that still have I_LOCK|I_NEW set. This means everything that the
test function needs _must_ be set in the set function (which is called
while the inode_lock is still held).
This could cause issues for inodes of 1 (only i_ino is getting set
right now).

However since you're seeing issues for inodes != 1, it could indicate
code elsewhere that isn't checking for I_LOCK|I_NEW.
Anyway, can you give the following patch a try?

--
Dave Johnson
Starent Networks

======================================

Fill out inode contents in cramfs_iget5_set() instead of get_cramfs_inode() to
prevent issues if cramfs_iget5_test() is called with I_LOCK|I_NEW still set.
Signed-off-by: Dave Johnson <djohnson+linux-kernel@sw.starentnetworks.com>

diff -Naur linux-2.6.15.4.orig/fs/cramfs/inode.c linux-2.6.15.4/fs/cramfs/inode.c
--- linux-2.6.15.4.orig/fs/cramfs/inode.c 2006-02-10 07:22:48.000000000 +0000
+++ linux-2.6.15.4/fs/cramfs/inode.c 2006-02-27 15:16:52.000000000 +0000
@@ -66,8 +66,36 @@

static int cramfs_iget5_set(struct inode *inode, void *opaque)
{
+ static struct timespec zerotime;
struct cramfs_inode *cramfs_inode = opaque;
+ inode->i_mode = cramfs_inode->mode;
+ inode->i_uid = cramfs_inode->uid;
+ inode->i_size = cramfs_inode->size;
+ inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1;
+ inode->i_blksize = PAGE_CACHE_SIZE;
+ inode->i_gid = cramfs_inode->gid;
+ /* Struct copy intentional */
+ inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime;
inode->i_ino = CRAMINO(cramfs_inode);
+ /* inode->i_nlink is left 1 - arguably wrong for directories,
+ but it's the best we can do without reading the directory
+ contents. 1 yields the right result in GNU find, even
+ without -noleaf option. */
+ if (S_ISREG(inode->i_mode)) {
+ inode->i_fop = &generic_ro_fops;
+ inode->i_data.a_ops = &cramfs_aops;
+ } else if (S_ISDIR(inode->i_mode)) {
+ inode->i_op = &cramfs_dir_inode_operations;
+ inode->i_fop = &cramfs_directory_operations;
+ } else if (S_ISLNK(inode->i_mode)) {
+ inode->i_op = &page_symlink_inode_operations;
+ inode->i_data.a_ops = &cramfs_aops;
+ } else {
+ inode->i_size = 0;
+ inode->i_blocks = 0;
+ init_special_inode(inode, inode->i_mode,
+ old_decode_dev(cramfs_inode->size));
+ }
return 0;
}

@@ -77,37 +105,7 @@
struct inode *inode = iget5_locked(sb, CRAMINO(cramfs_inode),
cramfs_iget5_test, cramfs_iget5_set,
cramfs_inode);
- static struct timespec zerotime;
-
if (inode && (inode->i_state & I_NEW)) {
- inode->i_mode = cramfs_inode->mode;
- inode->i_uid = cramfs_inode->uid;
- inode->i_size = cramfs_inode->size;
- inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1;
- inode->i_blksize = PAGE_CACHE_SIZE;
- inode->i_gid = cramfs_inode->gid;
- /* Struct copy intentional */
- inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime;
- inode->i_ino = CRAMINO(cramfs_inode);
- /* inode->i_nlink is left 1 - arguably wrong for directories,
- but it's the best we can do without reading the directory
- contents. 1 yields the right result in GNU find, even
- without -noleaf option. */
- if (S_ISREG(inode->i_mode)) {
- inode->i_fop = &generic_ro_fops;
- inode->i_data.a_ops = &cramfs_aops;
- } else if (S_ISDIR(inode->i_mode)) {
- inode->i_op = &cramfs_dir_inode_operations;
- inode->i_fop = &cramfs_directory_operations;
- } else if (S_ISLNK(inode->i_mode)) {
- inode->i_op = &page_symlink_inode_operations;
- inode->i_data.a_ops = &cramfs_aops;
- } else {
- inode->i_size = 0;
- inode->i_blocks = 0;
- init_special_inode(inode, inode->i_mode,
- old_decode_dev(cramfs_inode->size));
- }
unlock_new_inode(inode);
}
return inode;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2006-02-27 17:34    [from the cache]
©2003-2011 Jasper Spaans