From patchwork Fri Apr 9 17:44:06 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Surbhi Palande X-Patchwork-Id: 49857 X-Patchwork-Delegate: apw@canonical.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 3C8B5B7C8E for ; Sat, 10 Apr 2010 03:44:16 +1000 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.69) (envelope-from ) id 1O0IFU-0001Ph-H0; Fri, 09 Apr 2010 18:44:08 +0100 Received: from adelie.canonical.com ([91.189.90.139]) by chlorine.canonical.com with esmtp (Exim 4.69) (envelope-from ) id 1O0IFT-0001PX-EK for kernel-team@lists.canonical.com; Fri, 09 Apr 2010 18:44:07 +0100 Received: from hutte.canonical.com ([91.189.90.181]) by adelie.canonical.com with esmtp (Exim 4.69 #1 (Debian)) id 1O0IFT-0002Ag-Cg for ; Fri, 09 Apr 2010 18:44:07 +0100 Received: from a88-112-254-38.elisa-laajakaista.fi ([88.112.254.38] helo=canonical.com) by hutte.canonical.com with esmtpsa (TLS-1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.69) (envelope-from ) id 1O0IFT-0002CN-2F for kernel-team@lists.canonical.com; Fri, 09 Apr 2010 18:44:07 +0100 From: Surbhi Palande To: kernel-team@lists.canonical.com Subject: [PATCH][UBUNTU] sync before umount to reduce time taken by ext4 umount Date: Fri, 9 Apr 2010 20:44:06 +0300 Message-Id: <1270835046-14280-1-git-send-email-surbhi.palande@canonical.com> X-Mailer: git-send-email 1.6.3.3 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.9 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com This patch is a tempory fix for the bug 543617 on launchpad where users have reported huge amount of time for an ext4 unmount. When sync is called prior to umount, the time taken by umount is reduced to an acceptable value. The reason due to which ext4 umount takes a long time is: * a journal transaction is involved with every inode associated with a flush at umount time. A wait is performed till this journal transaction is flushed to the disk. In the example mentioned by Kees Cook on LP, there are 65K inodes and their associated journal data blocks which are flushed to the disk and 65K barriers called with a single unmount call. Due to the large dirty data flush interval time, the journal flush is not happening before umount is called in this particular case. The following patch puts the sync() related code before umount, so that users get an acceptable wait period whenever umount is called. Do consider merging this for Lucid, till a real fix is available. From bc7dddbc909a17c63b13ba4c62d420256bd11758 Mon Sep 17 00:00:00 2001 From: Surbhi Palande Date: Wed, 7 Apr 2010 15:03:11 +0300 Subject: [PATCH] sync before umount to reduce time taken by ext4 umount This is a temporary fix to reduce the time it takes an unmount, when no prior sync is called. The appropriate solution would be to fix the underlying ext4 journal, sync and barrier calls. BugLink: http://launchpad.net/bugs/543617 Signed-off-by: Surbhi Palande Acked-by: Stefan Bader Acked-by: Andy Whitcroft --- fs/namespace.c | 7 +++++++ fs/sync.c | 2 +- include/linux/fs.h | 1 + 3 files changed, 9 insertions(+), 1 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index a2cadcf..a648d7f 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -33,6 +33,7 @@ #include #include "pnode.h" #include "internal.h" +#include #define HASH_SHIFT ilog2(PAGE_SIZE / sizeof(struct list_head)) #define HASH_SIZE (1UL << HASH_SHIFT) @@ -1134,6 +1135,12 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags) if (!capable(CAP_SYS_ADMIN)) goto dput_and_out; + /* Temporary solution to fix long umount periods till + * we find the real fix + */ + sync_filesystems(0); + sync_filesystems(1); + retval = do_umount(path.mnt, flags); dput_and_out: /* we mustn't call path_put() as that would clear mnt_expiry_mark */ diff --git a/fs/sync.c b/fs/sync.c index d104591..09e3734 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -89,7 +89,7 @@ EXPORT_SYMBOL_GPL(sync_filesystem); * flags again, which will cause process A to resync everything. Fix that with * a local mutex. */ -static void sync_filesystems(int wait) +void sync_filesystems(int wait) { struct super_block *sb; static DEFINE_MUTEX(mutex); diff --git a/include/linux/fs.h b/include/linux/fs.h index 692a3ee..1a51c61 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1973,6 +1973,7 @@ static inline int thaw_bdev(struct block_device *bdev, struct super_block *sb) return 0; } #endif +extern void sync_filesystems(int wait); extern int sync_filesystem(struct super_block *); extern const struct file_operations def_blk_fops; extern const struct file_operations def_chr_fops;