From patchwork Tue Mar 11 06:56:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrick Wong X-Patchwork-Id: 328954 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 79C6E2C00BD for ; Tue, 11 Mar 2014 17:56:11 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753600AbaCKG4K (ORCPT ); Tue, 11 Mar 2014 02:56:10 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:21597 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752678AbaCKG4J (ORCPT ); Tue, 11 Mar 2014 02:56:09 -0400 Received: from ucsinet22.oracle.com (ucsinet22.oracle.com [156.151.31.94]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id s2B6u83A002721 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 11 Mar 2014 06:56:08 GMT Received: from userz7022.oracle.com (userz7022.oracle.com [156.151.31.86]) by ucsinet22.oracle.com (8.14.5+Sun/8.14.5) with ESMTP id s2B6u7X8015710 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 11 Mar 2014 06:56:07 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userz7022.oracle.com (8.14.5+Sun/8.14.4) with ESMTP id s2B6u7aN015701; Tue, 11 Mar 2014 06:56:07 GMT Received: from localhost (/67.160.151.179) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 10 Mar 2014 23:56:06 -0700 Subject: [PATCH 20/49] libext2fs: fix parents when modifying extents To: tytso@mit.edu, darrick.wong@oracle.com From: "Darrick J. Wong" Cc: linux-ext4@vger.kernel.org Date: Mon, 10 Mar 2014 23:56:05 -0700 Message-ID: <20140311065605.30585.47791.stgit@birch.djwong.org> In-Reply-To: <20140311065356.30585.47192.stgit@birch.djwong.org> References: <20140311065356.30585.47192.stgit@birch.djwong.org> User-Agent: StGit/0.15 MIME-Version: 1.0 X-Source-IP: ucsinet22.oracle.com [156.151.31.94] Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org In ext2fs_extent_set_bmap() and ext2fs_punch_extent(), fix the parents when altering either end of an extent so that the parent nodes reflect the added mapping. There's a slight complication to using fix_parents: if there are two mappings to an lblk in the tree, the value of handle->path->curr can point to either extent afterwards), which is documented in a comment. Signed-off-by: Darrick J. Wong --- lib/ext2fs/extent.c | 30 ++++++++++++++++++++++++------ lib/ext2fs/punch.c | 14 ++++++++++---- 2 files changed, 34 insertions(+), 10 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c index f27344e..80ce88f 100644 --- a/lib/ext2fs/extent.c +++ b/lib/ext2fs/extent.c @@ -720,7 +720,14 @@ errcode_t ext2fs_extent_goto(ext2_extent_handle_t handle, * and so on. * * Safe to call for any position in node; if not at the first entry, - * will simply return. + * it will simply return. + * + * Note a subtlety of this function -- if there happen to be two extents + * mapping the same lblk and someone calls fix_parents on the second of the two + * extents, the position of the extent handle after the call will be the second + * extent if nothing happened, or the first extent if something did. A caller + * in this situation must use ext2fs_extent_goto() after calling this function. + * Or simply don't map the same lblk with two extents, ever. */ errcode_t ext2fs_extent_fix_parents(ext2_extent_handle_t handle) { @@ -1379,17 +1386,25 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle, &next_extent); if (retval) goto done; - retval = ext2fs_extent_fix_parents(handle); - if (retval) - goto done; } else retval = ext2fs_extent_insert(handle, EXT2_EXTENT_INSERT_AFTER, &newextent); if (retval) goto done; - /* Now pointing at inserted extent; move back to prev */ + retval = ext2fs_extent_fix_parents(handle); + if (retval) + goto done; + /* + * Now pointing at inserted extent; move back to prev. + * + * We cannot use EXT2_EXTENT_PREV to go back; note the + * subtlety in the comment for fix_parents(). + */ + retval = ext2fs_extent_goto(handle, logical); + if (retval) + goto done; retval = ext2fs_extent_get(handle, - EXT2_EXTENT_PREV_LEAF, + EXT2_EXTENT_CURRENT, &extent); if (retval) goto done; @@ -1422,6 +1437,9 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle, 0, &newextent); if (retval) goto done; + retval = ext2fs_extent_fix_parents(handle); + if (retval) + goto done; retval = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT_LEAF, &extent); diff --git a/lib/ext2fs/punch.c b/lib/ext2fs/punch.c index 532c4b8..60cd2a3 100644 --- a/lib/ext2fs/punch.c +++ b/lib/ext2fs/punch.c @@ -344,10 +344,16 @@ static errcode_t ext2fs_punch_extent(ext2_filsys fs, ext2_ino_t ino, EXT2_EXTENT_INSERT_AFTER, &newex); if (retval) goto errout; - /* Now pointing at inserted extent; so go back */ - retval = ext2fs_extent_get(handle, - EXT2_EXTENT_PREV_LEAF, - &newex); + retval = ext2fs_extent_fix_parents(handle); + if (retval) + goto errout; + /* + * Now pointing at inserted extent; so go back. + * + * We cannot use EXT2_EXTENT_PREV to go back; note the + * subtlety in the comment for fix_parents(). + */ + retval = ext2fs_extent_goto(handle, extent.e_lblk); if (retval) goto errout; }