|
@@ -1516,13 +1516,26 @@ xfs_vm_write_failed(
|
|
|
loff_t pos,
|
|
|
unsigned len)
|
|
|
{
|
|
|
- loff_t block_offset = pos & PAGE_MASK;
|
|
|
+ loff_t block_offset;
|
|
|
loff_t block_start;
|
|
|
loff_t block_end;
|
|
|
loff_t from = pos & (PAGE_CACHE_SIZE - 1);
|
|
|
loff_t to = from + len;
|
|
|
struct buffer_head *bh, *head;
|
|
|
|
|
|
+ /*
|
|
|
+ * The request pos offset might be 32 or 64 bit, this is all fine
|
|
|
+ * on 64-bit platform. However, for 64-bit pos request on 32-bit
|
|
|
+ * platform, the high 32-bit will be masked off if we evaluate the
|
|
|
+ * block_offset via (pos & PAGE_MASK) because the PAGE_MASK is
|
|
|
+ * 0xfffff000 as an unsigned long, hence the result is incorrect
|
|
|
+ * which could cause the following ASSERT failed in most cases.
|
|
|
+ * In order to avoid this, we can evaluate the block_offset of the
|
|
|
+ * start of the page by using shifts rather than masks the mismatch
|
|
|
+ * problem.
|
|
|
+ */
|
|
|
+ block_offset = (pos >> PAGE_CACHE_SHIFT) << PAGE_CACHE_SHIFT;
|
|
|
+
|
|
|
ASSERT(block_offset + from == pos);
|
|
|
|
|
|
head = page_buffers(page);
|