From patchwork Tue Mar 30 18:07:52 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suresh Jayaraman X-Patchwork-Id: 49004 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 36F96B7C67 for ; Wed, 31 Mar 2010 05:08:36 +1100 (EST) Received: from fn.samba.org (localhost [127.0.0.1]) by lists.samba.org (Postfix) with ESMTP id 5B7ABAD22C; Tue, 30 Mar 2010 12:08:36 -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=-4.8 required=3.8 tests=AWL,BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.2.5 X-Original-To: linux-cifs-client@lists.samba.org Delivered-To: linux-cifs-client@lists.samba.org Received: from victor.provo.novell.com (victor.provo.novell.com [137.65.250.26]) by lists.samba.org (Postfix) with ESMTP id 47287AD1BF for ; Tue, 30 Mar 2010 12:08:31 -0600 (MDT) Received: from localhost (prv-ext-foundry1int.gns.novell.com [137.65.251.240]) by victor.provo.novell.com with ESMTP; Tue, 30 Mar 2010 12:08:13 -0600 From: Suresh Jayaraman To: Steve French Date: Tue, 30 Mar 2010 23:37:52 +0530 Message-Id: <1269972472-6055-1-git-send-email-sjayaraman@suse.de> X-Mailer: git-send-email 1.6.4.2 Cc: Jeff Layton , linux-cifs-client@lists.samba.org Subject: [linux-cifs-client] [PATCH] cifs: Fix a kernel BUG with remote OS/2 server 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 While chasing a bug report involving a OS/2 server, I noticed the server sets pSMBr->CountHigh to a incorrect value even in case of normal writes. This leads to 'nbytes' being computed wrongly and triggers a kernel BUG at mm/filemap.c. void iov_iter_advance(struct iov_iter *i, size_t bytes) { BUG_ON(i->count < bytes); <--- BUG here Why the server is setting 'CountHigh' is not clear but only does so after writing 64k bytes. Though this looks like the server bug, the client side crash may not be acceptable. When the write returns successfully and the bytes written as returned by the server is greater than bytes requested by the client, reset it to original bytes requested. Cc: Jeff Layton Signed-off-by: Suresh Jayaraman --- fs/cifs/cifssmb.c | 22 ++++++++++++++++++++++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 7cc7f83..44abf50 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1517,6 +1517,17 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, *nbytes = le16_to_cpu(pSMBr->CountHigh); *nbytes = (*nbytes) << 16; *nbytes += le16_to_cpu(pSMBr->Count); + + /* + * Workaround: Some legacy servers (read OS/2) might incorrectly + * set CountHigh for normal writes resulting in wrong 'nbytes' + * value. So when the write returns successfully and the bytes + * written as returned by the server is greater than bytes + * requested, reset it to original bytes requested. + */ + + if (*nbytes > count) + *nbytes = count; } cifs_buf_release(pSMB); @@ -1605,6 +1616,17 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, *nbytes = le16_to_cpu(pSMBr->CountHigh); *nbytes = (*nbytes) << 16; *nbytes += le16_to_cpu(pSMBr->Count); + + /* + * Workaround: Some legacy servers (read OS/2) might incorrectly + * set CountHigh for normal writes resulting in wrong 'nbytes' + * value. So when the write returns successfully and the bytes + * written as returned by the server is greater than bytes + * requested, reset it to original bytes requested. + */ + + if (*nbytes > count) + *nbytes = count; } /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */