From mboxrd@z Thu Jan 1 00:00:00 1970 From: Christoph Hellwig Subject: [PATCH 5/11] hfsplus: make sure sync writes out all metadata Date: Wed, 17 Nov 2010 23:22:25 +0100 Message-ID: <20101117222225.GF21700@lst.de> References: <20101117222117.GA21700@lst.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii To: linux-fsdevel@vger.kernel.org Return-path: Received: from verein.lst.de ([213.95.11.210]:38590 "EHLO verein.lst.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933707Ab0KQWW1 (ORCPT ); Wed, 17 Nov 2010 17:22:27 -0500 Received: from verein.lst.de (localhost [127.0.0.1]) by verein.lst.de (8.12.3/8.12.3/Debian-7.1) with ESMTP id oAHMMP88021786 (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO) for ; Wed, 17 Nov 2010 23:22:25 +0100 Received: (from hch@localhost) by verein.lst.de (8.12.3/8.12.3/Debian-7.2) id oAHMMPJm021785 for linux-fsdevel@vger.kernel.org; Wed, 17 Nov 2010 23:22:25 +0100 Content-Disposition: inline In-Reply-To: <20101117222117.GA21700@lst.de> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: hfsplus stores all metadata except for the volume headers in special inodes. While these are marked hashed and periodically written out by the flusher threads, we can't rely on that for sync. For the case of a data integrity sync the VM has life-lock avoidance code that avoids writing inodes again that are redirtied during the sync, which is something that can happen easily for hfsplus. So make sure we explicitly write out the metadata inodes at the beginning of hfsplus_sync_fs. Signed-off-by: Christoph Hellwig Index: linux-2.6/fs/hfsplus/super.c =================================================================== --- linux-2.6.orig/fs/hfsplus/super.c 2010-11-17 22:46:55.000000000 +0100 +++ linux-2.6/fs/hfsplus/super.c 2010-11-17 22:47:57.762004821 +0100 @@ -164,6 +164,22 @@ int hfsplus_sync_fs(struct super_block * sb->s_dirt = 0; + /* + * Explicitly write out the special metadata inodes. + * + * While these special inodes are marked as hashed and written + * out peridocically by the flusher threads we redirty them + * during writeout of normal inodes, and thus the life lock + * prevents us from getting the latest state to disk. + */ + error = filemap_write_and_wait(sbi->cat_tree->inode->i_mapping); + error2 = filemap_write_and_wait(sbi->ext_tree->inode->i_mapping); + if (!error) + error = error2; + error2 = filemap_write_and_wait(sbi->alloc_file->i_mapping); + if (!error) + error = error2; + mutex_lock(&sbi->vh_mutex); mutex_lock(&sbi->alloc_mutex); vhdr->free_blocks = cpu_to_be32(sbi->free_blocks); @@ -176,9 +192,11 @@ int hfsplus_sync_fs(struct super_block * write_backup = 1; } - error = hfsplus_submit_bio(sb->s_bdev, + error2 = hfsplus_submit_bio(sb->s_bdev, sbi->part_start + HFSPLUS_VOLHEAD_SECTOR, sbi->s_vhdr, WRITE_SYNC); + if (!error) + error = error2; if (!write_backup) goto out;