Commit 2ebec184 authored by Nathan Scott's avatar Nathan Scott

[XFS] Merge final laptop mode patch (xfssyncd) from Bart Samwel.

SGI Modid: xfs-linux:xfs-kern:171591a
parent 26d93369
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/writeback.h>
STATIC struct quotactl_ops linvfs_qops; STATIC struct quotactl_ops linvfs_qops;
STATIC struct super_operations linvfs_sops; STATIC struct super_operations linvfs_sops;
...@@ -400,6 +401,10 @@ xfssyncd( ...@@ -400,6 +401,10 @@ xfssyncd(
if (vfsp->vfs_flag & VFS_RDONLY) if (vfsp->vfs_flag & VFS_RDONLY)
continue; continue;
VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error); VFS_SYNC(vfsp, SYNCD_FLAGS, NULL, error);
vfsp->vfs_sync_seq++;
wmb();
wake_up(&vfsp->vfs_wait_single_sync_task);
} }
vfsp->vfs_sync_task = NULL; vfsp->vfs_sync_task = NULL;
...@@ -485,6 +490,24 @@ linvfs_sync_super( ...@@ -485,6 +490,24 @@ linvfs_sync_super(
VFS_SYNC(vfsp, flags, NULL, error); VFS_SYNC(vfsp, flags, NULL, error);
sb->s_dirt = 0; sb->s_dirt = 0;
if (unlikely(laptop_mode)) {
int prev_sync_seq = vfsp->vfs_sync_seq;
/*
* The disk must be active because we're syncing.
* We schedule syncd now (now that the disk is
* active) instead of later (when it might not be).
*/
wake_up_process(vfsp->vfs_sync_task);
/*
* We have to wait for the sync iteration to complete.
* If we don't, the disk activity caused by the sync
* will come after the sync is completed, and that
* triggers another sync from laptop mode.
*/
wait_event(vfsp->vfs_wait_single_sync_task,
vfsp->vfs_sync_seq != prev_sync_seq);
}
return -error; return -error;
} }
......
...@@ -250,6 +250,7 @@ vfs_allocate( void ) ...@@ -250,6 +250,7 @@ vfs_allocate( void )
vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP); vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP);
bhv_head_init(VFS_BHVHEAD(vfsp), "vfs"); bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
init_waitqueue_head(&vfsp->vfs_wait_sync_task); init_waitqueue_head(&vfsp->vfs_wait_sync_task);
init_waitqueue_head(&vfsp->vfs_wait_single_sync_task);
return vfsp; return vfsp;
} }
......
...@@ -51,7 +51,9 @@ typedef struct vfs { ...@@ -51,7 +51,9 @@ typedef struct vfs {
xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */ xfs_fsid_t *vfs_altfsid; /* An ID fixed for life of FS */
bhv_head_t vfs_bh; /* head of vfs behavior chain */ bhv_head_t vfs_bh; /* head of vfs behavior chain */
struct super_block *vfs_super; /* Linux superblock structure */ struct super_block *vfs_super; /* Linux superblock structure */
struct task_struct *vfs_sync_task; struct task_struct *vfs_sync_task; /* xfssyncd process */
int vfs_sync_seq; /* xfssyncd generation number */
wait_queue_head_t vfs_wait_single_sync_task;
wait_queue_head_t vfs_wait_sync_task; wait_queue_head_t vfs_wait_sync_task;
} vfs_t; } vfs_t;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment