diff mbox

PATCH zeroing ioctl21 flags progs-side

Message ID AANLkTikJVZ+a78tDumtZOTD-i_r9Ge8EgjEjta_Ja5tD@mail.gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

David Nicol Oct. 14, 2010, 4:17 p.m. UTC
None
diff mbox

Patch

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