diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_globals.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_icache.c | 29 | ||||
-rw-r--r-- | fs/xfs/xfs_icache.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_linux.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_mount.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_sysctl.c | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_sysctl.h | 1 |
9 files changed, 58 insertions, 1 deletions
diff --git a/fs/xfs/xfs_globals.c b/fs/xfs/xfs_globals.c index 76e81cff70b9..5399ef222dd7 100644 --- a/fs/xfs/xfs_globals.c +++ b/fs/xfs/xfs_globals.c | |||
@@ -21,7 +21,8 @@ | |||
21 | /* | 21 | /* |
22 | * Tunable XFS parameters. xfs_params is required even when CONFIG_SYSCTL=n, | 22 | * Tunable XFS parameters. xfs_params is required even when CONFIG_SYSCTL=n, |
23 | * other XFS code uses these values. Times are measured in centisecs (i.e. | 23 | * other XFS code uses these values. Times are measured in centisecs (i.e. |
24 | * 100ths of a second). | 24 | * 100ths of a second) with the exception of eofb_timer, which is measured in |
25 | * seconds. | ||
25 | */ | 26 | */ |
26 | xfs_param_t xfs_params = { | 27 | xfs_param_t xfs_params = { |
27 | /* MIN DFLT MAX */ | 28 | /* MIN DFLT MAX */ |
@@ -40,4 +41,5 @@ xfs_param_t xfs_params = { | |||
40 | .rotorstep = { 1, 1, 255 }, | 41 | .rotorstep = { 1, 1, 255 }, |
41 | .inherit_nodfrg = { 0, 1, 1 }, | 42 | .inherit_nodfrg = { 0, 1, 1 }, |
42 | .fstrm_timer = { 1, 30*100, 3600*100}, | 43 | .fstrm_timer = { 1, 30*100, 3600*100}, |
44 | .eofb_timer = { 1, 300, 3600*24}, | ||
43 | }; | 45 | }; |
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 906e6dcd2c55..96e344e3e927 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c | |||
@@ -615,6 +615,32 @@ restart: | |||
615 | return last_error; | 615 | return last_error; |
616 | } | 616 | } |
617 | 617 | ||
618 | /* | ||
619 | * Background scanning to trim post-EOF preallocated space. This is queued | ||
620 | * based on the 'background_prealloc_discard_period' tunable (5m by default). | ||
621 | */ | ||
622 | STATIC void | ||
623 | xfs_queue_eofblocks( | ||
624 | struct xfs_mount *mp) | ||
625 | { | ||
626 | rcu_read_lock(); | ||
627 | if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_EOFBLOCKS_TAG)) | ||
628 | queue_delayed_work(mp->m_eofblocks_workqueue, | ||
629 | &mp->m_eofblocks_work, | ||
630 | msecs_to_jiffies(xfs_eofb_secs * 1000)); | ||
631 | rcu_read_unlock(); | ||
632 | } | ||
633 | |||
634 | void | ||
635 | xfs_eofblocks_worker( | ||
636 | struct work_struct *work) | ||
637 | { | ||
638 | struct xfs_mount *mp = container_of(to_delayed_work(work), | ||
639 | struct xfs_mount, m_eofblocks_work); | ||
640 | xfs_icache_free_eofblocks(mp, NULL); | ||
641 | xfs_queue_eofblocks(mp); | ||
642 | } | ||
643 | |||
618 | int | 644 | int |
619 | xfs_inode_ag_iterator( | 645 | xfs_inode_ag_iterator( |
620 | struct xfs_mount *mp, | 646 | struct xfs_mount *mp, |
@@ -1273,6 +1299,9 @@ xfs_inode_set_eofblocks_tag( | |||
1273 | XFS_ICI_EOFBLOCKS_TAG); | 1299 | XFS_ICI_EOFBLOCKS_TAG); |
1274 | spin_unlock(&ip->i_mount->m_perag_lock); | 1300 | spin_unlock(&ip->i_mount->m_perag_lock); |
1275 | 1301 | ||
1302 | /* kick off background trimming */ | ||
1303 | xfs_queue_eofblocks(ip->i_mount); | ||
1304 | |||
1276 | trace_xfs_perag_set_eofblocks(ip->i_mount, pag->pag_agno, | 1305 | trace_xfs_perag_set_eofblocks(ip->i_mount, pag->pag_agno, |
1277 | -1, _RET_IP_); | 1306 | -1, _RET_IP_); |
1278 | } | 1307 | } |
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index 4934a77024cf..e0f138c70a2f 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h | |||
@@ -38,6 +38,7 @@ void xfs_inode_set_reclaim_tag(struct xfs_inode *ip); | |||
38 | void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip); | 38 | void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip); |
39 | void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip); | 39 | void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip); |
40 | int xfs_icache_free_eofblocks(struct xfs_mount *, struct xfs_eofblocks *); | 40 | int xfs_icache_free_eofblocks(struct xfs_mount *, struct xfs_eofblocks *); |
41 | void xfs_eofblocks_worker(struct work_struct *); | ||
41 | 42 | ||
42 | int xfs_sync_inode_grab(struct xfs_inode *ip); | 43 | int xfs_sync_inode_grab(struct xfs_inode *ip); |
43 | int xfs_inode_ag_iterator(struct xfs_mount *mp, | 44 | int xfs_inode_ag_iterator(struct xfs_mount *mp, |
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index 828662f70d64..0a134ca5211c 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h | |||
@@ -118,6 +118,7 @@ | |||
118 | #define xfs_rotorstep xfs_params.rotorstep.val | 118 | #define xfs_rotorstep xfs_params.rotorstep.val |
119 | #define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val | 119 | #define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val |
120 | #define xfs_fstrm_centisecs xfs_params.fstrm_timer.val | 120 | #define xfs_fstrm_centisecs xfs_params.fstrm_timer.val |
121 | #define xfs_eofb_secs xfs_params.eofb_timer.val | ||
121 | 122 | ||
122 | #define current_cpu() (raw_smp_processor_id()) | 123 | #define current_cpu() (raw_smp_processor_id()) |
123 | #define current_pid() (current->pid) | 124 | #define current_pid() (current->pid) |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 6f1c997704cd..41ae7e1590f5 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -1428,6 +1428,8 @@ xfs_unmountfs( | |||
1428 | __uint64_t resblks; | 1428 | __uint64_t resblks; |
1429 | int error; | 1429 | int error; |
1430 | 1430 | ||
1431 | cancel_delayed_work_sync(&mp->m_eofblocks_work); | ||
1432 | |||
1431 | xfs_qm_unmount_quotas(mp); | 1433 | xfs_qm_unmount_quotas(mp); |
1432 | xfs_rtunmount_inodes(mp); | 1434 | xfs_rtunmount_inodes(mp); |
1433 | IRELE(mp->m_rootip); | 1435 | IRELE(mp->m_rootip); |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index a631ca3b9065..dc306a09f56f 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -196,6 +196,8 @@ typedef struct xfs_mount { | |||
196 | #endif | 196 | #endif |
197 | struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ | 197 | struct xfs_mru_cache *m_filestream; /* per-mount filestream data */ |
198 | struct delayed_work m_reclaim_work; /* background inode reclaim */ | 198 | struct delayed_work m_reclaim_work; /* background inode reclaim */ |
199 | struct delayed_work m_eofblocks_work; /* background eof blocks | ||
200 | trimming */ | ||
199 | __int64_t m_update_flags; /* sb flags we need to update | 201 | __int64_t m_update_flags; /* sb flags we need to update |
200 | on the next remount,rw */ | 202 | on the next remount,rw */ |
201 | struct shrinker m_inode_shrink; /* inode reclaim shrinker */ | 203 | struct shrinker m_inode_shrink; /* inode reclaim shrinker */ |
@@ -207,6 +209,7 @@ typedef struct xfs_mount { | |||
207 | struct workqueue_struct *m_cil_workqueue; | 209 | struct workqueue_struct *m_cil_workqueue; |
208 | struct workqueue_struct *m_reclaim_workqueue; | 210 | struct workqueue_struct *m_reclaim_workqueue; |
209 | struct workqueue_struct *m_log_workqueue; | 211 | struct workqueue_struct *m_log_workqueue; |
212 | struct workqueue_struct *m_eofblocks_workqueue; | ||
210 | } xfs_mount_t; | 213 | } xfs_mount_t; |
211 | 214 | ||
212 | /* | 215 | /* |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 3d9ea947e9f8..ab8839b26272 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -874,8 +874,15 @@ xfs_init_mount_workqueues( | |||
874 | if (!mp->m_log_workqueue) | 874 | if (!mp->m_log_workqueue) |
875 | goto out_destroy_reclaim; | 875 | goto out_destroy_reclaim; |
876 | 876 | ||
877 | mp->m_eofblocks_workqueue = alloc_workqueue("xfs-eofblocks/%s", | ||
878 | WQ_NON_REENTRANT, 0, mp->m_fsname); | ||
879 | if (!mp->m_eofblocks_workqueue) | ||
880 | goto out_destroy_log; | ||
881 | |||
877 | return 0; | 882 | return 0; |
878 | 883 | ||
884 | out_destroy_log: | ||
885 | destroy_workqueue(mp->m_log_workqueue); | ||
879 | out_destroy_reclaim: | 886 | out_destroy_reclaim: |
880 | destroy_workqueue(mp->m_reclaim_workqueue); | 887 | destroy_workqueue(mp->m_reclaim_workqueue); |
881 | out_destroy_cil: | 888 | out_destroy_cil: |
@@ -892,6 +899,7 @@ STATIC void | |||
892 | xfs_destroy_mount_workqueues( | 899 | xfs_destroy_mount_workqueues( |
893 | struct xfs_mount *mp) | 900 | struct xfs_mount *mp) |
894 | { | 901 | { |
902 | destroy_workqueue(mp->m_eofblocks_workqueue); | ||
895 | destroy_workqueue(mp->m_log_workqueue); | 903 | destroy_workqueue(mp->m_log_workqueue); |
896 | destroy_workqueue(mp->m_reclaim_workqueue); | 904 | destroy_workqueue(mp->m_reclaim_workqueue); |
897 | destroy_workqueue(mp->m_cil_workqueue); | 905 | destroy_workqueue(mp->m_cil_workqueue); |
@@ -1393,6 +1401,7 @@ xfs_fs_fill_super( | |||
1393 | mutex_init(&mp->m_growlock); | 1401 | mutex_init(&mp->m_growlock); |
1394 | atomic_set(&mp->m_active_trans, 0); | 1402 | atomic_set(&mp->m_active_trans, 0); |
1395 | INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); | 1403 | INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker); |
1404 | INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker); | ||
1396 | 1405 | ||
1397 | mp->m_super = sb; | 1406 | mp->m_super = sb; |
1398 | sb->s_fs_info = mp; | 1407 | sb->s_fs_info = mp; |
diff --git a/fs/xfs/xfs_sysctl.c b/fs/xfs/xfs_sysctl.c index ee2d2adaa438..2801b5ce6cdb 100644 --- a/fs/xfs/xfs_sysctl.c +++ b/fs/xfs/xfs_sysctl.c | |||
@@ -202,6 +202,15 @@ static ctl_table xfs_table[] = { | |||
202 | .extra1 = &xfs_params.fstrm_timer.min, | 202 | .extra1 = &xfs_params.fstrm_timer.min, |
203 | .extra2 = &xfs_params.fstrm_timer.max, | 203 | .extra2 = &xfs_params.fstrm_timer.max, |
204 | }, | 204 | }, |
205 | { | ||
206 | .procname = "speculative_prealloc_lifetime", | ||
207 | .data = &xfs_params.eofb_timer.val, | ||
208 | .maxlen = sizeof(int), | ||
209 | .mode = 0644, | ||
210 | .proc_handler = proc_dointvec_minmax, | ||
211 | .extra1 = &xfs_params.eofb_timer.min, | ||
212 | .extra2 = &xfs_params.eofb_timer.max, | ||
213 | }, | ||
205 | /* please keep this the last entry */ | 214 | /* please keep this the last entry */ |
206 | #ifdef CONFIG_PROC_FS | 215 | #ifdef CONFIG_PROC_FS |
207 | { | 216 | { |
diff --git a/fs/xfs/xfs_sysctl.h b/fs/xfs/xfs_sysctl.h index b9937d450f8e..bd8e157c20ef 100644 --- a/fs/xfs/xfs_sysctl.h +++ b/fs/xfs/xfs_sysctl.h | |||
@@ -47,6 +47,7 @@ typedef struct xfs_param { | |||
47 | xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */ | 47 | xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */ |
48 | xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */ | 48 | xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */ |
49 | xfs_sysctl_val_t fstrm_timer; /* Filestream dir-AG assoc'n timeout. */ | 49 | xfs_sysctl_val_t fstrm_timer; /* Filestream dir-AG assoc'n timeout. */ |
50 | xfs_sysctl_val_t eofb_timer; /* Interval between eofb scan wakeups */ | ||
50 | } xfs_param_t; | 51 | } xfs_param_t; |
51 | 52 | ||
52 | /* | 53 | /* |