From patchwork Fri Jun 27 09:57:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Shilovsky X-Patchwork-Id: 4434291 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id BB7AA9F2C8 for ; Fri, 27 Jun 2014 09:58:14 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C14F220221 for ; Fri, 27 Jun 2014 09:58:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C1A542026D for ; Fri, 27 Jun 2014 09:58:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753304AbaF0J6K (ORCPT ); Fri, 27 Jun 2014 05:58:10 -0400 Received: from mail-lb0-f175.google.com ([209.85.217.175]:57040 "EHLO mail-lb0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753285AbaF0J6H (ORCPT ); Fri, 27 Jun 2014 05:58:07 -0400 Received: by mail-lb0-f175.google.com with SMTP id n15so3870908lbi.34 for ; Fri, 27 Jun 2014 02:58:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:subject:date:message-id:in-reply-to:references; bh=Y3Flw1Yhe/rz9iNixpdL15GyAGgufonVdIrxEa/pBz0=; b=DNNH5tboEo5ATzD3awGbSuzLuC3YmagtBBD+WoHUqgCdsvP/UpS0Z6s9+oQdxKgJRd 6PAs0FlFEM9X97yGn9ES6WXaMdjodcXt4tKPJtBFP2NAeOcemnIeWdKM+QbBkEmfq58M xH5b8LSiJHJmwLoNigoLfvwHfxsWDnXIjuOHz/SQ5sZrTzujFZBLL/2Ldqnl2zF17It9 wv+2NwK+YRfjFwUTfZdc5ugWcSUn7tCxOaKPvZiw5Tq9BiUGTs2nelM+Z6zxAvymts7k yeCfW1GUsmiiiEFUhlw0Y3TS+bv4L3Llfd8EOqOqdv/Ys5mQ7TxiS8KrP6lZyiYfJ0Hy pxew== X-Received: by 10.152.170.199 with SMTP id ao7mr15984902lac.44.1403863085774; Fri, 27 Jun 2014 02:58:05 -0700 (PDT) Received: from localhost.localdomain ([92.43.3.6]) by mx.google.com with ESMTPSA id y8sm10969918lbr.18.2014.06.27.02.58.03 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 27 Jun 2014 02:58:04 -0700 (PDT) From: Pavel Shilovsky To: linux-cifs@vger.kernel.org Subject: [PATCH v2 02/16] CIFS: Separate page processing from writepages Date: Fri, 27 Jun 2014 13:57:39 +0400 Message-Id: <1403863073-19526-3-git-send-email-pshilovsky@samba.org> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1403863073-19526-1-git-send-email-pshilovsky@samba.org> References: <1403863073-19526-1-git-send-email-pshilovsky@samba.org> Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Pavel Shilovsky Reviewed-by: --- fs/cifs/file.c | 152 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 82 insertions(+), 70 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 6b6df30..69d1763 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1878,6 +1878,86 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) return rc; } +static unsigned int +wdata_prepare_pages(struct cifs_writedata *wdata, unsigned int found_pages, + struct address_space *mapping, + struct writeback_control *wbc, + pgoff_t end, pgoff_t *index, pgoff_t *next, bool *done) +{ + unsigned int nr_pages = 0, i; + struct page *page; + + for (i = 0; i < found_pages; i++) { + page = wdata->pages[i]; + /* + * At this point we hold neither mapping->tree_lock nor + * lock on the page itself: the page may be truncated or + * invalidated (changing page->mapping to NULL), or even + * swizzled back from swapper_space to tmpfs file + * mapping + */ + + if (nr_pages == 0) + lock_page(page); + else if (!trylock_page(page)) + break; + + if (unlikely(page->mapping != mapping)) { + unlock_page(page); + break; + } + + if (!wbc->range_cyclic && page->index > end) { + *done = true; + unlock_page(page); + break; + } + + if (*next && (page->index != *next)) { + /* Not next consecutive page */ + unlock_page(page); + break; + } + + if (wbc->sync_mode != WB_SYNC_NONE) + wait_on_page_writeback(page); + + if (PageWriteback(page) || + !clear_page_dirty_for_io(page)) { + unlock_page(page); + break; + } + + /* + * This actually clears the dirty bit in the radix tree. + * See cifs_writepage() for more commentary. + */ + set_page_writeback(page); + if (page_offset(page) >= i_size_read(mapping->host)) { + *done = true; + unlock_page(page); + end_page_writeback(page); + break; + } + + wdata->pages[i] = page; + *next = page->index + 1; + ++nr_pages; + } + + /* reset index to refind any pages skipped */ + if (nr_pages == 0) + *index = wdata->pages[0]->index + 1; + + /* put any pages we aren't going to use */ + for (i = nr_pages; i < found_pages; i++) { + page_cache_release(wdata->pages[i]); + wdata->pages[i] = NULL; + } + + return nr_pages; +} + static int cifs_writepages(struct address_space *mapping, struct writeback_control *wbc) { @@ -1886,7 +1966,6 @@ static int cifs_writepages(struct address_space *mapping, pgoff_t end, index; struct cifs_writedata *wdata; struct TCP_Server_Info *server; - struct page *page; int rc = 0; /* @@ -1944,75 +2023,8 @@ retry: break; } - nr_pages = 0; - for (i = 0; i < found_pages; i++) { - page = wdata->pages[i]; - /* - * At this point we hold neither mapping->tree_lock nor - * lock on the page itself: the page may be truncated or - * invalidated (changing page->mapping to NULL), or even - * swizzled back from swapper_space to tmpfs file - * mapping - */ - - if (nr_pages == 0) - lock_page(page); - else if (!trylock_page(page)) - break; - - if (unlikely(page->mapping != mapping)) { - unlock_page(page); - break; - } - - if (!wbc->range_cyclic && page->index > end) { - done = true; - unlock_page(page); - break; - } - - if (next && (page->index != next)) { - /* Not next consecutive page */ - unlock_page(page); - break; - } - - if (wbc->sync_mode != WB_SYNC_NONE) - wait_on_page_writeback(page); - - if (PageWriteback(page) || - !clear_page_dirty_for_io(page)) { - unlock_page(page); - break; - } - - /* - * This actually clears the dirty bit in the radix tree. - * See cifs_writepage() for more commentary. - */ - set_page_writeback(page); - - if (page_offset(page) >= i_size_read(mapping->host)) { - done = true; - unlock_page(page); - end_page_writeback(page); - break; - } - - wdata->pages[i] = page; - next = page->index + 1; - ++nr_pages; - } - - /* reset index to refind any pages skipped */ - if (nr_pages == 0) - index = wdata->pages[0]->index + 1; - - /* put any pages we aren't going to use */ - for (i = nr_pages; i < found_pages; i++) { - page_cache_release(wdata->pages[i]); - wdata->pages[i] = NULL; - } + nr_pages = wdata_prepare_pages(wdata, found_pages, mapping, wbc, + end, &index, &next, &done); /* nothing to write? */ if (nr_pages == 0) {