* [PATCH] ceph: avoid 32-bit page index overflow
@ 2012-10-02 15:28 Alex Elder
2012-10-02 16:20 ` Sage Weil
2012-10-02 16:32 ` Christoph Hellwig
0 siblings, 2 replies; 4+ messages in thread
From: Alex Elder @ 2012-10-02 15:28 UTC (permalink / raw)
To: ceph-devel
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 casting all uses of page->index used in this way to
the desired 64-bit type.
This fixes http://tracker.newdream.net/issues/3112
Reported-by: Mohamed Pakkeer <pakkeer.mohideen@realimage.com>
Signed-off-by: Alex Elder <elder@inktank.com>
---
fs/ceph/addr.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 4469b63..15dee48 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -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->index << PAGE_CACHE_SHIFT, &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->index << PAGE_CACHE_SHIFT;
/* 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 = (loff_t) page->index << PAGE_CACHE_SHIFT;
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->index << PAGE_CACHE_SHIFT;
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 = (loff_t) page->index << PAGE_CACHE_SHIFT;
loff_t size, len;
int ret;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] ceph: avoid 32-bit page index overflow
2012-10-02 15:28 [PATCH] ceph: avoid 32-bit page index overflow Alex Elder
@ 2012-10-02 16:20 ` Sage Weil
2012-10-02 16:32 ` Christoph Hellwig
1 sibling, 0 replies; 4+ messages in thread
From: Sage Weil @ 2012-10-02 16:20 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
Yay!
Reviewed-by: Sage Weil <sage@inktank.com>
On Tue, 2 Oct 2012, Alex Elder wrote:
> 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 casting all uses of page->index used in this way to
> the desired 64-bit type.
>
> This fixes http://tracker.newdream.net/issues/3112
>
> Reported-by: Mohamed Pakkeer <pakkeer.mohideen@realimage.com>
> Signed-off-by: Alex Elder <elder@inktank.com>
> ---
> fs/ceph/addr.c | 11 +++++------
> 1 file changed, 5 insertions(+), 6 deletions(-)
>
> diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
> index 4469b63..15dee48 100644
> --- a/fs/ceph/addr.c
> +++ b/fs/ceph/addr.c
> @@ -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->index << PAGE_CACHE_SHIFT, &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->index << PAGE_CACHE_SHIFT;
>
> /* 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 = (loff_t) page->index << PAGE_CACHE_SHIFT;
> 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->index << PAGE_CACHE_SHIFT;
> 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 = (loff_t) page->index << PAGE_CACHE_SHIFT;
> loff_t size, len;
> int ret;
>
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] ceph: avoid 32-bit page index overflow
2012-10-02 15:28 [PATCH] ceph: avoid 32-bit page index overflow Alex Elder
2012-10-02 16:20 ` Sage Weil
@ 2012-10-02 16:32 ` Christoph Hellwig
2012-10-02 19:21 ` Alex Elder
1 sibling, 1 reply; 4+ messages in thread
From: Christoph Hellwig @ 2012-10-02 16:32 UTC (permalink / raw)
To: Alex Elder; +Cc: ceph-devel
On Tue, Oct 02, 2012 at 10:28:24AM -0500, Alex Elder wrote:
> 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 casting all uses of page->index used in this way to
> the desired 64-bit type.
It would be cleaner if you'd use the page_offset helper, which was
added to fix this problem without having to remember the right casts
everywhere.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] ceph: avoid 32-bit page index overflow
2012-10-02 16:32 ` Christoph Hellwig
@ 2012-10-02 19:21 ` Alex Elder
0 siblings, 0 replies; 4+ messages in thread
From: Alex Elder @ 2012-10-02 19:21 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: ceph-devel
On 10/02/2012 11:32 AM, Christoph Hellwig wrote:
> On Tue, Oct 02, 2012 at 10:28:24AM -0500, Alex Elder wrote:
>> 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 casting all uses of page->index used in this way to
>> the desired 64-bit type.
>
> It would be cleaner if you'd use the page_offset helper, which was
> added to fix this problem without having to remember the right casts
> everywhere.
Will do. Thanks Christoph.
-Alex
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-10-02 19:21 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-02 15:28 [PATCH] ceph: avoid 32-bit page index overflow Alex Elder
2012-10-02 16:20 ` Sage Weil
2012-10-02 16:32 ` Christoph Hellwig
2012-10-02 19:21 ` Alex Elder
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.