From patchwork Sun Dec 9 06:21:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hou Tao X-Patchwork-Id: 1009912 X-Patchwork-Delegate: richard@nod.at Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=huawei.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="U1C7bMfH"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43CGJ01x8cz9s3C for ; Sun, 9 Dec 2018 17:19:12 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=c3bxK+F3PRMS01YGCrz2zbjFO4cHXnzOWCBu+WQHCdU=; b=U1C7bMfHLcdBme L+7/0AJFvOnKUgCgMUD95K9Uih9BLpbLENXhuM0pFPI1q2/xhDme8ZlDthBm6PHWJuJOOehbncSaN rnc9r+jFLPVC14Ml/FYUlD0ABbcVoSuQ3gybEw4a6ygaHAw0xvAm4vjoj5oqjFkhY8JF5RWThkNJV i4kvMl/whyMsHyl/ZCkV0gc2pSh+1wnto/Lyv/6Y9RTNawRNWHvlZztxpMF213lw61quf8vsLnehG Dg372xfgYPBY3RnDg3HANobADXG0QGu0inklmFR4RSumHXy1UR4H42JSmsfigmoXn0bl2QqNhlcYU RpG6ZyQbrRhMc9jJRW1Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVsQh-00036j-25; Sun, 09 Dec 2018 06:19:03 +0000 Received: from szxga05-in.huawei.com ([45.249.212.191] helo=huawei.com) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gVsQO-00035f-A4 for linux-mtd@lists.infradead.org; Sun, 09 Dec 2018 06:18:46 +0000 Received: from DGGEMS413-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 55313EA0C9F0B; Sun, 9 Dec 2018 14:18:25 +0800 (CST) Received: from huawei.com (10.90.53.225) by DGGEMS413-HUB.china.huawei.com (10.3.19.213) with Microsoft SMTP Server id 14.3.408.0; Sun, 9 Dec 2018 14:18:24 +0800 From: Hou Tao To: , Subject: [PATCH] jffs2: make the overwritten xattr invisible after remount Date: Sun, 9 Dec 2018 14:21:33 +0800 Message-ID: <20181209062133.106781-1-houtao1@huawei.com> X-Mailer: git-send-email 2.16.2.dirty MIME-Version: 1.0 X-Originating-IP: [10.90.53.225] X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181208_221844_510196_FFB736B2 X-CRM114-Status: GOOD ( 12.41 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [45.249.212.191 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 SPF_HELO_PASS SPF: HELO matches SPF record X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: richard.weinberger@gmail.com, boris.brezillon@bootlin.com, linux-kernel@vger.kernel.org Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org For xattr modification, we do not write a new jffs2_raw_xref with delete marker into flash, so if a xattr is modified then removed, and the old xref & xdatum are not erased by GC, after reboot or remount, the new xattr xref will be dead but the old xattr xref will be alive, and we will get the overwritten xattr instead of non-existent error when reading the removed xattr. Fix it by writing the deletion mark for xattr overwrite. Fixes: 8a13695cbe4e ("[JFFS2][XATTR] rid unnecessary writing of delete marker.") Signed-off-by: Hou Tao --- fs/jffs2/xattr.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index da3e18503c65..b2d6072f34af 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c @@ -573,6 +573,15 @@ static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct return ref; /* success */ } +static void move_xattr_ref_to_dead_list(struct jffs2_sb_info *c, + struct jffs2_xattr_ref *ref) +{ + spin_lock(&c->erase_completion_lock); + ref->next = c->xref_dead_list; + c->xref_dead_list = ref; + spin_unlock(&c->erase_completion_lock); +} + static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) { /* must be called under down_write(xattr_sem) */ @@ -582,10 +591,7 @@ static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *re ref->xseqno |= XREF_DELETE_MARKER; ref->ino = ref->ic->ino; ref->xid = ref->xd->xid; - spin_lock(&c->erase_completion_lock); - ref->next = c->xref_dead_list; - c->xref_dead_list = ref; - spin_unlock(&c->erase_completion_lock); + move_xattr_ref_to_dead_list(c, ref); dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n", ref->ino, ref->xid, ref->xseqno); @@ -1090,6 +1096,40 @@ int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname, return rc; } +static void do_jffs2_delete_xattr_ref(struct jffs2_sb_info *c, + struct jffs2_xattr_ref *ref) +{ + uint32_t request, length; + int err; + struct jffs2_xattr_datum *xd; + + request = PAD(sizeof(struct jffs2_raw_xref)); + err = jffs2_reserve_space(c, request, &length, + ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE); + down_write(&c->xattr_sem); + if (err) { + JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", + err, request); + delete_xattr_ref(c, ref); + up_write(&c->xattr_sem); + return; + } + + xd = ref->xd; + ref->ino = ref->ic->ino; + ref->xid = xd->xid; + ref->xseqno |= XREF_DELETE_MARKER; + save_xattr_ref(c, ref); + + move_xattr_ref_to_dead_list(c, ref); + dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n", + ref->ino, ref->xid, ref->xseqno); + unrefer_xattr_datum(c, xd); + + up_write(&c->xattr_sem); + jffs2_complete_reservation(c); +} + int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, const char *buffer, size_t size, int flags) { @@ -1097,7 +1137,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); struct jffs2_inode_cache *ic = f->inocache; struct jffs2_xattr_datum *xd; - struct jffs2_xattr_ref *ref, *newref, **pref; + struct jffs2_xattr_ref *ref, *newref, *oldref, **pref; uint32_t length, request; int rc; @@ -1113,6 +1153,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, return rc; } + oldref = NULL; /* Find existing xattr */ down_write(&c->xattr_sem); retry: @@ -1196,11 +1237,13 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname, rc = PTR_ERR(newref); unrefer_xattr_datum(c, xd); } else if (ref) { - delete_xattr_ref(c, ref); + oldref = ref; } out: up_write(&c->xattr_sem); jffs2_complete_reservation(c); + if (oldref) + do_jffs2_delete_xattr_ref(c, oldref); return rc; }