From patchwork Fri Mar 19 05:25:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 1455577 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=HusKyZqc; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4F1snR01K1z9sS8 for ; Fri, 19 Mar 2021 16:26:18 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233743AbhCSFZl (ORCPT ); Fri, 19 Mar 2021 01:25:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51012 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233730AbhCSFZX (ORCPT ); Fri, 19 Mar 2021 01:25:23 -0400 Received: from mail-lj1-x235.google.com (mail-lj1-x235.google.com [IPv6:2a00:1450:4864:20::235]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 94A97C06174A for ; Thu, 18 Mar 2021 22:25:22 -0700 (PDT) Received: by mail-lj1-x235.google.com with SMTP id r20so10457204ljk.4 for ; Thu, 18 Mar 2021 22:25:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=Oshase93bF1Ivofc+egjrvcsBJ7hy/99gSrLVUqUqp0=; b=HusKyZqcGycB665rHzGUbAmkTMD+Ezv8ks5tYsdbOocglQ6mISJSq+igiPaaiqONaM SB+AKrxJtQWFqHk9LZmxnrGhzRoRZ8iIFouxKCrGeK5vdc5Uo5wY20N6cK3mtWPPobSZ jz8Pt5t/t11aq61mPsnpUlTx4vmJguXmh4H9SYwwUfGV3UrvZgdBEWnS0Rsymsx23LlZ 4Jt+RlsikquHHWgWwevL022GHF2GA8WK+CT3MWPcsdZGCaTpFkLZ3Bd6GMWZnkoRYwHj 0KH0JYo9gVMf4FHzXqhGvaPHI/NEYOYXgcDDuqWjNs3PU62FAWXOmG1L7brUxTQWc9dY v/Bw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=Oshase93bF1Ivofc+egjrvcsBJ7hy/99gSrLVUqUqp0=; b=SgNp/Aiqoe/x1/W1GpQYxnLVCBWRXAHpUNLE9zemI638/kvDetbMN9dRTnBs9dAsk4 JLirg3v+DRPKJfu5yUYnQOJxxmM8690gGFNzgX2doqFuEMwKJnEeWbLFcr3Cl3g/Ah+r K5xOOkBiVvx8uCKNnWHLY0kYuyDkeIpGfSqhPyr2qHIQUvKaexORsAsZNF3wa8Wb7HfU /FjbQD4yZNaXwthbRscDOb0tCpInS5mMybM2f7mY4KbKSD/ZYDQrO8iPdOV1vlBt0NTA OilNcN5YQqgR3YSuIakaSc9fqkrnYJvyy3kbp5AlbjdiQ/KiMVErR1cqeVDdGLBtuNos yIww== X-Gm-Message-State: AOAM5334bUGgsEZfnaYD2tMWOYqspFeCmdBX1paO31isZn1oBU3QZLRH fQ7qMY7vNoLNPsAvM4U42i+ohBt//EL0cKBlQaxCN41HJ8furQ== X-Google-Smtp-Source: ABdhPJxgl1i3lnu8G3kTFVriJVvQn4DIzu/XY6YX+4ItN+CO13nMjZfQF6Exda6sZ/HHyTdKWWPllDNnyf+IXAIOQOE= X-Received: by 2002:a05:651c:339:: with SMTP id b25mr7438347ljp.406.1616131519323; Thu, 18 Mar 2021 22:25:19 -0700 (PDT) MIME-Version: 1.0 From: Steve French Date: Fri, 19 Mar 2021 00:25:08 -0500 Message-ID: Subject: [PATCH] cifs: fix allocation size on newly created files To: CIFS Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org Applications that create and extend and write to a file do not expect to see 0 allocation size. When file is extended, set its allocation size to a plausible value until we have a chance to query the server for it. When the file is cached this will prevent showing an impossible number of allocated blocks (like 0). This fixes e.g. xfstests 614 which does 1) create a file and set its size to 64K 2) mmap write 64K to the file 3) stat -c %b for the file (to query the number of allocated blocks) It was failing because we returned 0 blocks. Even though we would return the correct cached file size, we returned an impossible allocation size. Signed-off-by: Steve French CC: Reviewed-by: Aurelien Aptel --- fs/cifs/inode.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) inode->i_mapping && inode->i_mapping->nrpages != 0) { rc = filemap_fdatawait(inode->i_mapping); @@ -2585,6 +2585,14 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, if (rc == 0) { cifsInode->server_eof = attrs->ia_size; cifs_setsize(inode, attrs->ia_size); + /* + * i_blocks is not related to (i_size / i_blksize), + * but instead 512 byte (2**9) size is required for + * calculating num blocks. Until we can query the + * server for actual allocation size, this is best estimate + * we have for the blocks allocated for this file + */ + inode->i_blocks = (512 - 1 + attrs->ia_size) >> 9; /* * The man page of truncate says if the size changed, @@ -2912,7 +2920,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) sys_utimes in which case we ought to fail the call back to the user when the server rejects the call */ if ((rc) && (attrs->ia_valid & - (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE))) + (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE))) rc = 0; } From 2ea7f44e54c7d3c4e8236e82950efb6aedda2486 Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 19 Mar 2021 00:05:48 -0500 Subject: [PATCH] cifs: fix allocation size on newly created files Applications that create and extend and write to a file do not expect to see 0 allocation size. When file is extended, set its allocation size to a plausible value until we have a chance to query the server for it. When the file is cached this will prevent showing an impossible number of allocated blocks (like 0). This fixes e.g. xfstests 614 which does 1) create a file and set its size to 64K 2) mmap write 64K to the file 3) stat -c %b for the file (to query the number of allocated blocks) It was failing because we returned 0 blocks. Even though we would return the correct cached file size, we returned an impossible allocation size. Signed-off-by: Steve French CC: --- fs/cifs/inode.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 7c61bc9573c0..17a2c87b811c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -2395,7 +2395,7 @@ int cifs_getattr(struct user_namespace *mnt_userns, const struct path *path, * We need to be sure that all dirty pages are written and the server * has actual ctime, mtime and file length. */ - if ((request_mask & (STATX_CTIME | STATX_MTIME | STATX_SIZE)) && + if ((request_mask & (STATX_CTIME | STATX_MTIME | STATX_SIZE | STATX_BLOCKS)) && !CIFS_CACHE_READ(CIFS_I(inode)) && inode->i_mapping && inode->i_mapping->nrpages != 0) { rc = filemap_fdatawait(inode->i_mapping); @@ -2585,6 +2585,14 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, if (rc == 0) { cifsInode->server_eof = attrs->ia_size; cifs_setsize(inode, attrs->ia_size); + /* + * i_blocks is not related to (i_size / i_blksize), + * but instead 512 byte (2**9) size is required for + * calculating num blocks. Until we can query the + * server for actual allocation size, this is best estimate + * we have for the blocks allocated for this file + */ + inode->i_blocks = (512 - 1 + attrs->ia_size) >> 9; /* * The man page of truncate says if the size changed, @@ -2912,7 +2920,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) sys_utimes in which case we ought to fail the call back to the user when the server rejects the call */ if ((rc) && (attrs->ia_valid & - (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE))) + (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE))) rc = 0; } -- 2.27.0