From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx2.suse.de ([195.135.220.15]:51576 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932314AbcFCPn1 (ORCPT ); Fri, 3 Jun 2016 11:43:27 -0400 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id D918EAC3D for ; Fri, 3 Jun 2016 15:43:25 +0000 (UTC) From: David Sterba To: stable@vger.kernel.org Subject: [PATCH 18/21] Btrfs: fix empty symlink after creating symlink and fsync parent dir Date: Fri, 3 Jun 2016 17:42:46 +0200 Message-Id: <1464968566-6997-1-git-send-email-dsterba@suse.com> In-Reply-To: <20160603154006.GP29147@suse.cz> References: <20160603154006.GP29147@suse.cz> Sender: stable-owner@vger.kernel.org List-ID: From: Filipe Manana commit 3f9749f6e9edcf8ec569fb542efc3be35e06e84a upstream. If we create a symlink, fsync its parent directory, crash/power fail and mount the filesystem, we end up with an empty symlink, which not only is useless it's also not allowed in linux (the man page symlink(2) is well explicit about that). So we just need to make sure to fully log an inode if it's a symlink, to ensure its inline extent gets logged, ensuring the same behaviour as ext3, ext4, xfs, reiserfs, f2fs, nilfs2, etc. Example reproducer: $ mkfs.btrfs -f /dev/sdb $ mount /dev/sdb /mnt $ mkdir /mnt/testdir $ sync $ ln -s /mnt/foo /mnt/testdir/bar $ xfs_io -c fsync /mnt/testdir $ mount /dev/sdb /mnt $ readlink /mnt/testdir/bar A test case for fstests follows soon. Signed-off-by: Filipe Manana --- fs/btrfs/tree-log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 23df70e7f884..a2cd42107945 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -5157,7 +5157,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, } ctx->log_new_dentries = false; - if (type == BTRFS_FT_DIR) + if (type == BTRFS_FT_DIR || type == BTRFS_FT_SYMLINK) log_mode = LOG_INODE_ALL; btrfs_release_path(path); ret = btrfs_log_inode(trans, root, di_inode, -- 2.7.1