diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-03-02 23:16:01 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-03-02 23:16:01 -0500 |
| commit | 013daec9c19b73ef1e8e427dd7c8acca5766c17e (patch) | |
| tree | c14c687f40ec22c5f48e23a08e8ae00c2ddfc2f9 /fs | |
| parent | bf13c9a894162a91c8bb7d9555933e9fc3ff7d0e (diff) | |
| parent | 0414855fdc4a40da05221fc6062cccbc0c30f169 (diff) | |
Merge 3.14-rc5 into tty-next
We want these fixes in here
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/fs-writeback.c | 33 | ||||
| -rw-r--r-- | fs/kernfs/mount.c | 8 | ||||
| -rw-r--r-- | fs/notify/dnotify/dnotify.c | 2 | ||||
| -rw-r--r-- | fs/notify/fanotify/fanotify.c | 8 | ||||
| -rw-r--r-- | fs/notify/fanotify/fanotify_user.c | 13 | ||||
| -rw-r--r-- | fs/notify/fsnotify.c | 2 | ||||
| -rw-r--r-- | fs/notify/group.c | 8 | ||||
| -rw-r--r-- | fs/notify/inotify/inotify.h | 2 | ||||
| -rw-r--r-- | fs/notify/inotify/inotify_fsnotify.c | 3 | ||||
| -rw-r--r-- | fs/notify/inotify/inotify_user.c | 14 | ||||
| -rw-r--r-- | fs/notify/notification.c | 20 | ||||
| -rw-r--r-- | fs/quota/dquot.c | 14 | ||||
| -rw-r--r-- | fs/sync.c | 15 | ||||
| -rw-r--r-- | fs/sysfs/mount.c | 5 | ||||
| -rw-r--r-- | fs/udf/file.c | 14 | ||||
| -rw-r--r-- | fs/udf/inode.c | 1 | ||||
| -rw-r--r-- | fs/xfs/xfs_super.c | 2 |
17 files changed, 110 insertions, 54 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index e0259a163f98..d754e3cf99a8 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
| @@ -40,18 +40,13 @@ | |||
| 40 | struct wb_writeback_work { | 40 | struct wb_writeback_work { |
| 41 | long nr_pages; | 41 | long nr_pages; |
| 42 | struct super_block *sb; | 42 | struct super_block *sb; |
| 43 | /* | 43 | unsigned long *older_than_this; |
| 44 | * Write only inodes dirtied before this time. Don't forget to set | ||
| 45 | * older_than_this_is_set when you set this. | ||
| 46 | */ | ||
| 47 | unsigned long older_than_this; | ||
| 48 | enum writeback_sync_modes sync_mode; | 44 | enum writeback_sync_modes sync_mode; |
| 49 | unsigned int tagged_writepages:1; | 45 | unsigned int tagged_writepages:1; |
| 50 | unsigned int for_kupdate:1; | 46 | unsigned int for_kupdate:1; |
| 51 | unsigned int range_cyclic:1; | 47 | unsigned int range_cyclic:1; |
| 52 | unsigned int for_background:1; | 48 | unsigned int for_background:1; |
| 53 | unsigned int for_sync:1; /* sync(2) WB_SYNC_ALL writeback */ | 49 | unsigned int for_sync:1; /* sync(2) WB_SYNC_ALL writeback */ |
| 54 | unsigned int older_than_this_is_set:1; | ||
| 55 | enum wb_reason reason; /* why was writeback initiated? */ | 50 | enum wb_reason reason; /* why was writeback initiated? */ |
| 56 | 51 | ||
| 57 | struct list_head list; /* pending work list */ | 52 | struct list_head list; /* pending work list */ |
| @@ -252,10 +247,10 @@ static int move_expired_inodes(struct list_head *delaying_queue, | |||
| 252 | int do_sb_sort = 0; | 247 | int do_sb_sort = 0; |
| 253 | int moved = 0; | 248 | int moved = 0; |
| 254 | 249 | ||
| 255 | WARN_ON_ONCE(!work->older_than_this_is_set); | ||
| 256 | while (!list_empty(delaying_queue)) { | 250 | while (!list_empty(delaying_queue)) { |
| 257 | inode = wb_inode(delaying_queue->prev); | 251 | inode = wb_inode(delaying_queue->prev); |
| 258 | if (inode_dirtied_after(inode, work->older_than_this)) | 252 | if (work->older_than_this && |
| 253 | inode_dirtied_after(inode, *work->older_than_this)) | ||
| 259 | break; | 254 | break; |
| 260 | list_move(&inode->i_wb_list, &tmp); | 255 | list_move(&inode->i_wb_list, &tmp); |
| 261 | moved++; | 256 | moved++; |
| @@ -742,8 +737,6 @@ static long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages, | |||
| 742 | .sync_mode = WB_SYNC_NONE, | 737 | .sync_mode = WB_SYNC_NONE, |
| 743 | .range_cyclic = 1, | 738 | .range_cyclic = 1, |
| 744 | .reason = reason, | 739 | .reason = reason, |
| 745 | .older_than_this = jiffies, | ||
| 746 | .older_than_this_is_set = 1, | ||
| 747 | }; | 740 | }; |
| 748 | 741 | ||
| 749 | spin_lock(&wb->list_lock); | 742 | spin_lock(&wb->list_lock); |
| @@ -802,13 +795,12 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
| 802 | { | 795 | { |
| 803 | unsigned long wb_start = jiffies; | 796 | unsigned long wb_start = jiffies; |
| 804 | long nr_pages = work->nr_pages; | 797 | long nr_pages = work->nr_pages; |
| 798 | unsigned long oldest_jif; | ||
| 805 | struct inode *inode; | 799 | struct inode *inode; |
| 806 | long progress; | 800 | long progress; |
| 807 | 801 | ||
| 808 | if (!work->older_than_this_is_set) { | 802 | oldest_jif = jiffies; |
| 809 | work->older_than_this = jiffies; | 803 | work->older_than_this = &oldest_jif; |
| 810 | work->older_than_this_is_set = 1; | ||
| 811 | } | ||
| 812 | 804 | ||
| 813 | spin_lock(&wb->list_lock); | 805 | spin_lock(&wb->list_lock); |
| 814 | for (;;) { | 806 | for (;;) { |
| @@ -842,10 +834,10 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
| 842 | * safe. | 834 | * safe. |
| 843 | */ | 835 | */ |
| 844 | if (work->for_kupdate) { | 836 | if (work->for_kupdate) { |
| 845 | work->older_than_this = jiffies - | 837 | oldest_jif = jiffies - |
| 846 | msecs_to_jiffies(dirty_expire_interval * 10); | 838 | msecs_to_jiffies(dirty_expire_interval * 10); |
| 847 | } else if (work->for_background) | 839 | } else if (work->for_background) |
| 848 | work->older_than_this = jiffies; | 840 | oldest_jif = jiffies; |
| 849 | 841 | ||
| 850 | trace_writeback_start(wb->bdi, work); | 842 | trace_writeback_start(wb->bdi, work); |
| 851 | if (list_empty(&wb->b_io)) | 843 | if (list_empty(&wb->b_io)) |
| @@ -1357,21 +1349,18 @@ EXPORT_SYMBOL(try_to_writeback_inodes_sb); | |||
| 1357 | 1349 | ||
| 1358 | /** | 1350 | /** |
| 1359 | * sync_inodes_sb - sync sb inode pages | 1351 | * sync_inodes_sb - sync sb inode pages |
| 1360 | * @sb: the superblock | 1352 | * @sb: the superblock |
| 1361 | * @older_than_this: timestamp | ||
| 1362 | * | 1353 | * |
| 1363 | * This function writes and waits on any dirty inode belonging to this | 1354 | * This function writes and waits on any dirty inode belonging to this |
| 1364 | * superblock that has been dirtied before given timestamp. | 1355 | * super_block. |
| 1365 | */ | 1356 | */ |
| 1366 | void sync_inodes_sb(struct super_block *sb, unsigned long older_than_this) | 1357 | void sync_inodes_sb(struct super_block *sb) |
| 1367 | { | 1358 | { |
| 1368 | DECLARE_COMPLETION_ONSTACK(done); | 1359 | DECLARE_COMPLETION_ONSTACK(done); |
| 1369 | struct wb_writeback_work work = { | 1360 | struct wb_writeback_work work = { |
| 1370 | .sb = sb, | 1361 | .sb = sb, |
| 1371 | .sync_mode = WB_SYNC_ALL, | 1362 | .sync_mode = WB_SYNC_ALL, |
| 1372 | .nr_pages = LONG_MAX, | 1363 | .nr_pages = LONG_MAX, |
| 1373 | .older_than_this = older_than_this, | ||
| 1374 | .older_than_this_is_set = 1, | ||
| 1375 | .range_cyclic = 0, | 1364 | .range_cyclic = 0, |
| 1376 | .done = &done, | 1365 | .done = &done, |
| 1377 | .reason = WB_REASON_SYNC, | 1366 | .reason = WB_REASON_SYNC, |
diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index 0d6ce895a9ee..0f4152defe7b 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c | |||
| @@ -94,6 +94,7 @@ const void *kernfs_super_ns(struct super_block *sb) | |||
| 94 | * @fs_type: file_system_type of the fs being mounted | 94 | * @fs_type: file_system_type of the fs being mounted |
| 95 | * @flags: mount flags specified for the mount | 95 | * @flags: mount flags specified for the mount |
| 96 | * @root: kernfs_root of the hierarchy being mounted | 96 | * @root: kernfs_root of the hierarchy being mounted |
| 97 | * @new_sb_created: tell the caller if we allocated a new superblock | ||
| 97 | * @ns: optional namespace tag of the mount | 98 | * @ns: optional namespace tag of the mount |
| 98 | * | 99 | * |
| 99 | * This is to be called from each kernfs user's file_system_type->mount() | 100 | * This is to be called from each kernfs user's file_system_type->mount() |
| @@ -104,7 +105,8 @@ const void *kernfs_super_ns(struct super_block *sb) | |||
| 104 | * The return value can be passed to the vfs layer verbatim. | 105 | * The return value can be passed to the vfs layer verbatim. |
| 105 | */ | 106 | */ |
| 106 | struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, | 107 | struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, |
| 107 | struct kernfs_root *root, const void *ns) | 108 | struct kernfs_root *root, bool *new_sb_created, |
| 109 | const void *ns) | ||
| 108 | { | 110 | { |
| 109 | struct super_block *sb; | 111 | struct super_block *sb; |
| 110 | struct kernfs_super_info *info; | 112 | struct kernfs_super_info *info; |
| @@ -122,6 +124,10 @@ struct dentry *kernfs_mount_ns(struct file_system_type *fs_type, int flags, | |||
| 122 | kfree(info); | 124 | kfree(info); |
| 123 | if (IS_ERR(sb)) | 125 | if (IS_ERR(sb)) |
| 124 | return ERR_CAST(sb); | 126 | return ERR_CAST(sb); |
| 127 | |||
| 128 | if (new_sb_created) | ||
| 129 | *new_sb_created = !sb->s_root; | ||
| 130 | |||
| 125 | if (!sb->s_root) { | 131 | if (!sb->s_root) { |
| 126 | error = kernfs_fill_super(sb); | 132 | error = kernfs_fill_super(sb); |
| 127 | if (error) { | 133 | if (error) { |
diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 0b9ff4395e6a..abc8cbcfe90e 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c | |||
| @@ -86,7 +86,7 @@ static int dnotify_handle_event(struct fsnotify_group *group, | |||
| 86 | struct fsnotify_mark *inode_mark, | 86 | struct fsnotify_mark *inode_mark, |
| 87 | struct fsnotify_mark *vfsmount_mark, | 87 | struct fsnotify_mark *vfsmount_mark, |
| 88 | u32 mask, void *data, int data_type, | 88 | u32 mask, void *data, int data_type, |
| 89 | const unsigned char *file_name) | 89 | const unsigned char *file_name, u32 cookie) |
| 90 | { | 90 | { |
| 91 | struct dnotify_mark *dn_mark; | 91 | struct dnotify_mark *dn_mark; |
| 92 | struct dnotify_struct *dn; | 92 | struct dnotify_struct *dn; |
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 0e792f5e3147..dc638f786d5c 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
| @@ -147,7 +147,7 @@ static int fanotify_handle_event(struct fsnotify_group *group, | |||
| 147 | struct fsnotify_mark *inode_mark, | 147 | struct fsnotify_mark *inode_mark, |
| 148 | struct fsnotify_mark *fanotify_mark, | 148 | struct fsnotify_mark *fanotify_mark, |
| 149 | u32 mask, void *data, int data_type, | 149 | u32 mask, void *data, int data_type, |
| 150 | const unsigned char *file_name) | 150 | const unsigned char *file_name, u32 cookie) |
| 151 | { | 151 | { |
| 152 | int ret = 0; | 152 | int ret = 0; |
| 153 | struct fanotify_event_info *event; | 153 | struct fanotify_event_info *event; |
| @@ -192,10 +192,12 @@ static int fanotify_handle_event(struct fsnotify_group *group, | |||
| 192 | 192 | ||
| 193 | ret = fsnotify_add_notify_event(group, fsn_event, fanotify_merge); | 193 | ret = fsnotify_add_notify_event(group, fsn_event, fanotify_merge); |
| 194 | if (ret) { | 194 | if (ret) { |
| 195 | BUG_ON(mask & FAN_ALL_PERM_EVENTS); | 195 | /* Permission events shouldn't be merged */ |
| 196 | BUG_ON(ret == 1 && mask & FAN_ALL_PERM_EVENTS); | ||
| 196 | /* Our event wasn't used in the end. Free it. */ | 197 | /* Our event wasn't used in the end. Free it. */ |
| 197 | fsnotify_destroy_event(group, fsn_event); | 198 | fsnotify_destroy_event(group, fsn_event); |
| 198 | ret = 0; | 199 | |
| 200 | return 0; | ||
| 199 | } | 201 | } |
| 200 | 202 | ||
| 201 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | 203 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index b6175fa11bf8..287a22c04149 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
| @@ -698,6 +698,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
| 698 | struct fsnotify_group *group; | 698 | struct fsnotify_group *group; |
| 699 | int f_flags, fd; | 699 | int f_flags, fd; |
| 700 | struct user_struct *user; | 700 | struct user_struct *user; |
| 701 | struct fanotify_event_info *oevent; | ||
| 701 | 702 | ||
| 702 | pr_debug("%s: flags=%d event_f_flags=%d\n", | 703 | pr_debug("%s: flags=%d event_f_flags=%d\n", |
| 703 | __func__, flags, event_f_flags); | 704 | __func__, flags, event_f_flags); |
| @@ -730,8 +731,20 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
| 730 | group->fanotify_data.user = user; | 731 | group->fanotify_data.user = user; |
| 731 | atomic_inc(&user->fanotify_listeners); | 732 | atomic_inc(&user->fanotify_listeners); |
| 732 | 733 | ||
| 734 | oevent = kmem_cache_alloc(fanotify_event_cachep, GFP_KERNEL); | ||
| 735 | if (unlikely(!oevent)) { | ||
| 736 | fd = -ENOMEM; | ||
| 737 | goto out_destroy_group; | ||
| 738 | } | ||
| 739 | group->overflow_event = &oevent->fse; | ||
| 740 | fsnotify_init_event(group->overflow_event, NULL, FS_Q_OVERFLOW); | ||
| 741 | oevent->tgid = get_pid(task_tgid(current)); | ||
| 742 | oevent->path.mnt = NULL; | ||
| 743 | oevent->path.dentry = NULL; | ||
| 744 | |||
| 733 | group->fanotify_data.f_flags = event_f_flags; | 745 | group->fanotify_data.f_flags = event_f_flags; |
| 734 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | 746 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS |
| 747 | oevent->response = 0; | ||
| 735 | mutex_init(&group->fanotify_data.access_mutex); | 748 | mutex_init(&group->fanotify_data.access_mutex); |
| 736 | init_waitqueue_head(&group->fanotify_data.access_waitq); | 749 | init_waitqueue_head(&group->fanotify_data.access_waitq); |
| 737 | INIT_LIST_HEAD(&group->fanotify_data.access_list); | 750 | INIT_LIST_HEAD(&group->fanotify_data.access_list); |
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 1d4e1ea2f37c..9d3e9c50066a 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
| @@ -179,7 +179,7 @@ static int send_to_group(struct inode *to_tell, | |||
| 179 | 179 | ||
| 180 | return group->ops->handle_event(group, to_tell, inode_mark, | 180 | return group->ops->handle_event(group, to_tell, inode_mark, |
| 181 | vfsmount_mark, mask, data, data_is, | 181 | vfsmount_mark, mask, data, data_is, |
| 182 | file_name); | 182 | file_name, cookie); |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | /* | 185 | /* |
diff --git a/fs/notify/group.c b/fs/notify/group.c index ee674fe2cec7..ad1995980456 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c | |||
| @@ -55,6 +55,13 @@ void fsnotify_destroy_group(struct fsnotify_group *group) | |||
| 55 | /* clear the notification queue of all events */ | 55 | /* clear the notification queue of all events */ |
| 56 | fsnotify_flush_notify(group); | 56 | fsnotify_flush_notify(group); |
| 57 | 57 | ||
| 58 | /* | ||
| 59 | * Destroy overflow event (we cannot use fsnotify_destroy_event() as | ||
| 60 | * that deliberately ignores overflow events. | ||
| 61 | */ | ||
| 62 | if (group->overflow_event) | ||
| 63 | group->ops->free_event(group->overflow_event); | ||
| 64 | |||
| 58 | fsnotify_put_group(group); | 65 | fsnotify_put_group(group); |
| 59 | } | 66 | } |
| 60 | 67 | ||
| @@ -99,7 +106,6 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops) | |||
| 99 | INIT_LIST_HEAD(&group->marks_list); | 106 | INIT_LIST_HEAD(&group->marks_list); |
| 100 | 107 | ||
| 101 | group->ops = ops; | 108 | group->ops = ops; |
| 102 | fsnotify_init_event(&group->overflow_event, NULL, FS_Q_OVERFLOW); | ||
| 103 | 109 | ||
| 104 | return group; | 110 | return group; |
| 105 | } | 111 | } |
diff --git a/fs/notify/inotify/inotify.h b/fs/notify/inotify/inotify.h index 485eef3f4407..ed855ef6f077 100644 --- a/fs/notify/inotify/inotify.h +++ b/fs/notify/inotify/inotify.h | |||
| @@ -27,6 +27,6 @@ extern int inotify_handle_event(struct fsnotify_group *group, | |||
| 27 | struct fsnotify_mark *inode_mark, | 27 | struct fsnotify_mark *inode_mark, |
| 28 | struct fsnotify_mark *vfsmount_mark, | 28 | struct fsnotify_mark *vfsmount_mark, |
| 29 | u32 mask, void *data, int data_type, | 29 | u32 mask, void *data, int data_type, |
| 30 | const unsigned char *file_name); | 30 | const unsigned char *file_name, u32 cookie); |
| 31 | 31 | ||
| 32 | extern const struct fsnotify_ops inotify_fsnotify_ops; | 32 | extern const struct fsnotify_ops inotify_fsnotify_ops; |
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index d5ee56348bb8..43ab1e1a07a2 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c | |||
| @@ -67,7 +67,7 @@ int inotify_handle_event(struct fsnotify_group *group, | |||
| 67 | struct fsnotify_mark *inode_mark, | 67 | struct fsnotify_mark *inode_mark, |
| 68 | struct fsnotify_mark *vfsmount_mark, | 68 | struct fsnotify_mark *vfsmount_mark, |
| 69 | u32 mask, void *data, int data_type, | 69 | u32 mask, void *data, int data_type, |
| 70 | const unsigned char *file_name) | 70 | const unsigned char *file_name, u32 cookie) |
| 71 | { | 71 | { |
| 72 | struct inotify_inode_mark *i_mark; | 72 | struct inotify_inode_mark *i_mark; |
| 73 | struct inotify_event_info *event; | 73 | struct inotify_event_info *event; |
| @@ -103,6 +103,7 @@ int inotify_handle_event(struct fsnotify_group *group, | |||
| 103 | fsn_event = &event->fse; | 103 | fsn_event = &event->fse; |
| 104 | fsnotify_init_event(fsn_event, inode, mask); | 104 | fsnotify_init_event(fsn_event, inode, mask); |
| 105 | event->wd = i_mark->wd; | 105 | event->wd = i_mark->wd; |
| 106 | event->sync_cookie = cookie; | ||
| 106 | event->name_len = len; | 107 | event->name_len = len; |
| 107 | if (len) | 108 | if (len) |
| 108 | strcpy(event->name, file_name); | 109 | strcpy(event->name, file_name); |
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 497395c8274b..78a2ca3966c3 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
| @@ -495,7 +495,7 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark, | |||
| 495 | 495 | ||
| 496 | /* Queue ignore event for the watch */ | 496 | /* Queue ignore event for the watch */ |
| 497 | inotify_handle_event(group, NULL, fsn_mark, NULL, FS_IN_IGNORED, | 497 | inotify_handle_event(group, NULL, fsn_mark, NULL, FS_IN_IGNORED, |
| 498 | NULL, FSNOTIFY_EVENT_NONE, NULL); | 498 | NULL, FSNOTIFY_EVENT_NONE, NULL, 0); |
| 499 | 499 | ||
| 500 | i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark); | 500 | i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark); |
| 501 | /* remove this mark from the idr */ | 501 | /* remove this mark from the idr */ |
| @@ -633,11 +633,23 @@ static int inotify_update_watch(struct fsnotify_group *group, struct inode *inod | |||
| 633 | static struct fsnotify_group *inotify_new_group(unsigned int max_events) | 633 | static struct fsnotify_group *inotify_new_group(unsigned int max_events) |
| 634 | { | 634 | { |
| 635 | struct fsnotify_group *group; | 635 | struct fsnotify_group *group; |
| 636 | struct inotify_event_info *oevent; | ||
| 636 | 637 | ||
| 637 | group = fsnotify_alloc_group(&inotify_fsnotify_ops); | 638 | group = fsnotify_alloc_group(&inotify_fsnotify_ops); |
| 638 | if (IS_ERR(group)) | 639 | if (IS_ERR(group)) |
| 639 | return group; | 640 | return group; |
| 640 | 641 | ||
| 642 | oevent = kmalloc(sizeof(struct inotify_event_info), GFP_KERNEL); | ||
| 643 | if (unlikely(!oevent)) { | ||
| 644 | fsnotify_destroy_group(group); | ||
| 645 | return ERR_PTR(-ENOMEM); | ||
| 646 | } | ||
| 647 | group->overflow_event = &oevent->fse; | ||
| 648 | fsnotify_init_event(group->overflow_event, NULL, FS_Q_OVERFLOW); | ||
| 649 | oevent->wd = -1; | ||
| 650 | oevent->sync_cookie = 0; | ||
| 651 | oevent->name_len = 0; | ||
| 652 | |||
| 641 | group->max_events = max_events; | 653 | group->max_events = max_events; |
| 642 | 654 | ||
| 643 | spin_lock_init(&group->inotify_data.idr_lock); | 655 | spin_lock_init(&group->inotify_data.idr_lock); |
diff --git a/fs/notify/notification.c b/fs/notify/notification.c index 18b3c4427dca..1e58402171a5 100644 --- a/fs/notify/notification.c +++ b/fs/notify/notification.c | |||
| @@ -80,7 +80,8 @@ void fsnotify_destroy_event(struct fsnotify_group *group, | |||
| 80 | /* | 80 | /* |
| 81 | * Add an event to the group notification queue. The group can later pull this | 81 | * Add an event to the group notification queue. The group can later pull this |
| 82 | * event off the queue to deal with. The function returns 0 if the event was | 82 | * event off the queue to deal with. The function returns 0 if the event was |
| 83 | * added to the queue, 1 if the event was merged with some other queued event. | 83 | * added to the queue, 1 if the event was merged with some other queued event, |
| 84 | * 2 if the queue of events has overflown. | ||
| 84 | */ | 85 | */ |
| 85 | int fsnotify_add_notify_event(struct fsnotify_group *group, | 86 | int fsnotify_add_notify_event(struct fsnotify_group *group, |
| 86 | struct fsnotify_event *event, | 87 | struct fsnotify_event *event, |
| @@ -95,10 +96,14 @@ int fsnotify_add_notify_event(struct fsnotify_group *group, | |||
| 95 | mutex_lock(&group->notification_mutex); | 96 | mutex_lock(&group->notification_mutex); |
| 96 | 97 | ||
| 97 | if (group->q_len >= group->max_events) { | 98 | if (group->q_len >= group->max_events) { |
| 99 | ret = 2; | ||
| 98 | /* Queue overflow event only if it isn't already queued */ | 100 | /* Queue overflow event only if it isn't already queued */ |
| 99 | if (list_empty(&group->overflow_event.list)) | 101 | if (!list_empty(&group->overflow_event->list)) { |
| 100 | event = &group->overflow_event; | 102 | mutex_unlock(&group->notification_mutex); |
| 101 | ret = 1; | 103 | return ret; |
| 104 | } | ||
| 105 | event = group->overflow_event; | ||
| 106 | goto queue; | ||
| 102 | } | 107 | } |
| 103 | 108 | ||
| 104 | if (!list_empty(list) && merge) { | 109 | if (!list_empty(list) && merge) { |
| @@ -109,6 +114,7 @@ int fsnotify_add_notify_event(struct fsnotify_group *group, | |||
| 109 | } | 114 | } |
| 110 | } | 115 | } |
| 111 | 116 | ||
| 117 | queue: | ||
| 112 | group->q_len++; | 118 | group->q_len++; |
| 113 | list_add_tail(&event->list, list); | 119 | list_add_tail(&event->list, list); |
| 114 | mutex_unlock(&group->notification_mutex); | 120 | mutex_unlock(&group->notification_mutex); |
| @@ -132,7 +138,11 @@ struct fsnotify_event *fsnotify_remove_notify_event(struct fsnotify_group *group | |||
| 132 | 138 | ||
| 133 | event = list_first_entry(&group->notification_list, | 139 | event = list_first_entry(&group->notification_list, |
| 134 | struct fsnotify_event, list); | 140 | struct fsnotify_event, list); |
| 135 | list_del(&event->list); | 141 | /* |
| 142 | * We need to init list head for the case of overflow event so that | ||
| 143 | * check in fsnotify_add_notify_events() works | ||
| 144 | */ | ||
| 145 | list_del_init(&event->list); | ||
| 136 | group->q_len--; | 146 | group->q_len--; |
| 137 | 147 | ||
| 138 | return event; | 148 | return event; |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 831d49a4111f..cfc8dcc16043 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
| @@ -581,9 +581,17 @@ int dquot_scan_active(struct super_block *sb, | |||
| 581 | dqstats_inc(DQST_LOOKUPS); | 581 | dqstats_inc(DQST_LOOKUPS); |
| 582 | dqput(old_dquot); | 582 | dqput(old_dquot); |
| 583 | old_dquot = dquot; | 583 | old_dquot = dquot; |
| 584 | ret = fn(dquot, priv); | 584 | /* |
| 585 | if (ret < 0) | 585 | * ->release_dquot() can be racing with us. Our reference |
| 586 | goto out; | 586 | * protects us from new calls to it so just wait for any |
| 587 | * outstanding call and recheck the DQ_ACTIVE_B after that. | ||
| 588 | */ | ||
| 589 | wait_on_dquot(dquot); | ||
| 590 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { | ||
| 591 | ret = fn(dquot, priv); | ||
| 592 | if (ret < 0) | ||
| 593 | goto out; | ||
| 594 | } | ||
| 587 | spin_lock(&dq_list_lock); | 595 | spin_lock(&dq_list_lock); |
| 588 | /* We are safe to continue now because our dquot could not | 596 | /* We are safe to continue now because our dquot could not |
| 589 | * be moved out of the inuse list while we hold the reference */ | 597 | * be moved out of the inuse list while we hold the reference */ |
| @@ -27,11 +27,10 @@ | |||
| 27 | * wait == 1 case since in that case write_inode() functions do | 27 | * wait == 1 case since in that case write_inode() functions do |
| 28 | * sync_dirty_buffer() and thus effectively write one block at a time. | 28 | * sync_dirty_buffer() and thus effectively write one block at a time. |
| 29 | */ | 29 | */ |
| 30 | static int __sync_filesystem(struct super_block *sb, int wait, | 30 | static int __sync_filesystem(struct super_block *sb, int wait) |
| 31 | unsigned long start) | ||
| 32 | { | 31 | { |
| 33 | if (wait) | 32 | if (wait) |
| 34 | sync_inodes_sb(sb, start); | 33 | sync_inodes_sb(sb); |
| 35 | else | 34 | else |
| 36 | writeback_inodes_sb(sb, WB_REASON_SYNC); | 35 | writeback_inodes_sb(sb, WB_REASON_SYNC); |
| 37 | 36 | ||
| @@ -48,7 +47,6 @@ static int __sync_filesystem(struct super_block *sb, int wait, | |||
| 48 | int sync_filesystem(struct super_block *sb) | 47 | int sync_filesystem(struct super_block *sb) |
| 49 | { | 48 | { |
| 50 | int ret; | 49 | int ret; |
| 51 | unsigned long start = jiffies; | ||
| 52 | 50 | ||
| 53 | /* | 51 | /* |
| 54 | * We need to be protected against the filesystem going from | 52 | * We need to be protected against the filesystem going from |
| @@ -62,17 +60,17 @@ int sync_filesystem(struct super_block *sb) | |||
| 62 | if (sb->s_flags & MS_RDONLY) | 60 | if (sb->s_flags & MS_RDONLY) |
| 63 | return 0; | 61 | return 0; |
| 64 | 62 | ||
| 65 | ret = __sync_filesystem(sb, 0, start); | 63 | ret = __sync_filesystem(sb, 0); |
| 66 | if (ret < 0) | 64 | if (ret < 0) |
| 67 | return ret; | 65 | return ret; |
| 68 | return __sync_filesystem(sb, 1, start); | 66 | return __sync_filesystem(sb, 1); |
| 69 | } | 67 | } |
| 70 | EXPORT_SYMBOL_GPL(sync_filesystem); | 68 | EXPORT_SYMBOL_GPL(sync_filesystem); |
| 71 | 69 | ||
| 72 | static void sync_inodes_one_sb(struct super_block *sb, void *arg) | 70 | static void sync_inodes_one_sb(struct super_block *sb, void *arg) |
| 73 | { | 71 | { |
| 74 | if (!(sb->s_flags & MS_RDONLY)) | 72 | if (!(sb->s_flags & MS_RDONLY)) |
| 75 | sync_inodes_sb(sb, *((unsigned long *)arg)); | 73 | sync_inodes_sb(sb); |
| 76 | } | 74 | } |
| 77 | 75 | ||
| 78 | static void sync_fs_one_sb(struct super_block *sb, void *arg) | 76 | static void sync_fs_one_sb(struct super_block *sb, void *arg) |
| @@ -104,10 +102,9 @@ static void fdatawait_one_bdev(struct block_device *bdev, void *arg) | |||
| 104 | SYSCALL_DEFINE0(sync) | 102 | SYSCALL_DEFINE0(sync) |
| 105 | { | 103 | { |
| 106 | int nowait = 0, wait = 1; | 104 | int nowait = 0, wait = 1; |
| 107 | unsigned long start = jiffies; | ||
| 108 | 105 | ||
| 109 | wakeup_flusher_threads(0, WB_REASON_SYNC); | 106 | wakeup_flusher_threads(0, WB_REASON_SYNC); |
| 110 | iterate_supers(sync_inodes_one_sb, &start); | 107 | iterate_supers(sync_inodes_one_sb, NULL); |
| 111 | iterate_supers(sync_fs_one_sb, &nowait); | 108 | iterate_supers(sync_fs_one_sb, &nowait); |
| 112 | iterate_supers(sync_fs_one_sb, &wait); | 109 | iterate_supers(sync_fs_one_sb, &wait); |
| 113 | iterate_bdevs(fdatawrite_one_bdev, NULL); | 110 | iterate_bdevs(fdatawrite_one_bdev, NULL); |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 6211230814fd..3eaf5c6622eb 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
| @@ -27,6 +27,7 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, | |||
| 27 | { | 27 | { |
| 28 | struct dentry *root; | 28 | struct dentry *root; |
| 29 | void *ns; | 29 | void *ns; |
| 30 | bool new_sb; | ||
| 30 | 31 | ||
| 31 | if (!(flags & MS_KERNMOUNT)) { | 32 | if (!(flags & MS_KERNMOUNT)) { |
| 32 | if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type)) | 33 | if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type)) |
| @@ -37,8 +38,8 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type, | |||
| 37 | } | 38 | } |
| 38 | 39 | ||
| 39 | ns = kobj_ns_grab_current(KOBJ_NS_TYPE_NET); | 40 | ns = kobj_ns_grab_current(KOBJ_NS_TYPE_NET); |
| 40 | root = kernfs_mount_ns(fs_type, flags, sysfs_root, ns); | 41 | root = kernfs_mount_ns(fs_type, flags, sysfs_root, &new_sb, ns); |
| 41 | if (IS_ERR(root)) | 42 | if (IS_ERR(root) || !new_sb) |
| 42 | kobj_ns_drop(KOBJ_NS_TYPE_NET, ns); | 43 | kobj_ns_drop(KOBJ_NS_TYPE_NET, ns); |
| 43 | return root; | 44 | return root; |
| 44 | } | 45 | } |
diff --git a/fs/udf/file.c b/fs/udf/file.c index c02a27a19c6d..1037637957c7 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
| @@ -144,6 +144,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 144 | size_t count = iocb->ki_nbytes; | 144 | size_t count = iocb->ki_nbytes; |
| 145 | struct udf_inode_info *iinfo = UDF_I(inode); | 145 | struct udf_inode_info *iinfo = UDF_I(inode); |
| 146 | 146 | ||
| 147 | mutex_lock(&inode->i_mutex); | ||
| 147 | down_write(&iinfo->i_data_sem); | 148 | down_write(&iinfo->i_data_sem); |
| 148 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | 149 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { |
| 149 | if (file->f_flags & O_APPEND) | 150 | if (file->f_flags & O_APPEND) |
| @@ -156,6 +157,7 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 156 | pos + count)) { | 157 | pos + count)) { |
| 157 | err = udf_expand_file_adinicb(inode); | 158 | err = udf_expand_file_adinicb(inode); |
| 158 | if (err) { | 159 | if (err) { |
| 160 | mutex_unlock(&inode->i_mutex); | ||
| 159 | udf_debug("udf_expand_adinicb: err=%d\n", err); | 161 | udf_debug("udf_expand_adinicb: err=%d\n", err); |
| 160 | return err; | 162 | return err; |
| 161 | } | 163 | } |
| @@ -169,9 +171,17 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 169 | } else | 171 | } else |
| 170 | up_write(&iinfo->i_data_sem); | 172 | up_write(&iinfo->i_data_sem); |
| 171 | 173 | ||
| 172 | retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); | 174 | retval = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos); |
| 173 | if (retval > 0) | 175 | mutex_unlock(&inode->i_mutex); |
| 176 | |||
| 177 | if (retval > 0) { | ||
| 178 | ssize_t err; | ||
| 179 | |||
| 174 | mark_inode_dirty(inode); | 180 | mark_inode_dirty(inode); |
| 181 | err = generic_write_sync(file, iocb->ki_pos - retval, retval); | ||
| 182 | if (err < 0) | ||
| 183 | retval = err; | ||
| 184 | } | ||
| 175 | 185 | ||
| 176 | return retval; | 186 | return retval; |
| 177 | } | 187 | } |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 062b7925bca0..982ce05c87ed 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
| @@ -265,6 +265,7 @@ int udf_expand_file_adinicb(struct inode *inode) | |||
| 265 | .nr_to_write = 1, | 265 | .nr_to_write = 1, |
| 266 | }; | 266 | }; |
| 267 | 267 | ||
| 268 | WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex)); | ||
| 268 | if (!iinfo->i_lenAlloc) { | 269 | if (!iinfo->i_lenAlloc) { |
| 269 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) | 270 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) |
| 270 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; | 271 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT; |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index f317488263dd..d971f4932b5d 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
| @@ -913,7 +913,7 @@ xfs_flush_inodes( | |||
| 913 | struct super_block *sb = mp->m_super; | 913 | struct super_block *sb = mp->m_super; |
| 914 | 914 | ||
| 915 | if (down_read_trylock(&sb->s_umount)) { | 915 | if (down_read_trylock(&sb->s_umount)) { |
| 916 | sync_inodes_sb(sb, jiffies); | 916 | sync_inodes_sb(sb); |
| 917 | up_read(&sb->s_umount); | 917 | up_read(&sb->s_umount); |
| 918 | } | 918 | } |
| 919 | } | 919 | } |
