aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunil Mushran <sunil.mushran@oracle.com>2009-06-19 19:53:17 -0400
committerJoel Becker <joel.becker@oracle.com>2009-06-22 17:24:51 -0400
commit692684e19e317a374c18e70a44d6413e51f71c11 (patch)
treec47da5b21e66f80458fff3da4cda72b8e0644c0f
parentc3d38840abaa45c1c5a5fabbb8ffc9a0d1a764d1 (diff)
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: Sunil Mushran <sunil.mushran@oracle.com> Signed-off-by: Joel Becker <joel.becker@oracle.com>
-rw-r--r--fs/ocfs2/journal.c14
-rw-r--r--fs/ocfs2/ocfs2.h6
-rw-r--r--fs/ocfs2/super.c5
3 files changed, 21 insertions, 4 deletions
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 4a3b9e6b31ad..70215a21fb20 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -1880,6 +1880,9 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)
1880 1880
1881 os = &osb->osb_orphan_scan; 1881 os = &osb->osb_orphan_scan;
1882 1882
1883 if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE)
1884 goto out;
1885
1883 status = ocfs2_orphan_scan_lock(osb, &seqno, DLM_LOCK_EX); 1886 status = ocfs2_orphan_scan_lock(osb, &seqno, DLM_LOCK_EX);
1884 if (status < 0) { 1887 if (status < 0) {
1885 if (status != -EAGAIN) 1888 if (status != -EAGAIN)
@@ -1887,6 +1890,10 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)
1887 goto out; 1890 goto out;
1888 } 1891 }
1889 1892
1893 /* Do no queue the tasks if the volume is being umounted */
1894 if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE)
1895 goto unlock;
1896
1890 if (os->os_seqno != seqno) { 1897 if (os->os_seqno != seqno) {
1891 os->os_seqno = seqno; 1898 os->os_seqno = seqno;
1892 goto unlock; 1899 goto unlock;
@@ -1920,8 +1927,9 @@ void ocfs2_orphan_scan_work(struct work_struct *work)
1920 1927
1921 mutex_lock(&os->os_lock); 1928 mutex_lock(&os->os_lock);
1922 ocfs2_queue_orphan_scan(osb); 1929 ocfs2_queue_orphan_scan(osb);
1923 schedule_delayed_work(&os->os_orphan_scan_work, 1930 if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE)
1924 ocfs2_orphan_scan_timeout()); 1931 schedule_delayed_work(&os->os_orphan_scan_work,
1932 ocfs2_orphan_scan_timeout());
1925 mutex_unlock(&os->os_lock); 1933 mutex_unlock(&os->os_lock);
1926} 1934}
1927 1935
@@ -1930,6 +1938,7 @@ void ocfs2_orphan_scan_stop(struct ocfs2_super *osb)
1930 struct ocfs2_orphan_scan *os; 1938 struct ocfs2_orphan_scan *os;
1931 1939
1932 os = &osb->osb_orphan_scan; 1940 os = &osb->osb_orphan_scan;
1941 atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE);
1933 mutex_lock(&os->os_lock); 1942 mutex_lock(&os->os_lock);
1934 cancel_delayed_work(&os->os_orphan_scan_work); 1943 cancel_delayed_work(&os->os_orphan_scan_work);
1935 mutex_unlock(&os->os_lock); 1944 mutex_unlock(&os->os_lock);
@@ -1940,6 +1949,7 @@ int ocfs2_orphan_scan_init(struct ocfs2_super *osb)
1940 struct ocfs2_orphan_scan *os; 1949 struct ocfs2_orphan_scan *os;
1941 1950
1942 os = &osb->osb_orphan_scan; 1951 os = &osb->osb_orphan_scan;
1952 atomic_set(&os->os_state, ORPHAN_SCAN_ACTIVE);
1943 os->os_osb = osb; 1953 os->os_osb = osb;
1944 os->os_count = 0; 1954 os->os_count = 0;
1945 os->os_scantime = CURRENT_TIME; 1955 os->os_scantime = CURRENT_TIME;
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 18c1d9ec1c93..60e89503ce5a 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -154,6 +154,11 @@ struct ocfs2_lock_res {
154#endif 154#endif
155}; 155};
156 156
157enum ocfs2_orphan_scan_state {
158 ORPHAN_SCAN_ACTIVE,
159 ORPHAN_SCAN_INACTIVE
160};
161
157struct ocfs2_orphan_scan { 162struct ocfs2_orphan_scan {
158 struct mutex os_lock; 163 struct mutex os_lock;
159 struct ocfs2_super *os_osb; 164 struct ocfs2_super *os_osb;
@@ -162,6 +167,7 @@ struct ocfs2_orphan_scan {
162 struct timespec os_scantime; /* time this node ran the scan */ 167 struct timespec os_scantime; /* time this node ran the scan */
163 u32 os_count; /* tracks node specific scans */ 168 u32 os_count; /* tracks node specific scans */
164 u32 os_seqno; /* tracks cluster wide scans */ 169 u32 os_seqno; /* tracks cluster wide scans */
170 atomic_t os_state; /* ACTIVE or INACTIVE */
165}; 171};
166 172
167struct ocfs2_dlm_debug { 173struct ocfs2_dlm_debug {
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index d64739b593e9..3e8a68b103ab 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1814,14 +1814,15 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
1814 1814
1815 debugfs_remove(osb->osb_ctxt); 1815 debugfs_remove(osb->osb_ctxt);
1816 1816
1817 /* Orphan scan should be stopped as early as possible */
1818 ocfs2_orphan_scan_stop(osb);
1819
1817 ocfs2_disable_quotas(osb); 1820 ocfs2_disable_quotas(osb);
1818 1821
1819 ocfs2_shutdown_local_alloc(osb); 1822 ocfs2_shutdown_local_alloc(osb);
1820 1823
1821 ocfs2_truncate_log_shutdown(osb); 1824 ocfs2_truncate_log_shutdown(osb);
1822 1825
1823 ocfs2_orphan_scan_stop(osb);
1824
1825 /* This will disable recovery and flush any recovery work. */ 1826 /* This will disable recovery and flush any recovery work. */
1826 ocfs2_recovery_exit(osb); 1827 ocfs2_recovery_exit(osb);
1827 1828