From patchwork Tue Oct 2 15:28:24 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Elder X-Patchwork-Id: 1538001 Return-Path: X-Original-To: patchwork-ceph-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 31BE0DFFAD for ; Tue, 2 Oct 2012 15:28:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754146Ab2JBP21 (ORCPT ); Tue, 2 Oct 2012 11:28:27 -0400 Received: from mail-ie0-f174.google.com ([209.85.223.174]:50110 "EHLO mail-ie0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754049Ab2JBP20 (ORCPT ); Tue, 2 Oct 2012 11:28:26 -0400 Received: by ieak13 with SMTP id k13so14913314iea.19 for ; Tue, 02 Oct 2012 08:28:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject :content-type:content-transfer-encoding:x-gm-message-state; bh=zqmK4mG2bWUc7UoXY6oZ2JgqYokuHMEoBHpXLPVSFM8=; b=h5LlCciJDp5wIwJ9lnarcSb8uArqJO6u4G5Djj20YpOIyD7xn2UVmh9HvdhmOb8ifV 5BgQr5cwIMClVlraEqEFpFeU7Xem7SqGlA8WQSa5jXWXPIMICdTsqF7w0mF6GtvbJIWV jCgzYqGGHvBefX199a4Cs7UjldC2cubIQw++nvvnQyNiMY/TQoNOwYaUAwGZOq8Q031l WwoGYxVSzg12iZ/8aL4spAYaYyrZRz8EscyigJa1r4znDs/Tm+Z5/eepJBzSsRKtMUdj zaki9VlFNBS8k1KM7BhFfkeCCjyiq+9XgiLyTKas2PH89OM+qnqpbdq/qDPWRHiDoAms pDQA== Received: by 10.50.12.168 with SMTP id z8mr9175649igb.74.1349191706179; Tue, 02 Oct 2012 08:28:26 -0700 (PDT) Received: from [172.22.22.4] (c-71-195-31-37.hsd1.mn.comcast.net. [71.195.31.37]) by mx.google.com with ESMTPS id wn3sm1500854igb.12.2012.10.02.08.28.24 (version=SSLv3 cipher=OTHER); Tue, 02 Oct 2012 08:28:25 -0700 (PDT) Message-ID: <506B0818.1040407@inktank.com> Date: Tue, 02 Oct 2012 10:28:24 -0500 From: Alex Elder User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120912 Thunderbird/15.0.1 MIME-Version: 1.0 To: ceph-devel@vger.kernel.org Subject: [PATCH] ceph: avoid 32-bit page index overflow X-Gm-Message-State: ALoCoQnbeIcMCNfb38UDv91koBAa3cSvMvTzsbzEHVQsDtmJSxzgNo+OsJ1VQJAijXsqrm10TACH Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org 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 Signed-off-by: Alex Elder Reviewed-by: Sage Weil --- fs/ceph/addr.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) 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; 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);