From patchwork Sat Aug 6 15:52:13 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peng Tao X-Patchwork-Id: 1041742 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p76FqgN8008431 for ; Sat, 6 Aug 2011 15:53:05 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752901Ab1HFPxE (ORCPT ); Sat, 6 Aug 2011 11:53:04 -0400 Received: from mail-pz0-f42.google.com ([209.85.210.42]:41908 "EHLO mail-pz0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751899Ab1HFPxD (ORCPT ); Sat, 6 Aug 2011 11:53:03 -0400 Received: by mail-pz0-f42.google.com with SMTP id 37so5621454pzk.1 for ; Sat, 06 Aug 2011 08:53:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=4BNgWBb4Qo6TsiGrXla6N6Qx9Vt4/v2VH0Maum0ptsw=; b=qVaE7uStLASIL61uwO/Bo3vpUIvejpiQWzuz5fkqNjPALRIyTq3/X5cfn4/8ERNkNH jBBXAlhnjHP8BhIuUQYLbFSJjnuqMh79LuQlYr4FnuR5ngblSfvxvOZu4HJ7EzX2C9hT 6YU/Ejo4lbIrIFFw5wNkF9Dp70eYiNM2Lg3JQ= Received: by 10.142.179.4 with SMTP id b4mr3492491wff.146.1312645982732; Sat, 06 Aug 2011 08:53:02 -0700 (PDT) Received: from debian-sid.localdomain ([123.118.148.226]) by mx.google.com with ESMTPS id l7sm4280038pbh.42.2011.08.06.08.52.56 (version=SSLv3 cipher=OTHER); Sat, 06 Aug 2011 08:53:01 -0700 (PDT) From: Peng Tao To: linux-nfs@vger.kernel.org Cc: rees@umich.edu, bhalevy@tonian.com, Trond.Myklebust@netapp.com, Peng Tao Subject: [PATCH 1/2] pNFS: deal with ld write failure Date: Sat, 6 Aug 2011 08:52:13 -0700 Message-Id: <1312645934-4436-2-git-send-email-bergwolf@gmail.com> X-Mailer: git-send-email 1.7.1.262.g5ef3d In-Reply-To: <1312645934-4436-1-git-send-email-bergwolf@gmail.com> References: <1312645934-4436-1-git-send-email-bergwolf@gmail.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Sat, 06 Aug 2011 15:53:05 +0000 (UTC) For pnfs pagelist write failure, we need to pg_recoalesce and resend IO to mds. Signed-off-by: Peng Tao --- fs/nfs/internal.h | 4 ++++ fs/nfs/pnfs.c | 35 ++++++++++++++++++++++++++++++++--- fs/nfs/write.c | 21 ++++++++++++++------- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index ab12913..62f183d 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -305,6 +305,10 @@ extern void nfs_readdata_release(struct nfs_read_data *rdata); /* write.c */ extern int nfs_generic_flush(struct nfs_pageio_descriptor *desc, struct list_head *head); +extern int do_nfs_writepage(struct page *page, struct writeback_control *wbc, + struct nfs_pageio_descriptor *pgio); +extern void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio, + struct inode *inode, int ioflags); extern void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio); extern void nfs_writedata_release(struct nfs_write_data *wdata); extern void nfs_commit_free(struct nfs_write_data *p); diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index e550e88..08aba45 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1172,6 +1172,13 @@ int pnfs_ld_write_done(struct nfs_write_data *data) { int status; + struct nfs_pageio_descriptor pgio; + struct writeback_control wbc = { + .sync_mode = WB_SYNC_ALL, + .range_start = data->mds_offset, + .nr_to_write = data->npages, + .range_end = LLONG_MAX, + }; if (!data->pnfs_error) { pnfs_set_layoutcommit(data); @@ -1180,11 +1187,33 @@ pnfs_ld_write_done(struct nfs_write_data *data) return 0; } + put_lseg(data->lseg); + data->lseg = NULL; dprintk("%s: pnfs_error=%d, retry via MDS\n", __func__, data->pnfs_error); - status = nfs_initiate_write(data, NFS_CLIENT(data->inode), - data->mds_ops, NFS_FILE_SYNC); - return status ? : -EAGAIN; + nfs_pageio_init_write_mds(&pgio, data->inode, FLUSH_STABLE); + pgio.pg_recoalesce = 1; + while (!list_empty(&data->pages)) { + struct nfs_page *req = nfs_list_entry(data->pages.next); + struct page *page = req->wb_page; + + nfs_list_remove_request(req); + nfs_clear_page_tag_locked(req); + + end_page_writeback(page); + + lock_page(page); + status = do_nfs_writepage(page, &wbc, &pgio); + if (status) { + /* FIXME: is this enough?? */ + set_page_dirty(page); + } + unlock_page(page); + } + nfs_pageio_complete(&pgio); + nfs_writedata_release(data); + + return 0; } EXPORT_SYMBOL_GPL(pnfs_ld_write_done); diff --git a/fs/nfs/write.c b/fs/nfs/write.c index b39b37f..0ccdf98 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -285,14 +285,9 @@ out: return ret; } -static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, struct nfs_pageio_descriptor *pgio) +int do_nfs_writepage(struct page *page, struct writeback_control *wbc, struct nfs_pageio_descriptor *pgio) { - struct inode *inode = page->mapping->host; int ret; - - nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); - nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1); - nfs_pageio_cond_complete(pgio, page->index); ret = nfs_page_async_flush(pgio, page, wbc->sync_mode == WB_SYNC_NONE); if (ret == -EAGAIN) { @@ -301,6 +296,17 @@ static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, st } return ret; } +EXPORT_SYMBOL_GPL(do_nfs_writepage); + +static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, struct nfs_pageio_descriptor *pgio) +{ + struct inode *inode = page->mapping->host; + + nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); + nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1); + + return do_nfs_writepage(page, wbc, pgio); +} /* * Write an mmapped page to the server. @@ -1051,12 +1057,13 @@ static const struct nfs_pageio_ops nfs_pageio_write_ops = { .pg_doio = nfs_generic_pg_writepages, }; -static void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio, +void nfs_pageio_init_write_mds(struct nfs_pageio_descriptor *pgio, struct inode *inode, int ioflags) { nfs_pageio_init(pgio, inode, &nfs_pageio_write_ops, NFS_SERVER(inode)->wsize, ioflags); } +EXPORT_SYMBOL_GPL(nfs_pageio_init_write_mds); void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio) {