diff options
| author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2009-04-06 22:01:51 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-07 11:31:18 -0400 |
| commit | 1088dcf4c3a0a27fdad5214781d5084b11405238 (patch) | |
| tree | 4d08f45ff4867d629e5ad4e94e0362e897ffa1e1 /fs | |
| parent | 76068c4ff1cc03d9d24d17fd9e6a1475bc2f6730 (diff) | |
nilfs2: remove timedwait ioctl command
This removes NILFS_IOCTL_TIMEDWAIT command from ioctl interface along
with the related flags and wait queue.
The command is terrible because it just sleeps in the ioctl. I prefer
to avoid this by devising means of event polling in userland program.
By reconsidering the userland GC daemon, I found this is possible
without changing behaviour of the daemon and sacrificing efficiency.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/nilfs2/ioctl.c | 95 | ||||
| -rw-r--r-- | fs/nilfs2/segment.c | 5 | ||||
| -rw-r--r-- | fs/nilfs2/the_nilfs.c | 1 | ||||
| -rw-r--r-- | fs/nilfs2/the_nilfs.h | 6 |
4 files changed, 2 insertions, 105 deletions
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index 9e4d9e64c8ff..85a291ccc1be 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
| @@ -578,62 +578,9 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs, | |||
| 578 | static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp, | 578 | static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp, |
| 579 | unsigned int cmd, void __user *argp) | 579 | unsigned int cmd, void __user *argp) |
| 580 | { | 580 | { |
| 581 | int ret; | ||
| 582 | |||
| 583 | if (!capable(CAP_SYS_ADMIN)) | 581 | if (!capable(CAP_SYS_ADMIN)) |
| 584 | return -EPERM; | 582 | return -EPERM; |
| 585 | 583 | return nilfs_clean_segments(inode->i_sb, argp); | |
| 586 | ret = nilfs_clean_segments(inode->i_sb, argp); | ||
| 587 | clear_nilfs_cond_nongc_write(NILFS_SB(inode->i_sb)->s_nilfs); | ||
| 588 | return ret; | ||
| 589 | } | ||
| 590 | |||
| 591 | static int nilfs_ioctl_test_cond(struct the_nilfs *nilfs, int cond) | ||
| 592 | { | ||
| 593 | return (cond & NILFS_TIMEDWAIT_SEG_WRITE) && | ||
| 594 | nilfs_cond_nongc_write(nilfs); | ||
| 595 | } | ||
| 596 | |||
| 597 | static void nilfs_ioctl_clear_cond(struct the_nilfs *nilfs, int cond) | ||
| 598 | { | ||
| 599 | if (cond & NILFS_TIMEDWAIT_SEG_WRITE) | ||
| 600 | clear_nilfs_cond_nongc_write(nilfs); | ||
| 601 | } | ||
| 602 | |||
| 603 | static int nilfs_ioctl_timedwait(struct inode *inode, struct file *filp, | ||
| 604 | unsigned int cmd, void __user *argp) | ||
| 605 | { | ||
| 606 | struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; | ||
| 607 | struct nilfs_wait_cond wc; | ||
| 608 | long ret; | ||
| 609 | |||
| 610 | if (!capable(CAP_SYS_ADMIN)) | ||
| 611 | return -EPERM; | ||
| 612 | if (copy_from_user(&wc, argp, sizeof(wc))) | ||
| 613 | return -EFAULT; | ||
| 614 | |||
| 615 | unlock_kernel(); | ||
| 616 | ret = wc.wc_flags ? | ||
| 617 | wait_event_interruptible_timeout( | ||
| 618 | nilfs->ns_cleanerd_wq, | ||
| 619 | nilfs_ioctl_test_cond(nilfs, wc.wc_cond), | ||
| 620 | timespec_to_jiffies(&wc.wc_timeout)) : | ||
| 621 | wait_event_interruptible( | ||
| 622 | nilfs->ns_cleanerd_wq, | ||
| 623 | nilfs_ioctl_test_cond(nilfs, wc.wc_cond)); | ||
| 624 | lock_kernel(); | ||
| 625 | nilfs_ioctl_clear_cond(nilfs, wc.wc_cond); | ||
| 626 | |||
| 627 | if (ret > 0) { | ||
| 628 | jiffies_to_timespec(ret, &wc.wc_timeout); | ||
| 629 | if (copy_to_user(argp, &wc, sizeof(wc))) | ||
| 630 | return -EFAULT; | ||
| 631 | return 0; | ||
| 632 | } | ||
| 633 | if (ret != 0) | ||
| 634 | return -EINTR; | ||
| 635 | |||
| 636 | return wc.wc_flags ? -ETIME : 0; | ||
| 637 | } | 584 | } |
| 638 | 585 | ||
| 639 | static int nilfs_ioctl_sync(struct inode *inode, struct file *filp, | 586 | static int nilfs_ioctl_sync(struct inode *inode, struct file *filp, |
| @@ -679,8 +626,6 @@ int nilfs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | |||
| 679 | return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp); | 626 | return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp); |
| 680 | case NILFS_IOCTL_CLEAN_SEGMENTS: | 627 | case NILFS_IOCTL_CLEAN_SEGMENTS: |
| 681 | return nilfs_ioctl_clean_segments(inode, filp, cmd, argp); | 628 | return nilfs_ioctl_clean_segments(inode, filp, cmd, argp); |
| 682 | case NILFS_IOCTL_TIMEDWAIT: | ||
| 683 | return nilfs_ioctl_timedwait(inode, filp, cmd, argp); | ||
| 684 | case NILFS_IOCTL_SYNC: | 629 | case NILFS_IOCTL_SYNC: |
| 685 | return nilfs_ioctl_sync(inode, filp, cmd, argp); | 630 | return nilfs_ioctl_sync(inode, filp, cmd, argp); |
| 686 | default: | 631 | default: |
| @@ -871,41 +816,6 @@ nilfs_compat_ioctl_clean_segments(struct inode *inode, struct file *filp, | |||
| 871 | inode, filp, cmd, (unsigned long)uargv); | 816 | inode, filp, cmd, (unsigned long)uargv); |
| 872 | } | 817 | } |
| 873 | 818 | ||
| 874 | static int | ||
| 875 | nilfs_compat_ioctl_timedwait(struct inode *inode, struct file *filp, | ||
| 876 | unsigned int cmd, unsigned long arg) | ||
| 877 | { | ||
| 878 | struct nilfs_wait_cond __user *uwcond; | ||
| 879 | struct nilfs_wait_cond32 __user *uwcond32; | ||
| 880 | struct timespec ts; | ||
| 881 | int cond, flags, ret; | ||
| 882 | |||
| 883 | uwcond = compat_alloc_user_space(sizeof(struct nilfs_wait_cond)); | ||
| 884 | uwcond32 = compat_ptr(arg); | ||
| 885 | if (get_user(cond, &uwcond32->wc_cond) || | ||
| 886 | put_user(cond, &uwcond->wc_cond) || | ||
| 887 | get_user(flags, &uwcond32->wc_flags) || | ||
| 888 | put_user(flags, &uwcond->wc_flags) || | ||
| 889 | get_user(ts.tv_sec, &uwcond32->wc_timeout.tv_sec) || | ||
| 890 | get_user(ts.tv_nsec, &uwcond32->wc_timeout.tv_nsec) || | ||
| 891 | put_user(ts.tv_sec, &uwcond->wc_timeout.tv_sec) || | ||
| 892 | put_user(ts.tv_nsec, &uwcond->wc_timeout.tv_nsec)) | ||
| 893 | return -EFAULT; | ||
| 894 | |||
| 895 | ret = nilfs_compat_locked_ioctl(inode, filp, cmd, | ||
| 896 | (unsigned long)uwcond); | ||
| 897 | if (ret < 0) | ||
| 898 | return ret; | ||
| 899 | |||
| 900 | if (get_user(ts.tv_sec, &uwcond->wc_timeout.tv_sec) || | ||
| 901 | get_user(ts.tv_nsec, &uwcond->wc_timeout.tv_nsec) || | ||
| 902 | put_user(ts.tv_sec, &uwcond32->wc_timeout.tv_sec) || | ||
| 903 | put_user(ts.tv_nsec, &uwcond32->wc_timeout.tv_nsec)) | ||
| 904 | return -EFAULT; | ||
| 905 | |||
| 906 | return 0; | ||
| 907 | } | ||
| 908 | |||
| 909 | static int nilfs_compat_ioctl_sync(struct inode *inode, struct file *filp, | 819 | static int nilfs_compat_ioctl_sync(struct inode *inode, struct file *filp, |
| 910 | unsigned int cmd, unsigned long arg) | 820 | unsigned int cmd, unsigned long arg) |
| 911 | { | 821 | { |
| @@ -943,9 +853,6 @@ long nilfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 943 | case NILFS_IOCTL32_CLEAN_SEGMENTS: | 853 | case NILFS_IOCTL32_CLEAN_SEGMENTS: |
| 944 | return nilfs_compat_ioctl_clean_segments( | 854 | return nilfs_compat_ioctl_clean_segments( |
| 945 | inode, filp, NILFS_IOCTL_CLEAN_SEGMENTS, arg); | 855 | inode, filp, NILFS_IOCTL_CLEAN_SEGMENTS, arg); |
| 946 | case NILFS_IOCTL32_TIMEDWAIT: | ||
| 947 | return nilfs_compat_ioctl_timedwait( | ||
| 948 | inode, filp, NILFS_IOCTL_TIMEDWAIT, arg); | ||
| 949 | case NILFS_IOCTL_SYNC: | 856 | case NILFS_IOCTL_SYNC: |
| 950 | return nilfs_compat_ioctl_sync(inode, filp, cmd, arg); | 857 | return nilfs_compat_ioctl_sync(inode, filp, cmd, arg); |
| 951 | default: | 858 | default: |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 6d66c5cb7b51..5db12d774a03 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
| @@ -2114,11 +2114,8 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci) | |||
| 2114 | nilfs_drop_collected_inodes(&sci->sc_gc_inodes); | 2114 | nilfs_drop_collected_inodes(&sci->sc_gc_inodes); |
| 2115 | if (update_sr) | 2115 | if (update_sr) |
| 2116 | nilfs_commit_gcdat_inode(nilfs); | 2116 | nilfs_commit_gcdat_inode(nilfs); |
| 2117 | } else { | 2117 | } else |
| 2118 | nilfs->ns_nongc_ctime = sci->sc_seg_ctime; | 2118 | nilfs->ns_nongc_ctime = sci->sc_seg_ctime; |
| 2119 | set_nilfs_cond_nongc_write(nilfs); | ||
| 2120 | wake_up(&nilfs->ns_cleanerd_wq); | ||
| 2121 | } | ||
| 2122 | 2119 | ||
| 2123 | sci->sc_nblk_inc += sci->sc_nblk_this_inc; | 2120 | sci->sc_nblk_inc += sci->sc_nblk_this_inc; |
| 2124 | 2121 | ||
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 852e0bf3a3c5..69b625586226 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c | |||
| @@ -73,7 +73,6 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev) | |||
| 73 | nilfs->ns_gc_inodes_h = NULL; | 73 | nilfs->ns_gc_inodes_h = NULL; |
| 74 | INIT_LIST_HEAD(&nilfs->ns_used_segments); | 74 | INIT_LIST_HEAD(&nilfs->ns_used_segments); |
| 75 | init_rwsem(&nilfs->ns_segctor_sem); | 75 | init_rwsem(&nilfs->ns_segctor_sem); |
| 76 | init_waitqueue_head(&nilfs->ns_cleanerd_wq); | ||
| 77 | 76 | ||
| 78 | return nilfs; | 77 | return nilfs; |
| 79 | } | 78 | } |
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index 9cd3c113f052..75da37306964 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h | |||
| @@ -37,7 +37,6 @@ enum { | |||
| 37 | THE_NILFS_LOADED, /* Roll-back/roll-forward has done and | 37 | THE_NILFS_LOADED, /* Roll-back/roll-forward has done and |
| 38 | the latest checkpoint was loaded */ | 38 | the latest checkpoint was loaded */ |
| 39 | THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */ | 39 | THE_NILFS_DISCONTINUED, /* 'next' pointer chain has broken */ |
| 40 | THE_NILFS_COND_NONGC_WRITE, /* Condition to wake up cleanerd */ | ||
| 41 | }; | 40 | }; |
| 42 | 41 | ||
| 43 | /** | 42 | /** |
| @@ -74,7 +73,6 @@ enum { | |||
| 74 | * @ns_gc_dat: shadow inode of the DAT file inode for GC | 73 | * @ns_gc_dat: shadow inode of the DAT file inode for GC |
| 75 | * @ns_gc_inodes: dummy inodes to keep live blocks | 74 | * @ns_gc_inodes: dummy inodes to keep live blocks |
| 76 | * @ns_gc_inodes_h: hash list to keep dummy inode holding live blocks | 75 | * @ns_gc_inodes_h: hash list to keep dummy inode holding live blocks |
| 77 | * @ns_cleanerd_wq: wait queue for cleanerd | ||
| 78 | * @ns_blocksize_bits: bit length of block size | 76 | * @ns_blocksize_bits: bit length of block size |
| 79 | * @ns_nsegments: number of segments in filesystem | 77 | * @ns_nsegments: number of segments in filesystem |
| 80 | * @ns_blocks_per_segment: number of blocks per segment | 78 | * @ns_blocks_per_segment: number of blocks per segment |
| @@ -151,9 +149,6 @@ struct the_nilfs { | |||
| 151 | struct list_head ns_gc_inodes; | 149 | struct list_head ns_gc_inodes; |
| 152 | struct hlist_head *ns_gc_inodes_h; | 150 | struct hlist_head *ns_gc_inodes_h; |
| 153 | 151 | ||
| 154 | /* cleanerd */ | ||
| 155 | wait_queue_head_t ns_cleanerd_wq; | ||
| 156 | |||
| 157 | /* Disk layout information (static) */ | 152 | /* Disk layout information (static) */ |
| 158 | unsigned int ns_blocksize_bits; | 153 | unsigned int ns_blocksize_bits; |
| 159 | unsigned long ns_nsegments; | 154 | unsigned long ns_nsegments; |
| @@ -186,7 +181,6 @@ static inline int nilfs_##name(struct the_nilfs *nilfs) \ | |||
| 186 | THE_NILFS_FNS(INIT, init) | 181 | THE_NILFS_FNS(INIT, init) |
| 187 | THE_NILFS_FNS(LOADED, loaded) | 182 | THE_NILFS_FNS(LOADED, loaded) |
| 188 | THE_NILFS_FNS(DISCONTINUED, discontinued) | 183 | THE_NILFS_FNS(DISCONTINUED, discontinued) |
| 189 | THE_NILFS_FNS(COND_NONGC_WRITE, cond_nongc_write) | ||
| 190 | 184 | ||
| 191 | void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64); | 185 | void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64); |
| 192 | struct the_nilfs *alloc_nilfs(struct block_device *); | 186 | struct the_nilfs *alloc_nilfs(struct block_device *); |
