[patch] Re: 2.3.30 oopses (ntfs related ?) (fwd)

Benjamin C.R. LaHaise (blah@kvack.org)
Wed, 8 Dec 1999 03:23:50 -0500 (EST)


> I just got 2 oopses during init. The one in getblk (first one) is actually
> a spinlock BUG. If you need some more details, ask me.
>
> The ntfs driver appears to be broken. vol->clustersize seems to be used as
> a size or as a number of blocks depending on the places.
> The 2.3.30 patch seems to use it as a number of bits (in ntfs/super.c):

The ntfs patch I posted earlier is broken -- can you try this one against
2.3.31pre1 and tell me how it goes?

-ben

diff -ur clean/2.3.31pre1/fs/ntfs/fs.c 2.3.31pre1/fs/ntfs/fs.c
--- clean/2.3.31pre1/fs/ntfs/fs.c Mon Dec 6 23:10:54 1999
+++ 2.3.31pre1/fs/ntfs/fs.c Wed Dec 8 03:07:19 1999
@@ -812,6 +812,7 @@
struct statfs fs;
struct inode *mft;
ntfs_volume *vol;
+ ntfs_u64 size;
int error;

ntfs_debug(DEBUG_OTHER, "ntfs_statfs\n");
@@ -820,16 +821,21 @@
fs.f_type=NTFS_SUPER_MAGIC;
fs.f_bsize=vol->clustersize;

- error = ntfs_get_volumesize( NTFS_SB2VOL( sb ), &fs.f_blocks );
+ error = ntfs_get_volumesize( NTFS_SB2VOL( sb ), &size );
if( error )
return -error;
+ fs.f_blocks = size; /* volumesize is in clusters */
fs.f_bfree=ntfs_get_free_cluster_count(vol->bitmap);
fs.f_bavail=fs.f_bfree;

/* Number of files is limited by free space only, so we lie here */
fs.f_ffree=0;
mft=iget(sb,FILE_MFT);
- fs.f_files=mft->i_size >> vol->mft_recordbits;
+ if (!mft)
+ return -EIO;
+ /* So ... we lie... thus this following cast of loff_t value
+ is ok here.. */
+ fs.f_files = (unsigned long)mft->i_size / vol->mft_recordsize;
iput(mft);

/* should be read from volume */
diff -ur clean/2.3.31pre1/fs/ntfs/super.c 2.3.31pre1/fs/ntfs/super.c
--- clean/2.3.31pre1/fs/ntfs/super.c Mon Dec 6 23:10:54 1999
+++ 2.3.31pre1/fs/ntfs/super.c Wed Dec 8 03:09:29 1999
@@ -91,13 +91,12 @@
if(vol->mft_clusters_per_record<0 && vol->mft_clusters_per_record!=-10)
ntfs_error("Unexpected data #4 in boot block\n");

- vol->clustersize = vol->blocksize * vol->clusterfactor;
- if (vol->mft_clusters_per_record > 0)
- vol->mft_recordbits = vol->clustersize * vol->mft_clusters_per_record;
+ vol->clustersize=vol->blocksize*vol->clusterfactor;
+ if(vol->mft_clusters_per_record>0)
+ vol->mft_recordsize=
+ vol->clustersize*vol->mft_clusters_per_record;
else
- vol->mft_recordbits = -vol->mft_clusters_per_record;
-
- vol->mft_recordsize = 1 << vol->mft_recordbits;
+ vol->mft_recordsize=1<<(-vol->mft_clusters_per_record);
vol->index_recordsize=vol->clustersize*vol->index_clusters_per_record;
/* FIXME: long long value */
vol->mft_cluster=NTFS_GETU64(boot+0x30);
@@ -254,10 +253,9 @@
* Writes the volume size into vol_size. Returns 0 if successful
* or error.
*/
-int ntfs_get_volumesize(ntfs_volume *vol, long *vol_size )
+int ntfs_get_volumesize(ntfs_volume *vol, ntfs_u64 *vol_size )
{
ntfs_io io;
- ntfs_u64 size;
char *cluster0;

if( !vol_size )
@@ -273,11 +271,8 @@
io.do_read=1;
io.size=vol->clustersize;
ntfs_getput_clusters(vol,0,0,&io);
- size=NTFS_GETU64(cluster0+0x28);
+ *vol_size = NTFS_GETU64(cluster0+0x28);
ntfs_free(cluster0);
- /* FIXME: more than 2**32 cluster */
- /* FIXME: gcc will emit udivdi3 if we don't truncate it */
- *vol_size = ((unsigned long)size)/vol->clusterfactor;
return 0;
}

diff -ur clean/2.3.31pre1/fs/ntfs/super.h 2.3.31pre1/fs/ntfs/super.h
--- clean/2.3.31pre1/fs/ntfs/super.h Mon Apr 12 13:05:58 1999
+++ 2.3.31pre1/fs/ntfs/super.h Wed Dec 8 03:15:13 1999
@@ -10,7 +10,7 @@
#define ALLOC_REQUIRE_SIZE 2

int ntfs_get_free_cluster_count(ntfs_inode *bitmap);
-int ntfs_get_volumesize(ntfs_volume *vol, long *vol_size );
+int ntfs_get_volumesize(ntfs_volume *vol, ntfs_u64 *vol_size );
int ntfs_init_volume(ntfs_volume *vol,char *boot);
int ntfs_load_special_files(ntfs_volume *vol);
int ntfs_release_volume(ntfs_volume *vol);
diff -ur clean/2.3.31pre1/include/linux/ntfs_fs_sb.h 2.3.31pre1/include/linux/ntfs_fs_sb.h
--- clean/2.3.31pre1/include/linux/ntfs_fs_sb.h Mon Dec 6 23:10:55 1999
+++ 2.3.31pre1/include/linux/ntfs_fs_sb.h Wed Dec 8 02:56:29 1999
@@ -26,7 +26,6 @@
int clusterfactor;
int clustersize;
int mft_recordsize;
- int mft_recordbits;
int mft_clusters_per_record;
int index_recordsize;
int index_clusters_per_record;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/