Skip to content

Commit

Permalink
ocfs2: Stop orphan scan as early as possible during umount
Browse files Browse the repository at this point in the history
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: Sunil Mushran <sunil.mushran@oracle.com>
Signed-off-by: Joel Becker <joel.becker@oracle.com>
  • Loading branch information
Sunil Mushran authored and Joel Becker committed Jun 22, 2009
1 parent c3d3884 commit 692684e
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 4 deletions.
14 changes: 12 additions & 2 deletions fs/ocfs2/journal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1880,13 +1880,20 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)

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);
if (status < 0) {
if (status != -EAGAIN)
mlog_errno(status);
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) {
os->os_seqno = seqno;
goto unlock;
Expand Down Expand Up @@ -1920,8 +1927,9 @@ void ocfs2_orphan_scan_work(struct work_struct *work)

mutex_lock(&os->os_lock);
ocfs2_queue_orphan_scan(osb);
schedule_delayed_work(&os->os_orphan_scan_work,
ocfs2_orphan_scan_timeout());
if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE)
schedule_delayed_work(&os->os_orphan_scan_work,
ocfs2_orphan_scan_timeout());
mutex_unlock(&os->os_lock);
}

Expand All @@ -1930,6 +1938,7 @@ void ocfs2_orphan_scan_stop(struct ocfs2_super *osb)
struct ocfs2_orphan_scan *os;

os = &osb->osb_orphan_scan;
atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE);
mutex_lock(&os->os_lock);
cancel_delayed_work(&os->os_orphan_scan_work);
mutex_unlock(&os->os_lock);
Expand All @@ -1940,6 +1949,7 @@ int ocfs2_orphan_scan_init(struct ocfs2_super *osb)
struct ocfs2_orphan_scan *os;

os = &osb->osb_orphan_scan;
atomic_set(&os->os_state, ORPHAN_SCAN_ACTIVE);
os->os_osb = osb;
os->os_count = 0;
os->os_scantime = CURRENT_TIME;
Expand Down
6 changes: 6 additions & 0 deletions fs/ocfs2/ocfs2.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ struct ocfs2_lock_res {
#endif
};

enum ocfs2_orphan_scan_state {
ORPHAN_SCAN_ACTIVE,
ORPHAN_SCAN_INACTIVE
};

struct ocfs2_orphan_scan {
struct mutex os_lock;
struct ocfs2_super *os_osb;
Expand All @@ -162,6 +167,7 @@ struct ocfs2_orphan_scan {
struct timespec os_scantime; /* time this node ran the scan */
u32 os_count; /* tracks node specific scans */
u32 os_seqno; /* tracks cluster wide scans */
atomic_t os_state; /* ACTIVE or INACTIVE */
};

struct ocfs2_dlm_debug {
Expand Down
5 changes: 3 additions & 2 deletions fs/ocfs2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1814,14 +1814,15 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)

debugfs_remove(osb->osb_ctxt);

/* Orphan scan should be stopped as early as possible */
ocfs2_orphan_scan_stop(osb);

ocfs2_disable_quotas(osb);

ocfs2_shutdown_local_alloc(osb);

ocfs2_truncate_log_shutdown(osb);

ocfs2_orphan_scan_stop(osb);

/* This will disable recovery and flush any recovery work. */
ocfs2_recovery_exit(osb);

Expand Down

0 comments on commit 692684e

Please sign in to comment.