public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [2.6 PATCH]  ufs2_frag_map_fix : fixes wrong content reading in ufs2 code
@ 2004-04-12 11:06 Niraj Kumar
  2004-04-12 14:37 ` Niraj Kumar
  0 siblings, 1 reply; 2+ messages in thread
From: Niraj Kumar @ 2004-04-12 11:06 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, gcs

[-- Attachment #1: Type: text/plain, Size: 288 bytes --]

Andrew,

This is in continuation of the ufs2 read-only code that went into 2.6.5.

This patch fixes a bug where wrong content was being read off the disk
after around 4 MB mark.


Patch is also located at
http://ufs-linux.sourceforge.net/ufs2/2.6.5/ufs2_frag_map_fix.txt

Regards
Niraj



[-- Attachment #2: ufs2_frag_map_fix.txt --]
[-- Type: text/plain, Size: 5946 bytes --]

diff -ur linux-2.6.5/fs/ufs/dir.c linux-2.6.5-ufs2/fs/ufs/dir.c
--- linux-2.6.5/fs/ufs/dir.c	2004-04-04 09:07:44.000000000 +0530
+++ linux-2.6.5-ufs2/fs/ufs/dir.c	2004-04-05 14:00:37.000000000 +0530
@@ -56,13 +56,14 @@
 {
 	struct inode *inode = filp->f_dentry->d_inode;
 	int error = 0;
-	unsigned long offset, lblk, blk;
+	unsigned long offset, lblk;
 	int i, stored;
 	struct buffer_head * bh;
 	struct ufs_dir_entry * de;
 	struct super_block * sb;
 	int de_reclen;
 	unsigned flags;
+	u64     blk= 0L;
 
 	lock_kernel();
 
diff -ur linux-2.6.5/fs/ufs/inode.c linux-2.6.5-ufs2/fs/ufs/inode.c
--- linux-2.6.5/fs/ufs/inode.c	2004-04-04 09:06:26.000000000 +0530
+++ linux-2.6.5-ufs2/fs/ufs/inode.c	2004-04-12 15:02:28.000000000 +0530
@@ -50,7 +50,7 @@
 #define UFSD(x)
 #endif
 
-static int ufs_block_to_path(struct inode *inode, long i_block, int offsets[4])
+static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t offsets[4])
 {
 	struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi;
 	int ptrs = uspi->s_apb;
@@ -60,6 +60,8 @@
 		double_blocks = (1 << (ptrs_bits * 2));
 	int n = 0;
 
+	UFSD(("ptrs=uspi->s_apb = %d,double_blocks=%d \n",ptrs,double_blocks));
 	if (i_block < 0) {
 		ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
 	} else if (i_block < direct_blocks) {
@@ -87,20 +89,23 @@
  * the begining of the filesystem.
  */
 
-u64  ufs_frag_map(struct inode *inode, int frag)
+u64  ufs_frag_map(struct inode *inode, sector_t frag)
 {
 	struct ufs_inode_info *ufsi = UFS_I(inode);
 	struct super_block *sb = inode->i_sb;
 	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
-	int mask = uspi->s_apbmask>>uspi->s_fpbshift;
+	u64 mask = (u64) uspi->s_apbmask>>uspi->s_fpbshift;
 	int shift = uspi->s_apbshift-uspi->s_fpbshift;
-	int offsets[4], *p;
+	sector_t offsets[4], *p;
 	int depth = ufs_block_to_path(inode, frag >> uspi->s_fpbshift, offsets);
-	int ret = 0;
+	u64  ret = 0L;
 	u32 block;
-	u64 u2_block = 0;
+	u64 u2_block = 0L;
 	unsigned flags = UFS_SB(sb)->s_flags;
-	u64 temp = 0;
+	u64 temp = 0L;
+
+	UFSD((": frag = %lu  depth = %d\n",frag,depth));
+	UFSD((": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n",uspi->s_fpbshift,uspi->s_apbmask,mask));
 
 	if (depth == 0)
 		return 0;
@@ -116,7 +121,7 @@
 		goto out;
 	while (--depth) {
 		struct buffer_head *bh;
-		int n = *p++;
+		sector_t n = *p++;
 
 		bh = sb_bread(sb, uspi->s_sbbase + fs32_to_cpu(sb, block)+(n>>shift));
 		if (!bh)
@@ -126,20 +131,21 @@
 		if (!block)
 			goto out;
 	}
-	ret = uspi->s_sbbase + fs32_to_cpu(sb, block) + (frag & uspi->s_fpbmask);
+	ret = (u64) (uspi->s_sbbase + fs32_to_cpu(sb, block) + (frag & uspi->s_fpbmask));
 	goto out;
 ufs2:
 	u2_block = ufsi->i_u1.u2_i_data[*p++];
 	if (!u2_block)
 		goto out;
 
-	temp = (u64)uspi->s_sbbase + fs64_to_cpu(sb, u2_block);
 
 	while (--depth) {
 		struct buffer_head *bh;
-		u64 n = *p++;
+		sector_t n = *p++;
 
-		bh = sb_bread(sb, temp +(n>>shift));
+
+		temp = (u64)(uspi->s_sbbase) + fs64_to_cpu(sb, u2_block);
+		bh = sb_bread(sb, temp +(u64) (n>>shift));
 		if (!bh)
 			goto out;
 		u2_block = ((u64*)bh->b_data)[n & mask];
@@ -147,7 +153,8 @@
 		if (!u2_block)
 			goto out;
 	}
-	ret = temp + (frag & uspi->s_fpbmask);
+	temp = (u64)uspi->s_sbbase + fs64_to_cpu(sb, u2_block);
+	ret = temp + (u64) (frag & uspi->s_fpbmask);
 
 out:
 	unlock_kernel();
@@ -379,6 +386,7 @@
 	
 	if (!create) {
 		phys64 = ufs_frag_map(inode, fragment);
+		UFSD(("phys64 = %lu \n",phys64));
 		if (phys64)
 			map_bh(bh_result, sb, phys64);
 		return 0;
diff -ur linux-2.6.5/fs/ufs/super.c linux-2.6.5-ufs2/fs/ufs/super.c
--- linux-2.6.5/fs/ufs/super.c	2004-04-04 09:06:11.000000000 +0530
+++ linux-2.6.5-ufs2/fs/ufs/super.c	2004-04-12 15:03:25.000000000 +0530
@@ -93,6 +93,8 @@
 #undef UFS_SUPER_DEBUG
 #undef UFS_SUPER_DEBUG_MORE
 
+
+#undef UFS_SUPER_DEBUG_MORE
 #ifdef UFS_SUPER_DEBUG
 #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x;
 #else
@@ -157,6 +159,8 @@
 	printk("  magic:         0x%x\n", fs32_to_cpu(sb, usb->fs_magic));
 	printk("  fs_size:   %u\n",fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_size));
 	printk("  fs_dsize:  %u\n",fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_dsize));
+	printk("  bsize:         %u\n", fs32_to_cpu(usb, usb->fs_bsize));
+	printk("  fsize:         %u\n", fs32_to_cpu(usb, usb->fs_fsize));
 	printk("  fs_volname:  %s\n", usb->fs_u11.fs_u2.fs_volname);
 	printk("  fs_fsmnt:  %s\n", usb->fs_u11.fs_u2.fs_fsmnt);
 	printk("  fs_sblockloc: %u\n",fs64_to_cpu(sb,
@@ -897,6 +901,8 @@
 	uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
 	uspi->s_bshift = fs32_to_cpu(sb, usb1->fs_bshift);
 	uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);
+	UFSD(("uspi->s_bshift = %d,uspi->s_fshift = %d", uspi->s_bshift,
+		uspi->s_fshift));
 	uspi->s_fpbshift = fs32_to_cpu(sb, usb1->fs_fragshift);
 	uspi->s_fsbtodb = fs32_to_cpu(sb, usb1->fs_fsbtodb);
 	/* s_sbsize already set */
@@ -929,7 +935,12 @@
 	 * Compute another frequently used values
 	 */
 	uspi->s_fpbmask = uspi->s_fpb - 1;
-	uspi->s_apbshift = uspi->s_bshift - 2;
+	if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
+		uspi->s_apbshift = uspi->s_bshift - 3;
+	}
+	else {
+		uspi->s_apbshift = uspi->s_bshift - 2;
+	}
 	uspi->s_2apbshift = uspi->s_apbshift * 2;
 	uspi->s_3apbshift = uspi->s_apbshift * 3;
 	uspi->s_apb = 1 << uspi->s_apbshift;
diff -ur linux-2.6.5/include/linux/ufs_fs.h linux-2.6.5-ufs2/include/linux/ufs_fs.h
--- linux-2.6.5/include/linux/ufs_fs.h	2004-04-04 09:07:43.000000000 +0530
+++ linux-2.6.5-ufs2/include/linux/ufs_fs.h	2004-04-05 14:00:42.000000000 +0530
@@ -896,7 +896,7 @@
 extern struct inode * ufs_new_inode (struct inode *, int);
 
 /* inode.c */
-extern u64  ufs_frag_map (struct inode *, int);
+extern u64  ufs_frag_map (struct inode *, sector_t);
 extern void ufs_read_inode (struct inode *);
 extern void ufs_put_inode (struct inode *);
 extern void ufs_write_inode (struct inode *, int);

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [2.6 PATCH]  ufs2_frag_map_fix : fixes wrong content reading in ufs2 code
  2004-04-12 11:06 [2.6 PATCH] ufs2_frag_map_fix : fixes wrong content reading in ufs2 code Niraj Kumar
@ 2004-04-12 14:37 ` Niraj Kumar
  0 siblings, 0 replies; 2+ messages in thread
