This is once again the whole patch starting from 075587c96c2f39e227847d13ca0ef305b13cd7d3 (Chris Mason, April 06 2010) The difference between this one and yesterday''s is: 1: the file descriptor leak is corrected 2: the ioctl21 flags field is explicitly zeroed, for forwards compatibility. The intended semantics of the flags field is, zeroes mean, wait for everthing we know how to wait for using ioctl#21 -- a 1 will mean, ignore completion of that set of deferred tasks, when there are other deferred tasks ioctl#21 can be used to wait for. Also a 1 in a position associated with a reprioritization directive would mean to do something, and a zero would mean, do nothing so all-zeroes is supposed to mean, into a possible future where ioctl#21 does more, wait for completion of everything we know about, and don''t do any other optional anything. ---------- Forwarded message ---------- Date: Thu, Oct 14, 2010 at 9:32 AM Subject: zeroing ioctl21 flags progs-side To: davidnicol@gmail.com diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index e9bf864..a350b75 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..6a35257 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1451,6 +1451,7 @@ static int cleaner_kthread(void *arg) mutex_trylock(&root->fs_info->cleaner_mutex)) { btrfs_run_delayed_iputs(root); btrfs_clean_old_snapshots(root); + wake_up_all(&root->fs_info->cleaner_notification_registration); mutex_unlock(&root->fs_info->cleaner_mutex); } @@ -1581,6 +1582,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); diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9254b3d..ffc86a8 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); + + /* the bicwa flags field is intended to hold bits + that will be set to 1 to disable a cleanliness + test. Currently there is only one test, but + when there are more (or other things, like + reprioritizing the cleaner thread because something + is waiting on it, although that happens already + because the waiting thing has yielded, so that + isn''t really a hot to-do item) this function + will of course get modified to implement them. */ + + if (bicwa->flags > 0x01) /* the highest flag we know about */ + { + err = -EINVAL; + goto done_with_bicwa; + } + + if (bicwa->ms > 0) + { + remainingjiffies = wait_event_interruptible_timeout( + root->fs_info->cleaner_notification_registration, + /* && together multiple FLAG OR TEST sequences + when there are more than one */ + ( bicwa->flags & 0x01 ? 1 : + list_empty(&root->fs_info->dead_roots) + ), + msecs_to_jiffies(bicwa->ms) + ); + 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, + list_empty(&root->fs_info->dead_roots) + ); + }; + + done_with_bicwa: + kfree(bicwa); + return err; + +} + + 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..18ff143 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{ + unsigned long ms; + unsigned long 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 -- l''égalité des droits pour les ambidextres -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html