mirror of
https://github.com/versity/scoutfs.git
synced 2026-02-07 11:10:44 +00:00
scoutfs: add sync deadline timer
Make sure that data is regularly synced. We switch to a delayed work struct that is always queued with the sync deadline. If we need an immediate sync we mod it to now. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -214,7 +214,7 @@ static int scoutfs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
atomic_set(&sbi->trans_holds, 0);
|
||||
init_waitqueue_head(&sbi->trans_hold_wq);
|
||||
spin_lock_init(&sbi->trans_write_lock);
|
||||
INIT_WORK(&sbi->trans_write_work, scoutfs_trans_write_func);
|
||||
INIT_DELAYED_WORK(&sbi->trans_write_work, scoutfs_trans_write_func);
|
||||
init_waitqueue_head(&sbi->trans_write_wq);
|
||||
|
||||
/* XXX can have multiple mounts of a device, need mount id */
|
||||
@@ -242,6 +242,7 @@ static int scoutfs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
if (!sb->s_root)
|
||||
return -ENOMEM;
|
||||
|
||||
scoutfs_trans_restart_sync_deadline(sb);
|
||||
// scoutfs_scan_orphans(sb);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -40,7 +40,7 @@ struct scoutfs_sb_info {
|
||||
spinlock_t trans_write_lock;
|
||||
u64 trans_write_count;
|
||||
int trans_write_ret;
|
||||
struct work_struct trans_write_work;
|
||||
struct delayed_work trans_write_work;
|
||||
wait_queue_head_t trans_write_wq;
|
||||
struct workqueue_struct *trans_write_workq;
|
||||
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
* very long time.
|
||||
*/
|
||||
|
||||
/* sync dirty data at least this often */
|
||||
#define TRANS_SYNC_DELAY (HZ * 10)
|
||||
|
||||
/*
|
||||
* This work func is responsible for writing out all the dirty blocks
|
||||
* that make up the current dirty transaction. It prevents writers from
|
||||
@@ -77,7 +80,7 @@
|
||||
void scoutfs_trans_write_func(struct work_struct *work)
|
||||
{
|
||||
struct scoutfs_sb_info *sbi = container_of(work, struct scoutfs_sb_info,
|
||||
trans_write_work);
|
||||
trans_write_work.work);
|
||||
struct super_block *sb = sbi->sb;
|
||||
struct scoutfs_bio_completion comp;
|
||||
struct scoutfs_segment *seg;
|
||||
@@ -125,6 +128,8 @@ out:
|
||||
wake_up(&sbi->trans_hold_wq);
|
||||
|
||||
sbi->trans_task = NULL;
|
||||
|
||||
scoutfs_trans_restart_sync_deadline(sb);
|
||||
}
|
||||
|
||||
struct write_attempt {
|
||||
@@ -148,9 +153,14 @@ static int write_attempted(struct scoutfs_sb_info *sbi,
|
||||
return done;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We always have delayed sync work pending but the caller wants it
|
||||
* to execute immediately.
|
||||
*/
|
||||
static void queue_trans_work(struct scoutfs_sb_info *sbi)
|
||||
{
|
||||
queue_work(sbi->trans_write_workq, &sbi->trans_write_work);
|
||||
mod_delayed_work(sbi->trans_write_workq, &sbi->trans_write_work, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -194,6 +204,14 @@ int scoutfs_file_fsync(struct file *file, loff_t start, loff_t end,
|
||||
return scoutfs_sync_fs(file->f_inode->i_sb, 1);
|
||||
}
|
||||
|
||||
void scoutfs_trans_restart_sync_deadline(struct super_block *sb)
|
||||
{
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
|
||||
mod_delayed_work(sbi->trans_write_workq, &sbi->trans_write_work,
|
||||
TRANS_SYNC_DELAY);
|
||||
}
|
||||
|
||||
/*
|
||||
* The holder that creates the most dirty item data is adding a full
|
||||
* size xattr. The largest xattr can have a 255 byte name and 64KB
|
||||
@@ -322,7 +340,7 @@ void scoutfs_shutdown_trans(struct super_block *sb)
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
|
||||
if (sbi->trans_write_workq) {
|
||||
flush_work(&sbi->trans_write_work);
|
||||
cancel_delayed_work_sync(&sbi->trans_write_work);
|
||||
destroy_workqueue(sbi->trans_write_workq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ void scoutfs_trans_write_func(struct work_struct *work);
|
||||
int scoutfs_sync_fs(struct super_block *sb, int wait);
|
||||
int scoutfs_file_fsync(struct file *file, loff_t start, loff_t end,
|
||||
int datasync);
|
||||
void scoutfs_trans_restart_sync_deadline(struct super_block *sb);
|
||||
|
||||
int scoutfs_hold_trans(struct super_block *sb);
|
||||
void scoutfs_release_trans(struct super_block *sb);
|
||||
|
||||
Reference in New Issue
Block a user