xfs
[Top] [All Lists]

[patch 2/2] From: Bart Samwel <bart@xxxxxxxxx>

To: linux-xfs@xxxxxxxxxxx
Subject: [patch 2/2] From: Bart Samwel <bart@xxxxxxxxx>
From: bart@xxxxxxxxx
Date: Sat, 03 Apr 2004 15:36:15 +0200
Sender: linux-xfs-bounce@xxxxxxxxxxx

The XFS sync daemon is responsible for periodically syncing an XFS filesystem.
The problem: in laptop mode, this can kick in at any time and spin up the disk,
even when there is no other reason to do so.

This patch wakes up the XFS sync daemon whenever an XFS syncfs takes place 
(e.g.,
at sys_sync()) so that it does its job and then sleeps for as long as it can. It
does so only when laptop mode is active. Laptop mode calls sys_sync() to
perform a writeback just before the disk is spun down, so the XFS sync daemon 
will
be woken up just before the disk is spun down as well, and after that it will 
leave
the disk alone for a full lm_sync_interval.

The patch also exports symbol laptop_mode, so that XFS can still be compiled as 
a
module.
---



---

 linux-2.6.4-bsamwel/fs/xfs/linux/xfs_super.c |   23 +++++++++++++++++++++++
 linux-2.6.4-bsamwel/fs/xfs/linux/xfs_vfs.c   |    1 +
 linux-2.6.4-bsamwel/fs/xfs/linux/xfs_vfs.h   |    2 ++
 linux-2.6.4-bsamwel/mm/page-writeback.c      |    1 +
 4 files changed, 27 insertions(+)

diff -puN fs/xfs/linux/xfs_super.c~xfs-laptop-mode-syncd-synchronization 
fs/xfs/linux/xfs_super.c
--- linux-2.6.4/fs/xfs/linux/xfs_super.c~xfs-laptop-mode-syncd-synchronization  
2004-04-03 15:34:30.000000000 +0200
+++ linux-2.6.4-bsamwel/fs/xfs/linux/xfs_super.c        2004-04-03 
15:34:30.000000000 +0200
@@ -72,6 +72,7 @@
 #include <linux/init.h>
 #include <linux/mount.h>
 #include <linux/suspend.h>
+#include <linux/writeback.h>
 
 STATIC struct quotactl_ops linvfs_qops;
 STATIC struct super_operations linvfs_sops;
@@ -470,6 +471,10 @@ syncd(void *arg)
                if (vfsp->vfs_flag & VFS_RDONLY)
                        continue;
                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;
@@ -553,6 +558,24 @@ linvfs_sync_super(
        VFS_SYNC(vfsp, flags, NULL, error);
        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;
 }
 
diff -puN fs/xfs/linux/xfs_vfs.c~xfs-laptop-mode-syncd-synchronization 
fs/xfs/linux/xfs_vfs.c
--- linux-2.6.4/fs/xfs/linux/xfs_vfs.c~xfs-laptop-mode-syncd-synchronization    
2004-04-03 15:34:30.000000000 +0200
+++ linux-2.6.4-bsamwel/fs/xfs/linux/xfs_vfs.c  2004-04-03 15:34:30.000000000 
+0200
@@ -238,6 +238,7 @@ vfs_allocate( void )
        vfsp = kmem_zalloc(sizeof(vfs_t), KM_SLEEP);
        bhv_head_init(VFS_BHVHEAD(vfsp), "vfs");
        init_waitqueue_head(&vfsp->vfs_wait_sync_task);
+       init_waitqueue_head(&vfsp->vfs_wait_single_sync_task);
        return vfsp;
 }
 
diff -puN fs/xfs/linux/xfs_vfs.h~xfs-laptop-mode-syncd-synchronization 
fs/xfs/linux/xfs_vfs.h
--- linux-2.6.4/fs/xfs/linux/xfs_vfs.h~xfs-laptop-mode-syncd-synchronization    
2004-04-03 15:34:30.000000000 +0200
+++ linux-2.6.4-bsamwel/fs/xfs/linux/xfs_vfs.h  2004-04-03 15:34:30.000000000 
+0200
@@ -52,6 +52,8 @@ typedef struct vfs {
        bhv_head_t              vfs_bh;         /* head of vfs behavior chain */
        struct super_block      *vfs_super;     /* Linux superblock structure */
        struct task_struct      *vfs_sync_task;
+       int                     vfs_sync_seq;   /* syncd iteration sequence 
number */
+       wait_queue_head_t       vfs_wait_single_sync_task;
        wait_queue_head_t       vfs_wait_sync_task;
 } vfs_t;
 
diff -puN mm/page-writeback.c~xfs-laptop-mode-syncd-synchronization 
mm/page-writeback.c
--- linux-2.6.4/mm/page-writeback.c~xfs-laptop-mode-syncd-synchronization       
2004-04-03 15:34:30.000000000 +0200
+++ linux-2.6.4-bsamwel/mm/page-writeback.c     2004-04-03 15:34:30.000000000 
+0200
@@ -91,6 +91,7 @@ int block_dump;
  * Flag that puts the machine in "laptop mode".
  */
 int laptop_mode;
+EXPORT_SYMBOL(laptop_mode);
 
 /* End of sysctl-exported parameters */
 

_


<Prev in Thread] Current Thread [Next in Thread>