Skip to contentSkip to conversation

new 64 bit math link fail in xfs in linux-next today

PATCH In review Paul Gortmaker 4 participants 8 messages Apr 16, 2014

Subsystems (2)
lore
Share & tools
lore
#1 lore raw
Quoted 9 lines · Paul Gortmaker

Hi Dave,

Not sure if this has been reported yet, but this new failure showed up in the xtensa link of today's linux-next builds.

http://kisskb.ellerman.id.au/kisskb/buildresult/10938384/

Paul.

Try this works on i386. sorry if my mailer wraps the line:

The roundup in commit 68c1fb5d should be a roundup_64() because it is desired to round a 64 bit type by an integer and that will result in a 64 bit value. On 32 bit machines using roundup() in this case will result in the error:

ERROR: "__divdi3" [fs/xfs/xfs.ko] undefined!

---
 fs/xfs/xfs_aops.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/xfs_aops.c +1 -1
Index: b/fs/xfs/xfs_aops.c
===================================================================
@@ -1365,7 +1365,7 @@ __xfs_get_blocks(
 		if (offset < i_size_read(inode) &&
 		    offset + mapping_size >= i_size_read(inode)) {
 			/* limit mapping to block that spans EOF */
-			mapping_size = roundup(i_size_read(inode) - offset,
+			mapping_size = roundup_64(i_size_read(inode) - offset,
 					       1 << inode->i_blkbits);
 		}
 		if (mapping_size > LONG_MAX)

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#2 lore raw
Quoted 6 lines · Mark Tinguely
Quoted 5 lines · Paul Gortmaker

Hi Dave,

Not sure if this has been reported yet, but this new failure showed up in the xtensa link of today's linux-next builds.

Quoted 6 lines
Quoted 4 lines

http://kisskb.ellerman.id.au/kisskb/buildresult/10938384/

Paul.

Try this works on i386. sorry if my mailer wraps the line:

Yep, also works for xtensa too; feel free to add a reported-by and/or tested-by from me if you want.

Thanks,
Paul.
--

Quoted 27 lines

The roundup in commit 68c1fb5d should be a roundup_64() because it is desired to round a 64 bit type by an integer and that will result in a 64 bit value. On 32 bit machines using roundup() in this case will result in the error:

ERROR: "__divdi3" [fs/xfs/xfs.ko] undefined!

---
  fs/xfs/xfs_aops.c |    2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

Index: b/fs/xfs/xfs_aops.c
===================================================================

fs/xfs/xfs_aops.c +1 -1
@@ -1365,7 +1365,7 @@ __xfs_get_blocks(
  		if (offset < i_size_read(inode) &&
  		    offset + mapping_size >= i_size_read(inode)) {
  			/* limit mapping to block that spans EOF */
-			mapping_size = roundup(i_size_read(inode) - offset,
+			mapping_size = roundup_64(i_size_read(inode) - offset,
  					       1 << inode->i_blkbits);
  		}
  		if (mapping_size > LONG_MAX)
#3 lore raw

PATCH 1/1 xfs: fix 32bit __divdi3 undefined

In reply to Paul Gortmaker

The roundup in commit 68c1fb5d should be a roundup_64() because it is desired to round a 64 bit type by an integer and that will result in a 64 bit value. On 32 bit machines using roundup() in this case will result in the error:

ERROR: "__divdi3" [fs/xfs/xfs.ko] undefined!

---
 fs/xfs/xfs_aops.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/xfs/xfs_aops.c +1 -1
Index: b/fs/xfs/xfs_aops.c
===================================================================
@@ -1365,7 +1365,7 @@ __xfs_get_blocks(
 		if (offset < i_size_read(inode) &&
 		    offset + mapping_size >= i_size_read(inode)) {
 			/* limit mapping to block that spans EOF */
-			mapping_size = roundup(i_size_read(inode) - offset,
+			mapping_size = roundup_64(i_size_read(inode) - offset,
 					       1 << inode->i_blkbits);
 		}
 		if (mapping_size > LONG_MAX)

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

Reviewed-by on v1 1/1
#4 lore raw

Re: [PATCH] xfs: fix 32bit __divdi3 undefined

Quoted 10 lines · Mark Tinguely

The roundup in commit 68c1fb5d should be a roundup_64() because it is desired to round a 64 bit type by an integer and that will result in a 64 bit value. On 32 bit machines using roundup() in this case will result in the error:

ERROR: "__divdi3" [fs/xfs/xfs.ko] undefined!

Quoted 19 lines
---
 fs/xfs/xfs_aops.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: b/fs/xfs/xfs_aops.c
===================================================================

fs/xfs/xfs_aops.c +1 -1
@@ -1365,7 +1365,7 @@ __xfs_get_blocks(
 		if (offset < i_size_read(inode) &&
 		    offset + mapping_size >= i_size_read(inode)) {
 			/* limit mapping to block that spans EOF */
-			mapping_size = roundup(i_size_read(inode) - offset,
+			mapping_size = roundup_64(i_size_read(inode) - offset,
 					       1 << inode->i_blkbits);
 		}
 		if (mapping_size > LONG_MAX)
Quoted 5 lines

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#5 lore raw

Re: [PATCH] xfs: fix 32bit __divdi3 undefined

In reply to Mark Tinguely
Quoted 19 lines · Mark Tinguely

The roundup in commit 68c1fb5d should be a roundup_64() because it is desired to round a 64 bit type by an integer and that will result in a 64 bit value. On 32 bit machines using roundup() in this case will result in the error:

ERROR: "__divdi3" [fs/xfs/xfs.ko] undefined!

---
 fs/xfs/xfs_aops.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: b/fs/xfs/xfs_aops.c
===================================================================

fs/xfs/xfs_aops.c __xfs_get_blocks( · line 1371

Quoted 8 lines
fs/xfs/xfs_aops.c +1 -1
@@ -1365,7 +1365,7 @@ __xfs_get_blocks(
 		if (offset < i_size_read(inode) &&
 		    offset + mapping_size >= i_size_read(inode)) {
 			/* limit mapping to block that spans EOF */
-			mapping_size = roundup(i_size_read(inode) - offset,
+			mapping_size = roundup_64(i_size_read(inode) - offset,
 					       1 << inode->i_blkbits);
 		}
 		if (mapping_size > LONG_MAX)

I'm not going to apply this as a patch - I'm going to rebase the branch with the fix in the original patch so we don't have a bisect breakage in the branch. Don't worry, I'll add the fact you fixed the bug into the commit message...

Cheers,

Dave.

Signature · 7 lines
Dave Chinner
[email protected]

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
#6 lore raw

Re: [PATCH] xfs: fix 32bit __divdi3 undefined

Quoted 34 lines · Dave Chinner
Quoted 19 lines · Mark Tinguely

The roundup in commit 68c1fb5d should be a roundup_64() because it is desired to round a 64 bit type by an integer and that will result in a 64 bit value. On 32 bit machines using roundup() in this case will result in the error:

ERROR: "__divdi3" [fs/xfs/xfs.ko] undefined!

---
  fs/xfs/xfs_aops.c |    2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

Index: b/fs/xfs/xfs_aops.c
===================================================================

fs/xfs/xfs_aops.c __xfs_get_blocks( · line 1371

Quoted 8 lines
fs/xfs/xfs_aops.c +1 -1
@@ -1365,7 +1365,7 @@ __xfs_get_blocks(
  		if (offset<  i_size_read(inode)&&
  		offset + mapping_size>= i_size_read(inode)) {
  			/* limit mapping to block that spans EOF */
-			mapping_size = roundup(i_size_read(inode) - offset,
+			mapping_size = roundup_64(i_size_read(inode) - offset,
  					       1<<  inode->i_blkbits);
  		}
  		if (mapping_size>  LONG_MAX)

I'm not going to apply this as a patch - I'm going to rebase the branch with the fix in the original patch so we don't have a bisect breakage in the branch. Don't worry, I'll add the fact you fixed the bug into the commit message...

Quoted 3 lines

Cheers,

Dave.

Makes sense.

--Mark.

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#7 lore raw
In reply to Paul Gortmaker
Quoted 6 lines · Paul Gortmaker

Hi Dave,

Not sure if this has been reported yet, but this new failure showed up in the xtensa link of today's linux-next builds.

http://kisskb.ellerman.id.au/kisskb/buildresult/10938384/

fs/built-in.o: In function `__xfs_get_blocks':
/home/dave/src/build/x86-64/xfsdev/fs/xfs/xfs_aops.c:1368: undefined reference to `__divdi3'

Fmeh. The hunk that throws the error:

@@ -1354,6 +1362,12 @@ __xfs_get_blocks(

                ASSERT(mapping_size > 0);
                if (mapping_size > size)
                        mapping_size = size;

+ if (offset < i_size_read(inode) &&
+ offset + mapping_size >= i_size_read(inode)) {
+ /* limit mapping to block that spans EOF */
+ mapping_size = roundup(i_size_read(inode) - offset,
+ 1 << inode->i_blkbits);
+ }
if (mapping_size > LONG_MAX)
mapping_size = LONG_MAX;

You'd think a generic function like roundup() would handle that sort of 64/32 bit type problem, yes? But it doesn't, despite what the comment implies:

/* The `const' in roundup() prevents gcc-3.3 from calling __divdi3 */

#define roundup(x, y) (                                 \
{                                                       \
        const typeof(y) __y = y;                        \
        (((x) + (__y - 1)) / __y) * __y;                \
}                                                       \

)

It doesn't even have type checking that might warn you of impending problems...

<sigh>

/me looks around in the XFS code for a bit

... and finds roundup_64() in fs/xfs/xfs_linux.h. That uses do_div() to avoid this problem. And it's a static inline function, so it has type checking, too.

And so this hunk fixes the problem:

@@ -1365,7 +1365,7 @@ __xfs_get_blocks(
if (offset < i_size_read(inode) &&
offset + mapping_size >= i_size_read(inode)) {
/* limit mapping to block that spans EOF */
- mapping_size = roundup(i_size_read(inode) - offset,
+ mapping_size = roundup_64(i_size_read(inode) - offset,
1 << inode->i_blkbits);
}
if (mapping_size > LONG_MAX)

Can you test it, please, and I'll push out an updated branch hopefully in time for today's linux-next build....

Cheers,

Dave.

Signature · 2 lines
Dave Chinner
[email protected]