pnfs/blocklayout: Fix a 64-bit division/remainder issue in bl_map_stripe
authorTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 18 Sep 2014 21:03:46 +0000 (17:03 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Sun, 21 Sep 2014 18:20:20 +0000 (14:20 -0400)
kbuild test robot reports:

   fs/built-in.o: In function `bl_map_stripe':
   >> :(.text+0x965b4): undefined reference to `__aeabi_uldivmod'
   >> :(.text+0x965cc): undefined reference to `__aeabi_uldivmod'
   >> :(.text+0x96604): undefined reference to `__aeabi_uldivmod'

Fixes: 5c83746a0cf2 (pnfs/blocklayout: in-kernel GETDEVICEINFO XDR parsing)
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Christoph Hellwig <hch@lst.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/blocklayout/dev.c

index 00f159da06ee69651424339b8c4fe67012f4d4fd..5aed4f98df411be1d7612f566f5929d1db28c97a 100644 (file)
@@ -150,10 +150,13 @@ static bool bl_map_stripe(struct pnfs_block_dev *dev, u64 offset,
                struct pnfs_block_dev_map *map)
 {
        struct pnfs_block_dev *child;
-       u64 chunk = (offset / dev->chunk_size);
-       int chunk_idx = chunk % dev->nr_children;
+       u64 chunk;
+       u32 chunk_idx;
        u64 disk_offset;
 
+       chunk = div_u64(offset, dev->chunk_size);
+       div_u64_rem(chunk, dev->nr_children, &chunk_idx);
+
        if (chunk_idx > dev->nr_children) {
                dprintk("%s: invalid chunk idx %d (%lld/%lld)\n",
                        __func__, chunk_idx, offset, dev->chunk_size);
@@ -165,7 +168,7 @@ static bool bl_map_stripe(struct pnfs_block_dev *dev, u64 offset,
        offset = chunk * dev->chunk_size;
 
        /* disk offset of the stripe */
-       disk_offset = offset / dev->nr_children;
+       disk_offset = div_u64(offset, dev->nr_children);
 
        child = &dev->children[chunk_idx];
        child->map(child, disk_offset, map);