From: Niraj Kumar @ 2004-04-12 14:37 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 446 bytes --]

Niraj Kumar wrote:

> Andrew,
>
> This is in continuation of the ufs2 read-only code that went into 2.6.5.
>
> This patch fixes a bug where wrong content was being read off the disk
> after around 4 MB mark. 

Oh sorry ..... I noticed that the patch didn't applied cleanly to 2.6.5 
(possibly because
I did some hand tweaking without understanding enough about 'patch'  
........  too bad).

So here is the one which will apply cleanly.
Niraj




[-- Attachment #2: ufs2_frag_map_fix.txt --]
[-- Type: text/plain, Size: 5948 bytes --]

diff -ur linux-2.6.5/fs/ufs/dir.c linux-2.6.5-ufs2/fs/ufs/dir.c
--- linux-2.6.5/fs/ufs/dir.c	2004-04-04 09:07:44.000000000 +0530
+++ linux-2.6.5-ufs2/fs/ufs/dir.c	2004-04-05 14:00:37.000000000 +0530
@@ -56,13 +56,14 @@
 {
 	struct inode *inode = filp->f_dentry->d_inode;
 	int error = 0;
-	unsigned long offset, lblk, blk;
+	unsigned long offset, lblk;
 	int i, stored;
 	struct buffer_head * bh;
 	struct ufs_dir_entry * de;
 	struct super_block * sb;
 	int de_reclen;
 	unsigned flags;
+	u64     blk= 0L;
 
 	lock_kernel();
 
diff -ur linux-2.6.5/fs/ufs/inode.c linux-2.6.5-ufs2/fs/ufs/inode.c
--- linux-2.6.5/fs/ufs/inode.c	2004-04-04 09:06:26.000000000 +0530
+++ linux-2.6.5-ufs2/fs/ufs/inode.c	2004-04-12 15:02:28.000000000 +0530
@@ -50,7 +50,7 @@
 #define UFSD(x)
 #endif
 
-static int ufs_block_to_path(struct inode *inode, long i_block, int offsets[4])
+static int ufs_block_to_path(struct inode *inode, sector_t i_block, sector_t offsets[4])
 {
 	struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi;
 	int ptrs = uspi->s_apb;
@@ -60,6 +60,8 @@
 		double_blocks = (1 << (ptrs_bits * 2));
 	int n = 0;
 
+
+	UFSD(("ptrs=uspi->s_apb = %d,double_blocks=%d \n",ptrs,double_blocks));
 	if (i_block < 0) {
 		ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
 	} else if (i_block < direct_blocks) {
@@ -87,20 +89,23 @@
  * the begining of the filesystem.
  */
 
-u64  ufs_frag_map(struct inode *inode, int frag)
+u64  ufs_frag_map(struct inode *inode, sector_t frag)
 {
 	struct ufs_inode_info *ufsi = UFS_I(inode);
 	struct super_block *sb = inode->i_sb;
 	struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
-	int mask = uspi->s_apbmask>>uspi->s_fpbshift;
+	u64 mask = (u64) uspi->s_apbmask>>uspi->s_fpbshift;
 	int shift = uspi->s_apbshift-uspi->s_fpbshift;
-	int offsets[4], *p;
+	sector_t offsets[4], *p;
 	int depth = ufs_block_to_path(inode, frag >> uspi->s_fpbshift, offsets);
-	int ret = 0;
+	u64  ret = 0L;
 	u32 block;
-	u64 u2_block = 0;
+	u64 u2_block = 0L;
 	unsigned flags = UFS_SB(sb)->s_flags;
-	u64 temp = 0;
+	u64 temp = 0L;
+
+	UFSD((": frag = %lu  depth = %d\n",frag,depth));
+	UFSD((": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n",uspi->s_fpbshift,uspi->s_apbmask,mask));
 
 	if (depth == 0)
 		return 0;
@@ -116,7 +121,7 @@
 		goto out;
 	while (--depth) {
 		struct buffer_head *bh;
-		int n = *p++;
+		sector_t n = *p++;
 
 		bh = sb_bread(sb, uspi->s_sbbase + fs32_to_cpu(sb, block)+(n>>shift));
 		if (!bh)
@@ -126,20 +131,21 @@
 		if (!block)
 			goto out;
 	}
-	ret = uspi->s_sbbase + fs32_to_cpu(sb, block) + (frag & uspi->s_fpbmask);
+	ret = (u64) (uspi->s_sbbase + fs32_to_cpu(sb, block) + (frag & uspi->s_fpbmask));
 	goto out;
 ufs2:
 	u2_block = ufsi->i_u1.u2_i_data[*p++];
 	if (!u2_block)
 		goto out;
 
-	temp = (u64)uspi->s_sbbase + fs64_to_cpu(sb, u2_block);
 
 	while (--depth) {
 		struct buffer_head *bh;
-		u64 n = *p++;
+		sector_t n = *p++;
 
-		bh = sb_bread(sb, temp +(n>>shift));
+
+		temp = (u64)(uspi->s_sbbase) + fs64_to_cpu(sb, u2_block);
+		bh = sb_bread(sb, temp +(u64) (n>>shift));
 		if (!bh)
 			goto out;
 		u2_block = ((u64*)bh->b_data)[n & mask];
@@ -147,7 +153,8 @@
 		if (!u2_block)
 			goto out;
 	}
-	ret = temp + (frag & uspi->s_fpbmask);
+	temp = (u64)uspi->s_sbbase + fs64_to_cpu(sb, u2_block);
+	ret = temp + (u64) (frag & uspi->s_fpbmask);
 
 out:
 	unlock_kernel();
@@ -379,6 +386,7 @@
 	
 	if (!create) {
 		phys64 = ufs_frag_map(inode, fragment);
+		UFSD(("phys64 = %lu \n",phys64));
 		if (phys64)
 			map_bh(bh_result, sb, phys64);
 		return 0;
diff -ur linux-2.6.5/fs/ufs/super.c linux-2.6.5-ufs2/fs/ufs/super.c
--- linux-2.6.5/fs/ufs/super.c	2004-04-04 09:06:11.000000000 +0530
+++ linux-2.6.5-ufs2/fs/ufs/super.c	2004-04-12 15:03:25.000000000 +0530
@@ -93,6 +93,8 @@
 #undef UFS_SUPER_DEBUG
 #undef UFS_SUPER_DEBUG_MORE
 
+
+#undef UFS_SUPER_DEBUG_MORE
 #ifdef UFS_SUPER_DEBUG
 #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x;
 #else
@@ -157,6 +159,8 @@
 	printk("  magic:         0x%x\n", fs32_to_cpu(sb, usb->fs_magic));
 	printk("  fs_size:   %u\n",fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_size));
 	printk("  fs_dsize:  %u\n",fs64_to_cpu(sb, usb->fs_u11.fs_u2.fs_dsize));
+	printk("  bsize:         %u\n", fs32_to_cpu(usb, usb->fs_bsize));
+	printk("  fsize:         %u\n", fs32_to_cpu(usb, usb->fs_fsize));
 	printk("  fs_volname:  %s\n", usb->fs_u11.fs_u2.fs_volname);
 	printk("  fs_fsmnt:  %s\n", usb->fs_u11.fs_u2.fs_fsmnt);
 	printk("  fs_sblockloc: %u\n",fs64_to_cpu(sb,
@@ -897,6 +901,8 @@
 	uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
 	uspi->s_bshift = fs32_to_cpu(sb, usb1->fs_bshift);
 	uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);
+	UFSD(("uspi->s_bshift = %d,uspi->s_fshift = %d", uspi->s_bshift,
+		uspi->s_fshift));
 	uspi->s_fpbshift = fs32_to_cpu(sb, usb1->fs_fragshift);
 	uspi->s_fsbtodb = fs32_to_cpu(sb, usb1->fs_fsbtodb);
 	/* s_sbsize already set */
@@ -929,7 +935,12 @@
 	 * Compute another frequently used values
 	 */
 	uspi->s_fpbmask = uspi->s_fpb - 1;
-	uspi->s_apbshift = uspi->s_bshift - 2;
+	if ((flags & UFS_TYPE_MASK) == UFS_TYPE_UFS2) {
+		uspi->s_apbshift = uspi->s_bshift - 3;
+	}
+	else {
+		uspi->s_apbshift = uspi->s_bshift - 2;
+	}
 	uspi->s_2apbshift = uspi->s_apbshift * 2;
 	uspi->s_3apbshift = uspi->s_apbshift * 3;
 	uspi->s_apb = 1 << uspi->s_apbshift;
diff -ur linux-2.6.5/include/linux/ufs_fs.h linux-2.6.5-ufs2/include/linux/ufs_fs.h
--- linux-2.6.5/include/linux/ufs_fs.h	2004-04-04 09:07:43.000000000 +0530
+++ linux-2.6.5-ufs2/include/linux/ufs_fs.h	2004-04-05 14:00:42.000000000 +0530
@@ -896,7 +896,7 @@
 extern struct inode * ufs_new_inode (struct inode *, int);
 
 /* inode.c */
-extern u64  ufs_frag_map (struct inode *, int);
+extern u64  ufs_frag_map (struct inode *, sector_t);
 extern void ufs_read_inode (struct inode *);
 extern void ufs_put_inode (struct inode *);
 extern void ufs_write_inode (struct inode *, int);

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-04-12 14:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-04-12 11:06 [2.6 PATCH] ufs2_frag_map_fix : fixes wrong content reading in ufs2 code Niraj Kumar
2004-04-12 14:37 ` Niraj Kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox