ceph: avoid 32-bit page index overflow
A pgoff_t is defined (by default) to have type (unsigned long). On architectures such as i686 that's a 32-bit type. The ceph address space code was attempting to produce 64 bit offsets by shifting a page's index by PAGE_CACHE_SHIFT, but the result was not what was desired because the shift occurred before the result got promoted to 64 bits. Fix this by converting all uses of page->index used in this way to use the page_offset() macro, which ensures the 64-bit result has the intended value. This fixes http://tracker.newdream.net/issues/3112 Reported-by: Mohamed Pakkeer <pakkeer.mohideen@realimage.com> Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Sage Weil <sage@inktank.com>
This commit is contained in:
parent
457712a0bc
commit
6285bc2312
|
@ -205,7 +205,7 @@ static int readpage_nounlock(struct file *filp, struct page *page)
|
|||
dout("readpage inode %p file %p page %p index %lu\n",
|
||||
inode, filp, page, page->index);
|
||||
err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
|
||||
page->index << PAGE_CACHE_SHIFT, &len,
|
||||
(u64) page_offset(page), &len,
|
||||
ci->i_truncate_seq, ci->i_truncate_size,
|
||||
&page, 1, 0);
|
||||
if (err == -ENOENT)
|
||||
|
@ -286,7 +286,7 @@ static int start_read(struct inode *inode, struct list_head *page_list, int max)
|
|||
int nr_pages = 0;
|
||||
int ret;
|
||||
|
||||
off = page->index << PAGE_CACHE_SHIFT;
|
||||
off = (u64) page_offset(page);
|
||||
|
||||
/* count pages */
|
||||
next_index = page->index;
|
||||
|
@ -426,7 +426,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
|
|||
struct ceph_inode_info *ci;
|
||||
struct ceph_fs_client *fsc;
|
||||
struct ceph_osd_client *osdc;
|
||||
loff_t page_off = page->index << PAGE_CACHE_SHIFT;
|
||||
loff_t page_off = page_offset(page);
|
||||
int len = PAGE_CACHE_SIZE;
|
||||
loff_t i_size;
|
||||
int err = 0;
|
||||
|
@ -817,8 +817,7 @@ get_more_pages:
|
|||
/* ok */
|
||||
if (locked_pages == 0) {
|
||||
/* prepare async write request */
|
||||
offset = (unsigned long long)page->index
|
||||
<< PAGE_CACHE_SHIFT;
|
||||
offset = (u64) page_offset(page);
|
||||
len = wsize;
|
||||
req = ceph_osdc_new_request(&fsc->client->osdc,
|
||||
&ci->i_layout,
|
||||
|
@ -1180,7 +1179,7 @@ static int ceph_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||
struct inode *inode = vma->vm_file->f_dentry->d_inode;
|
||||
struct page *page = vmf->page;
|
||||
struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
|
||||
loff_t off = page->index << PAGE_CACHE_SHIFT;
|
||||
loff_t off = page_offset(page);
|
||||
loff_t size, len;
|
||||
int ret;
|
||||
|
||||
|
|
Loading…
Reference in New Issue