From patchwork Mon Dec 13 02:51:28 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Nicol X-Patchwork-Id: 404112 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oBD2x1vu001539 for ; Mon, 13 Dec 2010 02:59:01 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756540Ab0LMC6t (ORCPT ); Sun, 12 Dec 2010 21:58:49 -0500 Received: from mail-iy0-f174.google.com ([209.85.210.174]:54778 "EHLO mail-iy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754844Ab0LMC6t (ORCPT ); Sun, 12 Dec 2010 21:58:49 -0500 X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Mon, 13 Dec 2010 02:59:01 +0000 (UTC) X-Greylist: delayed 420 seconds by postgrey-1.27 at vger.kernel.org; Sun, 12 Dec 2010 21:58:49 EST Received: by iyi12 with SMTP id 12so672637iyi.19 for ; Sun, 12 Dec 2010 18:58:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:mime-version:received:from:date :message-id:subject:to:content-type; bh=dEUqUqzYKC+tze4WBy2ZazGIysZ9IA4A47RBkwdKCPA=; b=Y0ZYxIZksNXHIm8sHYWtRrhZcqqTf/iQ/ddxV8ACHknsfROtR/eTlkX4tJJfCMqQn/ 3OD9g9MlvadDYGhmuz34KIN9R1CL2C+X0MJ+BMYNAaIRyzGKpLGeFDiGjAqxyBxW35f/ IVMOi1GGHCDSIQXLhYhoGA8T3OsRjF6hr0Xlw= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:from:date:message-id:subject:to:content-type; b=SLXjlPUMfPFPQIOA3udVEK5+vZqz+pSJzy2x1OHhQz8JQ+r2Il3AqAiehRY1/A82qv nI6GiD0VSf3SUh2R8jzjheMiuNRWZZsSfWUGakAhXAX7FygbzOfGwFZXKbSQqVmMI/WE qeJBAwBcFmXxpyGL4lD06m0omUM4iFpbJzuhM= Received: by 10.42.213.134 with SMTP id gw6mr2319519icb.476.1292208708877; Sun, 12 Dec 2010 18:51:48 -0800 (PST) MIME-Version: 1.0 Received: by 10.231.206.148 with HTTP; Sun, 12 Dec 2010 18:51:28 -0800 (PST) From: David Nicol Date: Sun, 12 Dec 2010 20:51:28 -0600 Message-ID: Subject: PATCH: btrfs ioctl for waiting for kernel cleaner thread task completions kernel code To: BTRFS MAILING LIST Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 29c2009..114a4af 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -895,6 +895,7 @@ struct btrfs_fs_info { struct list_head trans_list; struct list_head hashers; struct list_head dead_roots; + wait_queue_head_t cleaner_notification_registration; struct list_head caching_block_groups; spinlock_t delayed_iput_lock; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 34f7c37..1ccc1e7 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1450,7 +1450,9 @@ static int cleaner_kthread(void *arg) if (!(root->fs_info->sb->s_flags & MS_RDONLY) && mutex_trylock(&root->fs_info->cleaner_mutex)) { btrfs_run_delayed_iputs(root); + wake_up_all(&root->fs_info->cleaner_notification_registration); btrfs_clean_old_snapshots(root); + wake_up_all(&root->fs_info->cleaner_notification_registration); mutex_unlock(&root->fs_info->cleaner_mutex); } @@ -1581,6 +1583,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC); INIT_LIST_HEAD(&fs_info->trans_list); INIT_LIST_HEAD(&fs_info->dead_roots); + init_waitqueue_head(&fs_info->cleaner_notification_registration); INIT_LIST_HEAD(&fs_info->delayed_iputs); INIT_LIST_HEAD(&fs_info->hashers); INIT_LIST_HEAD(&fs_info->delalloc_inodes); @@ -2393,7 +2396,9 @@ int btrfs_commit_super(struct btrfs_root *root) mutex_lock(&root->fs_info->cleaner_mutex); btrfs_run_delayed_iputs(root); + wake_up_all(&root->fs_info->cleaner_notification_registration); btrfs_clean_old_snapshots(root); + wake_up_all(&root->fs_info->cleaner_notification_registration); mutex_unlock(&root->fs_info->cleaner_mutex); /* wait until ongoing cleanup work done */ diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9254b3d..cc739ad 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1212,6 +1212,65 @@ static noinline int btrfs_ioctl_ino_lookup(struct file *file, return ret; } +static int btrfs_ioctl_cleaner_wait(struct btrfs_root *root, void __user *arg) +{ + struct btrfs_ioctl_cleaner_wait_args *bicwa; + long remainingjiffies; + int err; + + bicwa = memdup_user(arg, sizeof(*bicwa)); + if (IS_ERR(bicwa)) + return PTR_ERR(bicwa); + + err = -EINVAL; + + /* flag bit 0x04 means, error on unknown flag. + the highest possible valid flag value at this rev is 0x07. */ + if (bicwa->flags & 4 == 4 && bicwa->flags > 7 ){ + kfree(bicwa); + return err; + }; + +#define BICW_TEST ( \ + /* flag bit 0x01: suppress wait for dead_roots */ \ + (bicwa->flags & 1 == 1 || list_empty(&root->fs_info->dead_roots)) \ + \ + /* flag bit 0x02: wait for delayed iputs */ \ + && (bicwa->flags & 2 == 0 || list_empty(&root->fs_info->delayed_iputs)) \ + \ + /* 0x04 is consumed earlier */ \ + /* add the next one at 0x08 */ \ +) + + if (bicwa->ms > 0) + { + unsigned long millisecs = bicwa->ms; + remainingjiffies = wait_event_interruptible_timeout( + root->fs_info->cleaner_notification_registration, + BICW_TEST, msecs_to_jiffies(millisecs) + ); + if (remainingjiffies > 0) + err = 0; + else if (remainingjiffies < 0 ) + err = -EAGAIN; + else + err = -ETIME; + } + else + { + err = wait_event_interruptible( + root->fs_info->cleaner_notification_registration, + BICW_TEST + ); + }; + + kfree(bicwa); + return err; + +#undef BICWATEST +} + + static noinline int btrfs_ioctl_snap_destroy(struct file *file, void __user *arg) { @@ -2003,6 +2062,8 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_snap_create(file, argp, 1); case BTRFS_IOC_SNAP_DESTROY: return btrfs_ioctl_snap_destroy(file, argp); + case BTRFS_IOC_CLEANER_WAIT: + return btrfs_ioctl_cleaner_wait(root, argp); case BTRFS_IOC_DEFAULT_SUBVOL: return btrfs_ioctl_default_subvol(file, argp); case BTRFS_IOC_DEFRAG: diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 424694a..9af8530 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -138,6 +138,11 @@ struct btrfs_ioctl_space_args { struct btrfs_ioctl_space_info spaces[0]; }; +struct btrfs_ioctl_cleaner_wait_args{ + __u32 ms; + __u32 flags; +}; + #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \ struct btrfs_ioctl_vol_args) #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \ @@ -178,4 +183,6 @@ struct btrfs_ioctl_space_args { #define BTRFS_IOC_DEFAULT_SUBVOL _IOW(BTRFS_IOCTL_MAGIC, 19, u64) #define BTRFS_IOC_SPACE_INFO _IOWR(BTRFS_IOCTL_MAGIC, 20, \ struct btrfs_ioctl_space_args) +#define BTRFS_IOC_CLEANER_WAIT _IOW(BTRFS_IOCTL_MAGIC, 21, \ + struct btrfs_ioctl_cleaner_wait_args) #endif