Commit 692684e1 authored by Sunil Mushran's avatar Sunil Mushran Committed by Joel Becker

ocfs2: Stop orphan scan as early as possible during umount

Currently if the orphan scan fires a tick before the user issues the umount,
the umount will wait for the queued orphan scan tasks to complete.

This patch makes the umount stop the orphan scan as early as possible so as
to reduce the probability of the queued tasks slowing down the umount.
Signed-off-by: default avatarSunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
parent c3d38840
...@@ -1880,6 +1880,9 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb) ...@@ -1880,6 +1880,9 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)
os = &osb->osb_orphan_scan; os = &osb->osb_orphan_scan;
if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE)
goto out;
status = ocfs2_orphan_scan_lock(osb, &seqno, DLM_LOCK_EX); status = ocfs2_orphan_scan_lock(osb, &seqno, DLM_LOCK_EX);
if (status < 0) { if (status < 0) {
if (status != -EAGAIN) if (status != -EAGAIN)
...@@ -1887,6 +1890,10 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb) ...@@ -1887,6 +1890,10 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)
goto out; goto out;
} }
/* Do no queue the tasks if the volume is being umounted */
if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE)
goto unlock;
if (os->os_seqno != seqno) { if (os->os_seqno != seqno) {
os->os_seqno = seqno; os->os_seqno = seqno;
goto unlock; goto unlock;
...@@ -1920,8 +1927,9 @@ void ocfs2_orphan_scan_work(struct work_struct *work) ...@@ -1920,8 +1927,9 @@ void ocfs2_orphan_scan_work(struct work_struct *work)
mutex_lock(&os->os_lock); mutex_lock(&os->os_lock);
ocfs2_queue_orphan_scan(osb); ocfs2_queue_orphan_scan(osb);
schedule_delayed_work(&os->os_orphan_scan_work, if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE)
ocfs2_orphan_scan_timeout()); schedule_delayed_work(&os->os_orphan_scan_work,
ocfs2_orphan_scan_timeout());
mutex_unlock(&os->os_lock); mutex_unlock(&os->os_lock);
} }
...@@ -1930,6 +1938,7 @@ void ocfs2_orphan_scan_stop(struct ocfs2_super *osb) ...@@ -1930,6 +1938,7 @@ void ocfs2_orphan_scan_stop(struct ocfs2_super *osb)
struct ocfs2_orphan_scan *os; struct ocfs2_orphan_scan *os;
os = &osb->osb_orphan_scan; os = &osb->osb_orphan_scan;
atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE);
mutex_lock(&os->os_lock); mutex_lock(&os->os_lock);
cancel_delayed_work(&os->os_orphan_scan_work); cancel_delayed_work(&os->os_orphan_scan_work);
mutex_unlock(&os->os_lock); mutex_unlock(&os->os_lock);
...@@ -1940,6 +1949,7 @@ int ocfs2_orphan_scan_init(struct ocfs2_super *osb) ...@@ -1940,6 +1949,7 @@ int ocfs2_orphan_scan_init(struct ocfs2_super *osb)
struct ocfs2_orphan_scan *os; struct ocfs2_orphan_scan *os;
os = &osb->osb_orphan_scan; os = &osb->osb_orphan_scan;
atomic_set(&os->os_state, ORPHAN_SCAN_ACTIVE);
os->os_osb = osb; os->os_osb = osb;
os->os_count = 0; os->os_count = 0;
os->os_scantime = CURRENT_TIME; os->os_scantime = CURRENT_TIME;
......
...@@ -154,6 +154,11 @@ struct ocfs2_lock_res { ...@@ -154,6 +154,11 @@ struct ocfs2_lock_res {
#endif #endif
}; };
enum ocfs2_orphan_scan_state {
ORPHAN_SCAN_ACTIVE,
ORPHAN_SCAN_INACTIVE
};
struct ocfs2_orphan_scan { struct ocfs2_orphan_scan {
struct mutex os_lock; struct mutex os_lock;
struct ocfs2_super *os_osb; struct ocfs2_super *os_osb;
...@@ -162,6 +167,7 @@ struct ocfs2_orphan_scan { ...@@ -162,6 +167,7 @@ struct ocfs2_orphan_scan {
struct timespec os_scantime; /* time this node ran the scan */ struct timespec os_scantime; /* time this node ran the scan */
u32 os_count; /* tracks node specific scans */ u32 os_count; /* tracks node specific scans */
u32 os_seqno; /* tracks cluster wide scans */ u32 os_seqno; /* tracks cluster wide scans */
atomic_t os_state; /* ACTIVE or INACTIVE */
}; };
struct ocfs2_dlm_debug { struct ocfs2_dlm_debug {
......
...@@ -1814,14 +1814,15 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) ...@@ -1814,14 +1814,15 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
debugfs_remove(osb->osb_ctxt); debugfs_remove(osb->osb_ctxt);
/* Orphan scan should be stopped as early as possible */
ocfs2_orphan_scan_stop(osb);
ocfs2_disable_quotas(osb); ocfs2_disable_quotas(osb);
ocfs2_shutdown_local_alloc(osb); ocfs2_shutdown_local_alloc(osb);
ocfs2_truncate_log_shutdown(osb); ocfs2_truncate_log_shutdown(osb);
ocfs2_orphan_scan_stop(osb);
/* This will disable recovery and flush any recovery work. */ /* This will disable recovery and flush any recovery work. */
ocfs2_recovery_exit(osb); ocfs2_recovery_exit(osb);
......
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