diff options
author | Ingo Molnar <mingo@elte.hu> | 2012-01-17 03:51:46 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2012-01-17 03:51:46 -0500 |
commit | 6eadf1075c6f923fece419e38cf05bff559aefcd (patch) | |
tree | b743ce0a3743d6f1b915b19b077a6d5bad980ea1 /fs | |
parent | a1c611745c8c4e8996c1877d4e5d0fc95f227c38 (diff) | |
parent | c10076c4304083af15a41f6bc5e657e781c1f9a6 (diff) |
Merge branch 'tip/perf/urgent-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace into perf/urgent
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/async-thread.c | 3 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 9 | ||||
-rw-r--r-- | fs/ceph/dir.c | 29 | ||||
-rw-r--r-- | fs/cifs/connect.c | 4 | ||||
-rw-r--r-- | fs/fs-writeback.c | 11 | ||||
-rw-r--r-- | fs/locks.c | 11 | ||||
-rw-r--r-- | fs/minix/inode.c | 34 | ||||
-rw-r--r-- | fs/proc/stat.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 30 | ||||
-rw-r--r-- | fs/xfs/xfs_sync.c | 36 | ||||
-rw-r--r-- | fs/xfs/xfs_sync.h | 2 |
11 files changed, 77 insertions, 96 deletions
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index cb97174e2366..0b394580d860 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c | |||
@@ -563,8 +563,8 @@ static struct btrfs_worker_thread *find_worker(struct btrfs_workers *workers) | |||
563 | struct list_head *fallback; | 563 | struct list_head *fallback; |
564 | int ret; | 564 | int ret; |
565 | 565 | ||
566 | again: | ||
567 | spin_lock_irqsave(&workers->lock, flags); | 566 | spin_lock_irqsave(&workers->lock, flags); |
567 | again: | ||
568 | worker = next_worker(workers); | 568 | worker = next_worker(workers); |
569 | 569 | ||
570 | if (!worker) { | 570 | if (!worker) { |
@@ -579,6 +579,7 @@ again: | |||
579 | spin_unlock_irqrestore(&workers->lock, flags); | 579 | spin_unlock_irqrestore(&workers->lock, flags); |
580 | /* we're below the limit, start another worker */ | 580 | /* we're below the limit, start another worker */ |
581 | ret = __btrfs_start_workers(workers); | 581 | ret = __btrfs_start_workers(workers); |
582 | spin_lock_irqsave(&workers->lock, flags); | ||
582 | if (ret) | 583 | if (ret) |
583 | goto fallback; | 584 | goto fallback; |
584 | goto again; | 585 | goto again; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 0a6b928813a4..fd1a06df5bc6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -4590,10 +4590,6 @@ static int btrfs_add_nondir(struct btrfs_trans_handle *trans, | |||
4590 | int err = btrfs_add_link(trans, dir, inode, | 4590 | int err = btrfs_add_link(trans, dir, inode, |
4591 | dentry->d_name.name, dentry->d_name.len, | 4591 | dentry->d_name.name, dentry->d_name.len, |
4592 | backref, index); | 4592 | backref, index); |
4593 | if (!err) { | ||
4594 | d_instantiate(dentry, inode); | ||
4595 | return 0; | ||
4596 | } | ||
4597 | if (err > 0) | 4593 | if (err > 0) |
4598 | err = -EEXIST; | 4594 | err = -EEXIST; |
4599 | return err; | 4595 | return err; |
@@ -4655,6 +4651,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
4655 | else { | 4651 | else { |
4656 | init_special_inode(inode, inode->i_mode, rdev); | 4652 | init_special_inode(inode, inode->i_mode, rdev); |
4657 | btrfs_update_inode(trans, root, inode); | 4653 | btrfs_update_inode(trans, root, inode); |
4654 | d_instantiate(dentry, inode); | ||
4658 | } | 4655 | } |
4659 | out_unlock: | 4656 | out_unlock: |
4660 | nr = trans->blocks_used; | 4657 | nr = trans->blocks_used; |
@@ -4722,6 +4719,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
4722 | inode->i_mapping->a_ops = &btrfs_aops; | 4719 | inode->i_mapping->a_ops = &btrfs_aops; |
4723 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; | 4720 | inode->i_mapping->backing_dev_info = &root->fs_info->bdi; |
4724 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; | 4721 | BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops; |
4722 | d_instantiate(dentry, inode); | ||
4725 | } | 4723 | } |
4726 | out_unlock: | 4724 | out_unlock: |
4727 | nr = trans->blocks_used; | 4725 | nr = trans->blocks_used; |
@@ -4779,6 +4777,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
4779 | struct dentry *parent = dentry->d_parent; | 4777 | struct dentry *parent = dentry->d_parent; |
4780 | err = btrfs_update_inode(trans, root, inode); | 4778 | err = btrfs_update_inode(trans, root, inode); |
4781 | BUG_ON(err); | 4779 | BUG_ON(err); |
4780 | d_instantiate(dentry, inode); | ||
4782 | btrfs_log_new_name(trans, inode, NULL, parent); | 4781 | btrfs_log_new_name(trans, inode, NULL, parent); |
4783 | } | 4782 | } |
4784 | 4783 | ||
@@ -7245,6 +7244,8 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
7245 | drop_inode = 1; | 7244 | drop_inode = 1; |
7246 | 7245 | ||
7247 | out_unlock: | 7246 | out_unlock: |
7247 | if (!err) | ||
7248 | d_instantiate(dentry, inode); | ||
7248 | nr = trans->blocks_used; | 7249 | nr = trans->blocks_used; |
7249 | btrfs_end_transaction_throttle(trans, root); | 7250 | btrfs_end_transaction_throttle(trans, root); |
7250 | if (drop_inode) { | 7251 | if (drop_inode) { |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 3eeb97661262..98954003a8d3 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -1094,42 +1094,19 @@ static int ceph_snapdir_d_revalidate(struct dentry *dentry, | |||
1094 | /* | 1094 | /* |
1095 | * Set/clear/test dir complete flag on the dir's dentry. | 1095 | * Set/clear/test dir complete flag on the dir's dentry. |
1096 | */ | 1096 | */ |
1097 | static struct dentry * __d_find_any_alias(struct inode *inode) | ||
1098 | { | ||
1099 | struct dentry *alias; | ||
1100 | |||
1101 | if (list_empty(&inode->i_dentry)) | ||
1102 | return NULL; | ||
1103 | alias = list_first_entry(&inode->i_dentry, struct dentry, d_alias); | ||
1104 | return alias; | ||
1105 | } | ||
1106 | |||
1107 | void ceph_dir_set_complete(struct inode *inode) | 1097 | void ceph_dir_set_complete(struct inode *inode) |
1108 | { | 1098 | { |
1109 | struct dentry *dentry = __d_find_any_alias(inode); | 1099 | /* not yet implemented */ |
1110 | |||
1111 | if (dentry && ceph_dentry(dentry)) { | ||
1112 | dout(" marking %p (%p) complete\n", inode, dentry); | ||
1113 | set_bit(CEPH_D_COMPLETE, &ceph_dentry(dentry)->flags); | ||
1114 | } | ||
1115 | } | 1100 | } |
1116 | 1101 | ||
1117 | void ceph_dir_clear_complete(struct inode *inode) | 1102 | void ceph_dir_clear_complete(struct inode *inode) |
1118 | { | 1103 | { |
1119 | struct dentry *dentry = __d_find_any_alias(inode); | 1104 | /* not yet implemented */ |
1120 | |||
1121 | if (dentry && ceph_dentry(dentry)) { | ||
1122 | dout(" marking %p (%p) NOT complete\n", inode, dentry); | ||
1123 | clear_bit(CEPH_D_COMPLETE, &ceph_dentry(dentry)->flags); | ||
1124 | } | ||
1125 | } | 1105 | } |
1126 | 1106 | ||
1127 | bool ceph_dir_test_complete(struct inode *inode) | 1107 | bool ceph_dir_test_complete(struct inode *inode) |
1128 | { | 1108 | { |
1129 | struct dentry *dentry = __d_find_any_alias(inode); | 1109 | /* not yet implemented */ |
1130 | |||
1131 | if (dentry && ceph_dentry(dentry)) | ||
1132 | return test_bit(CEPH_D_COMPLETE, &ceph_dentry(dentry)->flags); | ||
1133 | return false; | 1110 | return false; |
1134 | } | 1111 | } |
1135 | 1112 | ||
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 8cd4b52d4217..f3670cf72587 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -282,7 +282,7 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB) | |||
282 | byte_count = be32_to_cpu(pTargetSMB->smb_buf_length); | 282 | byte_count = be32_to_cpu(pTargetSMB->smb_buf_length); |
283 | byte_count += total_in_buf2; | 283 | byte_count += total_in_buf2; |
284 | /* don't allow buffer to overflow */ | 284 | /* don't allow buffer to overflow */ |
285 | if (byte_count > CIFSMaxBufSize) | 285 | if (byte_count > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) |
286 | return -ENOBUFS; | 286 | return -ENOBUFS; |
287 | pTargetSMB->smb_buf_length = cpu_to_be32(byte_count); | 287 | pTargetSMB->smb_buf_length = cpu_to_be32(byte_count); |
288 | 288 | ||
@@ -2122,7 +2122,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) | |||
2122 | warned_on_ntlm = true; | 2122 | warned_on_ntlm = true; |
2123 | cERROR(1, "default security mechanism requested. The default " | 2123 | cERROR(1, "default security mechanism requested. The default " |
2124 | "security mechanism will be upgraded from ntlm to " | 2124 | "security mechanism will be upgraded from ntlm to " |
2125 | "ntlmv2 in kernel release 3.2"); | 2125 | "ntlmv2 in kernel release 3.3"); |
2126 | } | 2126 | } |
2127 | ses->overrideSecFlg = volume_info->secFlg; | 2127 | ses->overrideSecFlg = volume_info->secFlg; |
2128 | 2128 | ||
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index ac86f8b3e3cb..517f211a3bd4 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -47,17 +47,6 @@ struct wb_writeback_work { | |||
47 | struct completion *done; /* set if the caller waits */ | 47 | struct completion *done; /* set if the caller waits */ |
48 | }; | 48 | }; |
49 | 49 | ||
50 | const char *wb_reason_name[] = { | ||
51 | [WB_REASON_BACKGROUND] = "background", | ||
52 | [WB_REASON_TRY_TO_FREE_PAGES] = "try_to_free_pages", | ||
53 | [WB_REASON_SYNC] = "sync", | ||
54 | [WB_REASON_PERIODIC] = "periodic", | ||
55 | [WB_REASON_LAPTOP_TIMER] = "laptop_timer", | ||
56 | [WB_REASON_FREE_MORE_MEM] = "free_more_memory", | ||
57 | [WB_REASON_FS_FREE_SPACE] = "fs_free_space", | ||
58 | [WB_REASON_FORKER_THREAD] = "forker_thread" | ||
59 | }; | ||
60 | |||
61 | /* | 50 | /* |
62 | * Include the creation of the trace points after defining the | 51 | * Include the creation of the trace points after defining the |
63 | * wb_writeback_work structure so that the definition remains local to this | 52 | * wb_writeback_work structure so that the definition remains local to this |
diff --git a/fs/locks.c b/fs/locks.c index 3b0d05dcd7c1..637694bf3a03 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1205,6 +1205,8 @@ int __break_lease(struct inode *inode, unsigned int mode) | |||
1205 | int want_write = (mode & O_ACCMODE) != O_RDONLY; | 1205 | int want_write = (mode & O_ACCMODE) != O_RDONLY; |
1206 | 1206 | ||
1207 | new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK); | 1207 | new_fl = lease_alloc(NULL, want_write ? F_WRLCK : F_RDLCK); |
1208 | if (IS_ERR(new_fl)) | ||
1209 | return PTR_ERR(new_fl); | ||
1208 | 1210 | ||
1209 | lock_flocks(); | 1211 | lock_flocks(); |
1210 | 1212 | ||
@@ -1221,12 +1223,6 @@ int __break_lease(struct inode *inode, unsigned int mode) | |||
1221 | if (fl->fl_owner == current->files) | 1223 | if (fl->fl_owner == current->files) |
1222 | i_have_this_lease = 1; | 1224 | i_have_this_lease = 1; |
1223 | 1225 | ||
1224 | if (IS_ERR(new_fl) && !i_have_this_lease | ||
1225 | && ((mode & O_NONBLOCK) == 0)) { | ||
1226 | error = PTR_ERR(new_fl); | ||
1227 | goto out; | ||
1228 | } | ||
1229 | |||
1230 | break_time = 0; | 1226 | break_time = 0; |
1231 | if (lease_break_time > 0) { | 1227 | if (lease_break_time > 0) { |
1232 | break_time = jiffies + lease_break_time * HZ; | 1228 | break_time = jiffies + lease_break_time * HZ; |
@@ -1284,8 +1280,7 @@ restart: | |||
1284 | 1280 | ||
1285 | out: | 1281 | out: |
1286 | unlock_flocks(); | 1282 | unlock_flocks(); |
1287 | if (!IS_ERR(new_fl)) | 1283 | locks_free_lock(new_fl); |
1288 | locks_free_lock(new_fl); | ||
1289 | return error; | 1284 | return error; |
1290 | } | 1285 | } |
1291 | 1286 | ||
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 1d9e33966db0..4d46a6a59070 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
@@ -263,23 +263,6 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) | |||
263 | goto out_no_root; | 263 | goto out_no_root; |
264 | } | 264 | } |
265 | 265 | ||
266 | ret = -ENOMEM; | ||
267 | s->s_root = d_alloc_root(root_inode); | ||
268 | if (!s->s_root) | ||
269 | goto out_iput; | ||
270 | |||
271 | if (!(s->s_flags & MS_RDONLY)) { | ||
272 | if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ | ||
273 | ms->s_state &= ~MINIX_VALID_FS; | ||
274 | mark_buffer_dirty(bh); | ||
275 | } | ||
276 | if (!(sbi->s_mount_state & MINIX_VALID_FS)) | ||
277 | printk("MINIX-fs: mounting unchecked file system, " | ||
278 | "running fsck is recommended\n"); | ||
279 | else if (sbi->s_mount_state & MINIX_ERROR_FS) | ||
280 | printk("MINIX-fs: mounting file system with errors, " | ||
281 | "running fsck is recommended\n"); | ||
282 | |||
283 | /* Apparently minix can create filesystems that allocate more blocks for | 266 | /* Apparently minix can create filesystems that allocate more blocks for |
284 | * the bitmaps than needed. We simply ignore that, but verify it didn't | 267 | * the bitmaps than needed. We simply ignore that, but verify it didn't |
285 | * create one with not enough blocks and bail out if so. | 268 | * create one with not enough blocks and bail out if so. |
@@ -300,6 +283,23 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) | |||
300 | goto out_iput; | 283 | goto out_iput; |
301 | } | 284 | } |
302 | 285 | ||
286 | ret = -ENOMEM; | ||
287 | s->s_root = d_alloc_root(root_inode); | ||
288 | if (!s->s_root) | ||
289 | goto out_iput; | ||
290 | |||
291 | if (!(s->s_flags & MS_RDONLY)) { | ||
292 | if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ | ||
293 | ms->s_state &= ~MINIX_VALID_FS; | ||
294 | mark_buffer_dirty(bh); | ||
295 | } | ||
296 | if (!(sbi->s_mount_state & MINIX_VALID_FS)) | ||
297 | printk("MINIX-fs: mounting unchecked file system, " | ||
298 | "running fsck is recommended\n"); | ||
299 | else if (sbi->s_mount_state & MINIX_ERROR_FS) | ||
300 | printk("MINIX-fs: mounting file system with errors, " | ||
301 | "running fsck is recommended\n"); | ||
302 | |||
303 | return 0; | 303 | return 0; |
304 | 304 | ||
305 | out_iput: | 305 | out_iput: |
diff --git a/fs/proc/stat.c b/fs/proc/stat.c index 2a30d67dd6b8..0855e6f20391 100644 --- a/fs/proc/stat.c +++ b/fs/proc/stat.c | |||
@@ -32,7 +32,7 @@ static cputime64_t get_idle_time(int cpu) | |||
32 | idle = kstat_cpu(cpu).cpustat.idle; | 32 | idle = kstat_cpu(cpu).cpustat.idle; |
33 | idle = cputime64_add(idle, arch_idle_time(cpu)); | 33 | idle = cputime64_add(idle, arch_idle_time(cpu)); |
34 | } else | 34 | } else |
35 | idle = nsecs_to_jiffies64(1000 * idle_time); | 35 | idle = usecs_to_cputime64(idle_time); |
36 | 36 | ||
37 | return idle; | 37 | return idle; |
38 | } | 38 | } |
@@ -46,7 +46,7 @@ static cputime64_t get_iowait_time(int cpu) | |||
46 | /* !NO_HZ so we can rely on cpustat.iowait */ | 46 | /* !NO_HZ so we can rely on cpustat.iowait */ |
47 | iowait = kstat_cpu(cpu).cpustat.iowait; | 47 | iowait = kstat_cpu(cpu).cpustat.iowait; |
48 | else | 48 | else |
49 | iowait = nsecs_to_jiffies64(1000 * iowait_time); | 49 | iowait = usecs_to_cputime64(iowait_time); |
50 | 50 | ||
51 | return iowait; | 51 | return iowait; |
52 | } | 52 | } |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 3eca58f51ae9..8a899496fd5f 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -869,27 +869,6 @@ xfs_fs_dirty_inode( | |||
869 | } | 869 | } |
870 | 870 | ||
871 | STATIC int | 871 | STATIC int |
872 | xfs_log_inode( | ||
873 | struct xfs_inode *ip) | ||
874 | { | ||
875 | struct xfs_mount *mp = ip->i_mount; | ||
876 | struct xfs_trans *tp; | ||
877 | int error; | ||
878 | |||
879 | tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); | ||
880 | error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); | ||
881 | if (error) { | ||
882 | xfs_trans_cancel(tp, 0); | ||
883 | return error; | ||
884 | } | ||
885 | |||
886 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
887 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
888 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
889 | return xfs_trans_commit(tp, 0); | ||
890 | } | ||
891 | |||
892 | STATIC int | ||
893 | xfs_fs_write_inode( | 872 | xfs_fs_write_inode( |
894 | struct inode *inode, | 873 | struct inode *inode, |
895 | struct writeback_control *wbc) | 874 | struct writeback_control *wbc) |
@@ -902,10 +881,8 @@ xfs_fs_write_inode( | |||
902 | 881 | ||
903 | if (XFS_FORCED_SHUTDOWN(mp)) | 882 | if (XFS_FORCED_SHUTDOWN(mp)) |
904 | return -XFS_ERROR(EIO); | 883 | return -XFS_ERROR(EIO); |
905 | if (!ip->i_update_core) | ||
906 | return 0; | ||
907 | 884 | ||
908 | if (wbc->sync_mode == WB_SYNC_ALL) { | 885 | if (wbc->sync_mode == WB_SYNC_ALL || wbc->for_kupdate) { |
909 | /* | 886 | /* |
910 | * Make sure the inode has made it it into the log. Instead | 887 | * Make sure the inode has made it it into the log. Instead |
911 | * of forcing it all the way to stable storage using a | 888 | * of forcing it all the way to stable storage using a |
@@ -913,11 +890,14 @@ xfs_fs_write_inode( | |||
913 | * ->sync_fs call do that for thus, which reduces the number | 890 | * ->sync_fs call do that for thus, which reduces the number |
914 | * of synchronous log forces dramatically. | 891 | * of synchronous log forces dramatically. |
915 | */ | 892 | */ |
916 | error = xfs_log_inode(ip); | 893 | error = xfs_log_dirty_inode(ip, NULL, 0); |
917 | if (error) | 894 | if (error) |
918 | goto out; | 895 | goto out; |
919 | return 0; | 896 | return 0; |
920 | } else { | 897 | } else { |
898 | if (!ip->i_update_core) | ||
899 | return 0; | ||
900 | |||
921 | /* | 901 | /* |
922 | * We make this non-blocking if the inode is contended, return | 902 | * We make this non-blocking if the inode is contended, return |
923 | * EAGAIN to indicate to the caller that they did not succeed. | 903 | * EAGAIN to indicate to the caller that they did not succeed. |
diff --git a/fs/xfs/xfs_sync.c b/fs/xfs/xfs_sync.c index be5c51d8f757..f0994aedcd15 100644 --- a/fs/xfs/xfs_sync.c +++ b/fs/xfs/xfs_sync.c | |||
@@ -336,6 +336,32 @@ xfs_sync_fsdata( | |||
336 | return error; | 336 | return error; |
337 | } | 337 | } |
338 | 338 | ||
339 | int | ||
340 | xfs_log_dirty_inode( | ||
341 | struct xfs_inode *ip, | ||
342 | struct xfs_perag *pag, | ||
343 | int flags) | ||
344 | { | ||
345 | struct xfs_mount *mp = ip->i_mount; | ||
346 | struct xfs_trans *tp; | ||
347 | int error; | ||
348 | |||
349 | if (!ip->i_update_core) | ||
350 | return 0; | ||
351 | |||
352 | tp = xfs_trans_alloc(mp, XFS_TRANS_FSYNC_TS); | ||
353 | error = xfs_trans_reserve(tp, 0, XFS_FSYNC_TS_LOG_RES(mp), 0, 0, 0); | ||
354 | if (error) { | ||
355 | xfs_trans_cancel(tp, 0); | ||
356 | return error; | ||
357 | } | ||
358 | |||
359 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
360 | xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); | ||
361 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
362 | return xfs_trans_commit(tp, 0); | ||
363 | } | ||
364 | |||
339 | /* | 365 | /* |
340 | * When remounting a filesystem read-only or freezing the filesystem, we have | 366 | * When remounting a filesystem read-only or freezing the filesystem, we have |
341 | * two phases to execute. This first phase is syncing the data before we | 367 | * two phases to execute. This first phase is syncing the data before we |
@@ -359,6 +385,16 @@ xfs_quiesce_data( | |||
359 | { | 385 | { |
360 | int error, error2 = 0; | 386 | int error, error2 = 0; |
361 | 387 | ||
388 | /* | ||
389 | * Log all pending size and timestamp updates. The vfs writeback | ||
390 | * code is supposed to do this, but due to its overagressive | ||
391 | * livelock detection it will skip inodes where appending writes | ||
392 | * were written out in the first non-blocking sync phase if their | ||
393 | * completion took long enough that it happened after taking the | ||
394 | * timestamp for the cut-off in the blocking phase. | ||
395 | */ | ||
396 | xfs_inode_ag_iterator(mp, xfs_log_dirty_inode, 0); | ||
397 | |||
362 | xfs_qm_sync(mp, SYNC_TRYLOCK); | 398 | xfs_qm_sync(mp, SYNC_TRYLOCK); |
363 | xfs_qm_sync(mp, SYNC_WAIT); | 399 | xfs_qm_sync(mp, SYNC_WAIT); |
364 | 400 | ||
diff --git a/fs/xfs/xfs_sync.h b/fs/xfs/xfs_sync.h index 941202e7ac6e..fa965479d788 100644 --- a/fs/xfs/xfs_sync.h +++ b/fs/xfs/xfs_sync.h | |||
@@ -34,6 +34,8 @@ void xfs_quiesce_attr(struct xfs_mount *mp); | |||
34 | 34 | ||
35 | void xfs_flush_inodes(struct xfs_inode *ip); | 35 | void xfs_flush_inodes(struct xfs_inode *ip); |
36 | 36 | ||
37 | int xfs_log_dirty_inode(struct xfs_inode *ip, struct xfs_perag *pag, int flags); | ||
38 | |||
37 | int xfs_reclaim_inodes(struct xfs_mount *mp, int mode); | 39 | int xfs_reclaim_inodes(struct xfs_mount *mp, int mode); |
38 | int xfs_reclaim_inodes_count(struct xfs_mount *mp); | 40 | int xfs_reclaim_inodes_count(struct xfs_mount *mp); |
39 | void xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan); | 41 | void xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan); |