From patchwork Wed Aug 31 22:34:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 9307969 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A552B60487 for ; Wed, 31 Aug 2016 22:35:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 99771290CD for ; Wed, 31 Aug 2016 22:35:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8D6C329108; Wed, 31 Aug 2016 22:35:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from oss.sgi.com (oss.sgi.com [192.48.182.195]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 76F9D290CD for ; Wed, 31 Aug 2016 22:35:54 +0000 (UTC) Received: from oss.sgi.com (localhost [IPv6:::1]) by oss.sgi.com (Postfix) with ESMTP id B24627CA1; Wed, 31 Aug 2016 17:35:52 -0500 (CDT) X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A017D7CA0 for ; Wed, 31 Aug 2016 17:35:50 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6D7D7304032 for ; Wed, 31 Aug 2016 15:35:47 -0700 (PDT) X-ASG-Debug-ID: 1472682944-0bf57b53144abb90001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id iXyeV875tVuQ52HO for ; Wed, 31 Aug 2016 15:35:44 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Effective-Source-IP: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2C0GACAWsdXEAI1LHldg1ABAQEBAR6BU4ZynBABAQEBAQEGkwuCD4lqOhMBAgEBAQEBAQEGAQEBAQEBAQE3QIUPLyMYGBhSAwctiEW+XoVniSVvDYUQBZlQjzKPUwKQQSABgisBC4I9KjSEPoIuAQEB Received: from ppp121-44-53-2.lns20.syd4.internode.on.net (HELO dastard) ([121.44.53.2]) by ipmail05.adl6.internode.on.net with ESMTP; 01 Sep 2016 08:04:56 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1bfE5u-0007ik-UR; Thu, 01 Sep 2016 08:34:54 +1000 Received: from dave by disappointment with local (Exim 4.87) (envelope-from ) id 1bfE5j-0004KB-Mg; Thu, 01 Sep 2016 08:34:43 +1000 From: Dave Chinner To: linux-xfs@vger.kernel.org Subject: [PATCH] db: write via array indexing doesn't work Date: Thu, 1 Sep 2016 08:34:43 +1000 X-ASG-Orig-Subj: [PATCH] db: write via array indexing doesn't work Message-Id: <1472682883-16585-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.8.0.rc3 X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1472682944 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Barracuda-Scan-Msg-Size: 2358 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.32509 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Cc: xfs@oss.sgi.com X-BeenThere: xfs@oss.sgi.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: XFS Filesystem from SGI List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xfs-bounces@oss.sgi.com Sender: xfs-bounces@oss.sgi.com X-Virus-Scanned: ClamAV using ClamSMTP From: Dave Chinner This command to write a specific AGFL index: # xfs_db -x -c "agfl 0" -c "write -d bno[32] 78" /dev/ram0 doesn't write to array index 32 - it incorrectly writes to /somewhere/ in the entire array range. The issue here is that the write_struct() code assumes that the object it is printing always a structure member and any array indexes will be exposed as children of the parent type. This works just fine for structures with internal arrays, but when the type being decoded is an array, we get a direct reference to the offset to be written in the parent object. Hence we need to take into account the array index returned by the parent object parsing when calculating the size of the region to be modified rather than using fcount() as that results in the size always being set to the size of the entire array and the modification being written to the wrong place. Signed-off-by: Dave Chinner --- db/write.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/db/write.c b/db/write.c index 82a0c74..5c83874 100644 --- a/db/write.c +++ b/db/write.c @@ -701,8 +701,24 @@ write_struct( sfl = sfl->child; } + /* + * For structures, fsize * fcount tells us the size of the region we are + * modifying, which is usually a single structure member and is pointed + * to by the last child in the list. + * + * However, if the base structure is an array and we have a direct index + * into the array (e.g. write bno[5]) then we are returned a single + * flist object with the offset pointing directly at the location we + * need to modify. The length of the object we are modifying is then + * determined by the size of the individual array entry (fsize) and the + * indexes defined in the object, not the overall size of the array + * (which is what fcount returns). + */ bit_length = fsize(sfl->fld, iocur_top->data, parentoffset, 0); - bit_length *= fcount(sfl->fld, iocur_top->data, parentoffset); + if (sfl->fld->flags & FLD_ARRAY) + bit_length *= sfl->high - sfl->low + 1; + else + bit_length *= fcount(sfl->fld, iocur_top->data, parentoffset); /* convert this to a generic conversion routine */ /* should be able to handle str, num, or even labels */