From patchwork Tue Apr 20 20:07:16 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 50570 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.samba.org (fn.samba.org [216.83.154.106]) by ozlabs.org (Postfix) with ESMTP id 3C0B5B7D0E for ; Wed, 21 Apr 2010 06:09:04 +1000 (EST) Received: from fn.samba.org (localhost [127.0.0.1]) by lists.samba.org (Postfix) with ESMTP id 8A8E4AD23A; Tue, 20 Apr 2010 14:09:04 -0600 (MDT) X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on fn.samba.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=3.8 tests=AWL, BAYES_00, NO_MORE_FUNN, SPF_PASS autolearn=no version=3.2.5 X-Original-To: linux-cifs-client@lists.samba.org Delivered-To: linux-cifs-client@lists.samba.org Received: from cdptpa-omtalb.mail.rr.com (cdptpa-omtalb.mail.rr.com [75.180.132.122]) by lists.samba.org (Postfix) with ESMTP id 964FAAD23A for ; Tue, 20 Apr 2010 14:08:57 -0600 (MDT) X-Authority-Analysis: v=1.1 cv=MoTY9QBVwAhcB2GH59FwCsmLFwRIhosZyZPAEaxcLvM= c=1 sm=0 a=Nuxz9T9kjmAA:10 a=ld/erqUjW76FpBUqCqkKeA==:17 a=20KFwNOVAAAA:8 a=28I5HoMXsHGKNdGvwNgA:9 a=rK2mY5qPrVaWoLcGVg0k0ZJN_rMA:4 a=jEp0ucaQiEUA:10 a=qn7HVIrkxt8cNMuX:21 a=8DstTdYzbn4-glPf:21 a=ld/erqUjW76FpBUqCqkKeA==:117 X-Cloudmark-Score: 0 X-Originating-IP: 71.70.153.3 Received: from [71.70.153.3] ([71.70.153.3:45295] helo=mail.poochiereds.net) by cdptpa-oedge04.mail.rr.com (envelope-from ) (ecelerity 2.2.2.39 r()) with ESMTP id 80/55-23257-8D90ECB4; Tue, 20 Apr 2010 20:08:56 +0000 Received: by mail.poochiereds.net (Postfix, from userid 4447) id 9A35458092; Tue, 20 Apr 2010 16:07:20 -0400 (EDT) From: Jeff Layton To: linux-cifs-client@lists.samba.org, linux-fsdevel@vger.kernel.org Date: Tue, 20 Apr 2010 16:07:16 -0400 Message-Id: <1271794039-22787-9-git-send-email-jlayton@redhat.com> X-Mailer: git-send-email 1.6.6.1 In-Reply-To: <1271794039-22787-1-git-send-email-jlayton@redhat.com> References: <1271794039-22787-1-git-send-email-jlayton@redhat.com> Cc: smfrench@gmail.com Subject: [linux-cifs-client] [PATCH 08/11] cifs: fix handling of signing with writepages X-BeenThere: linux-cifs-client@lists.samba.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: The Linux CIFS VFS client List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-cifs-client-bounces@lists.samba.org Errors-To: linux-cifs-client-bounces@lists.samba.org Get a reference to the file early so we can base the decision about signing on the correct tcon. If that doesn't work for some reason, then fall back to generic_writepages. That's just as likely to fail, but it simplifies the error handling. In truth, I'm not sure how that could occur anyway, so maybe a NULL open_file here ought to be a BUG()? Signed-off-by: Jeff Layton --- fs/cifs/file.c | 85 ++++++++++++++++++++++++++----------------------------- 1 files changed, 40 insertions(+), 45 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index b56913a..12495c7 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1398,8 +1398,16 @@ static int cifs_writepages(struct address_space *mapping, int scanned = 0; int xid, long_op; + /* + * BB: Is this meaningful for a non-block-device file system? + * If it is, we should test it again after we do I/O + */ + if (wbc->nonblocking && bdi_write_congested(bdi)) { + wbc->encountered_congestion = 1; + return 0; + } + cifs_sb = CIFS_SB(mapping->host->i_sb); - tcon = cifs_sb_master_tcon(cifs_sb); /* * If wsize is smaller that the page cache size, default to writing @@ -1408,25 +1416,26 @@ static int cifs_writepages(struct address_space *mapping, if (cifs_sb->wsize < PAGE_CACHE_SIZE) return generic_writepages(mapping, wbc); - /* FIXME: not quite right -- we need to determine this once we know - * what tcon we're going to use. - */ - if (tcon->ses->sign && !experimEnabled) - return generic_writepages(mapping, wbc); - iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL); if (iov == NULL) return generic_writepages(mapping, wbc); - /* - * BB: Is this meaningful for a non-block-device file system? - * If it is, we should test it again after we do I/O + * if there's no open file, then this is likely to fail too, + * but it'll at least handle the return. Maybe it should be + * a BUG() instead? */ - if (wbc->nonblocking && bdi_write_congested(bdi)) { - wbc->encountered_congestion = 1; + open_file = find_writable_file(CIFS_I(mapping->host), false); + if (!open_file) { kfree(iov); - return 0; + return generic_writepages(mapping, wbc); + } + + tcon = open_file->tcon; + if (tcon->ses->sign && !experimEnabled) { + kfree(iov); + cifsFileInfo_put(open_file); + return generic_writepages(mapping, wbc); } xid = GetXid(); @@ -1532,39 +1541,24 @@ retry: break; } if (n_iov) { - /* Search for a writable handle every time we call - * CIFSSMBWrite2. We can't rely on the last handle - * we used to still be valid - */ - open_file = find_writable_file(CIFS_I(mapping->host), - false); - if (!open_file) { - cERROR(1, ("No writable handles for inode")); - rc = -EBADF; + long_op = cifs_write_timeout(cifsi, offset); + rc = CIFSSMBWrite2(xid, tcon, open_file->netfid, + bytes_to_write, offset, + &bytes_written, iov, n_iov, + long_op); + cifs_update_eof(cifsi, offset, bytes_written); + + if (rc || bytes_written < bytes_to_write) { + cERROR(1, ("Write2 ret %d, wrote %d", + rc, bytes_written)); + /* BB what if continued retry is + requested via mount flags? */ + if (rc == -ENOSPC) + set_bit(AS_ENOSPC, &mapping->flags); + else + set_bit(AS_EIO, &mapping->flags); } else { - tcon = open_file->tcon; - long_op = cifs_write_timeout(cifsi, offset); - rc = CIFSSMBWrite2(xid, tcon, - open_file->netfid, - bytes_to_write, offset, - &bytes_written, iov, n_iov, - long_op); - cifsFileInfo_put(open_file); - cifs_update_eof(cifsi, offset, bytes_written); - - if (rc || bytes_written < bytes_to_write) { - cERROR(1, ("Write2 ret %d, wrote %d", - rc, bytes_written)); - /* BB what if continued retry is - requested via mount flags? */ - if (rc == -ENOSPC) - set_bit(AS_ENOSPC, &mapping->flags); - else - set_bit(AS_EIO, &mapping->flags); - } else { - cifs_stats_bytes_written(tcon, - bytes_written); - } + cifs_stats_bytes_written(tcon, bytes_written); } for (i = 0; i < n_iov; i++) { page = pvec.pages[first + i]; @@ -1601,6 +1595,7 @@ retry: if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) mapping->writeback_index = index; + cifsFileInfo_put(open_file); FreeXid(xid); kfree(iov); return rc;