From patchwork Thu Jun 21 01:07:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jens Axboe X-Patchwork-Id: 10478917 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C3BA6601D7 for ; Thu, 21 Jun 2018 01:07:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B30F028AD1 for ; Thu, 21 Jun 2018 01:07:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A827D28C5B; Thu, 21 Jun 2018 01:07:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 713D428AD1 for ; Thu, 21 Jun 2018 01:07:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932278AbeFUBHi (ORCPT ); Wed, 20 Jun 2018 21:07:38 -0400 Received: from mail-io0-f193.google.com ([209.85.223.193]:38025 "EHLO mail-io0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754580AbeFUBHf (ORCPT ); Wed, 20 Jun 2018 21:07:35 -0400 Received: by mail-io0-f193.google.com with SMTP id l19-v6so1478364ioj.5 for ; Wed, 20 Jun 2018 18:07:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel-dk.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=JHvGv83pUKGXR3JhGGjwdTaGMeN8QLTDCUK9thC7tOs=; b=DBWH/IJxlabSTC0fNZilHaSzw7eNdJ6n9dp2HlwACrfhTGIwXN3VFTYAi5OL3FuF/g p5hP4z2E5FYn4opn5/+0spj2s030SvjGj1hH7ELM82x5+1GQ8tZ8he6gToYIBonGlEM3 kFhPRxq8JodXMwYUJpriio1qtmr6fNTDBzFW17Bl/fnVP+FJsHxlJed2UvPEReEw7yKp YsPDlZAjDDpiGyJjRiF2+xEEvIfSrnd4aAUF/Jfi7M7IwvJ9AKqtPHDgUZuIYNf7F5Cj VW8vljEtBdERzUcf87tlIIcUJ+tffkODQBgAxs+HFlXU4koc97JofTWtc8Q7RMV4YVSL Wriw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=JHvGv83pUKGXR3JhGGjwdTaGMeN8QLTDCUK9thC7tOs=; b=kjeEyeiTYhVJifs26YObH3mnPjtXalh2vIMJwdBPsr94qmjotGFRPCIcOJ3twjG5iB caJbsuCNgAGCl2l31Rc/DON68bk5LExEafz6102LMCbgxkrwxzlWxt1mB/vg3/wQdrdY +qc1Y/VYsMTOUMphqyR8vr87pREhyGg5D/jhT3dlJD13b0Xq9rQn2I6npZ7hwqUCHgIG QrD3Jpr+TdJePsHO3uidfo4x2P+qjvQ6aP//BBQLurwC4mRVPIN95KqG30q1+FWtkqRn jgc0kHxAm+q4tsTHVWv1vPjbMSRkzVw7mb8BOWGZQEjhqiQIfakem4GtAgGfZDZZ7ucg GAsA== X-Gm-Message-State: APt69E0EL+C1gGrBwWYhdRYLmkdCUis9UsHEmM6yGcilCS1X2d4dlwot h1nQ2NR6a9o7i7ukeF0SpUKuytWBbkI= X-Google-Smtp-Source: ADUXVKKf0vq1b8PZCRnXXbvKBwyWzskr0VLyeWsOaoVxA2Ln9PbT+gwH5hZ7kDIXv9qFa5w42jscQw== X-Received: by 2002:a6b:a510:: with SMTP id o16-v6mr17562729ioe.271.1529543254820; Wed, 20 Jun 2018 18:07:34 -0700 (PDT) Received: from x1.thefacebook.com (107.191.0.158.static.utbb.net. [107.191.0.158]) by smtp.gmail.com with ESMTPSA id u8-v6sm1482907iol.6.2018.06.20.18.07.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 20 Jun 2018 18:07:33 -0700 (PDT) From: Jens Axboe To: linux-fsdevel@vger.kernel.org Cc: viro@zeniv.linux.org.uk, akpm@linux-foundation.org, Jens Axboe Subject: [PATCH 2/4] mpage: mpage_readpages() should submit IO as read-ahead Date: Wed, 20 Jun 2018 19:07:23 -0600 Message-Id: <20180621010725.17813-3-axboe@kernel.dk> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180621010725.17813-1-axboe@kernel.dk> References: <20180621010725.17813-1-axboe@kernel.dk> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP a_ops->readpages() is only ever used for read-ahead, yet we don't flag the IO being submitted as such. Fix that up. Any file system that uses mpage_readpages() as its ->readpages() implementation will now get this right. Since we're passing in whether the IO is read-ahead or not, we don't need to pass in the 'gfp' separately, as it is dependent on the IO being read-ahead. Kill off that member. Add some documentation notes on ->readpages() being purely for read-ahead. Signed-off-by: Jens Axboe --- fs/f2fs/data.c | 5 +++++ fs/mpage.c | 29 +++++++++++++++++++---------- include/linux/fs.h | 4 ++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 8f931d699287..b7c9b58acf3e 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1421,6 +1421,11 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, /* * This function was originally taken from fs/mpage.c, and customized for f2fs. * Major change was from block_size == page_size in f2fs by default. + * + * Note that the aops->readpages() function is ONLY used for read-ahead. If + * this function ever deviates from doing just read-ahead, it should either + * use ->readpage() or do the necessary surgery to decouple ->readpages() + * readom read-ahead. */ static int f2fs_mpage_readpages(struct address_space *mapping, struct list_head *pages, struct page *page, diff --git a/fs/mpage.c b/fs/mpage.c index 0ecac5c410f4..b0f9de977526 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -137,11 +137,11 @@ struct mpage_readpage_args { struct bio *bio; struct page *page; unsigned nr_pages; + bool is_readahead; sector_t last_block_in_bio; struct buffer_head map_bh; unsigned long first_logical_block; get_block_t *get_block; - gfp_t gfp; }; /* @@ -170,8 +170,18 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args) struct block_device *bdev = NULL; int length; int fully_mapped = 1; + int op_flags; unsigned nblocks; unsigned relative_block; + gfp_t gfp; + + if (args->is_readahead) { + op_flags = REQ_RAHEAD; + gfp = readahead_gfp_mask(page->mapping); + } else { + op_flags = 0; + gfp = mapping_gfp_constraint(page->mapping, GFP_KERNEL); + } if (page_has_buffers(page)) goto confused; @@ -283,7 +293,7 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args) * This page will go to BIO. Do we need to send this BIO off first? */ if (args->bio && (args->last_block_in_bio != blocks[0] - 1)) - args->bio = mpage_bio_submit(REQ_OP_READ, 0, args->bio); + args->bio = mpage_bio_submit(REQ_OP_READ, op_flags, args->bio); alloc_new: if (args->bio == NULL) { @@ -293,14 +303,14 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args) goto out; } args->bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9), - min_t(int, args->nr_pages, BIO_MAX_PAGES), args->gfp); + min_t(int, args->nr_pages, BIO_MAX_PAGES), gfp); if (args->bio == NULL) goto confused; } length = first_hole << blkbits; if (bio_add_page(args->bio, page, length, 0) < length) { - args->bio = mpage_bio_submit(REQ_OP_READ, 0, args->bio); + args->bio = mpage_bio_submit(REQ_OP_READ, op_flags, args->bio); goto alloc_new; } @@ -308,7 +318,7 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args) nblocks = map_bh->b_size >> blkbits; if ((buffer_boundary(map_bh) && relative_block == nblocks) || (first_hole != blocks_per_page)) - args->bio = mpage_bio_submit(REQ_OP_READ, 0, args->bio); + args->bio = mpage_bio_submit(REQ_OP_READ, op_flags, args->bio); else args->last_block_in_bio = blocks[blocks_per_page - 1]; out: @@ -316,7 +326,7 @@ static struct bio *do_mpage_readpage(struct mpage_readpage_args *args) confused: if (args->bio) - args->bio = mpage_bio_submit(REQ_OP_READ, 0, args->bio); + args->bio = mpage_bio_submit(REQ_OP_READ, op_flags, args->bio); if (!PageUptodate(page)) block_read_full_page(page, args->get_block); else @@ -374,7 +384,7 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages, { struct mpage_readpage_args args = { .get_block = get_block, - .gfp = readahead_gfp_mask(mapping), + .is_readahead = true, }; unsigned page_idx; @@ -385,7 +395,7 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages, list_del(&page->lru); if (!add_to_page_cache_lru(page, mapping, page->index, - args.gfp)) { + readahead_gfp_mask(mapping))) { args.page = page; args.nr_pages = nr_pages - page_idx; args.bio = do_mpage_readpage(&args); @@ -394,7 +404,7 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages, } BUG_ON(!list_empty(pages)); if (args.bio) - mpage_bio_submit(REQ_OP_READ, 0, args.bio); + mpage_bio_submit(REQ_OP_READ, REQ_RAHEAD, args.bio); return 0; } EXPORT_SYMBOL(mpage_readpages); @@ -408,7 +418,6 @@ int mpage_readpage(struct page *page, get_block_t get_block) .page = page, .nr_pages = 1, .get_block = get_block, - .gfp = mapping_gfp_constraint(page->mapping, GFP_KERNEL), }; args.bio = do_mpage_readpage(&args); diff --git a/include/linux/fs.h b/include/linux/fs.h index 5c91108846db..b45c34a9b28d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -341,6 +341,10 @@ struct address_space_operations { /* Set a page dirty. Return true if this dirtied it */ int (*set_page_dirty)(struct page *page); + /* + * Reads in the requested pages. Unlike ->readpage(), this is + * PURELY used for read-ahead!. + */ int (*readpages)(struct file *filp, struct address_space *mapping, struct list_head *pages, unsigned nr_pages);