aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/glock.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2007-01-17 10:09:20 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2007-02-05 13:37:04 -0500
commit3699e3a44bf56e0cd58c97e8655f375ad9b65d9d (patch)
tree9ac31dd5b99373614f0cd52cc5a41536aeea271e /fs/gfs2/glock.c
parenta8d638e30e768adc6956541f79f7bf05139ba475 (diff)
[GFS2] Clean up/speed up readdir
This removes the extra filldir callback which gfs2 was using to enclose an attempt at readahead for inodes during readdir. The code was too complicated and also hurts performance badly in the case that the getdents64/readdir call isn't being followed by stat() and it wasn't even getting it right all the time when it was. As a result, on my test box an "ls" of a directory containing 250000 files fell from about 7mins (freshly mounted, so nothing cached) to between about 15 to 25 seconds. When the directory content was cached, the time taken fell from about 3mins to about 4 or 5 seconds. Interestingly in the cached case, running "ls -l" once reduced the time taken for subsequent runs of "ls" to about 6 secs even without this patch. Now it turns out that there was a special case of glocks being used for prefetching the metadata, but because of the timeouts for these locks (set to 10 secs) the metadata was being timed out before it was being used and this the prefetch code was constantly trying to prefetch the same data over and over. Calling "ls -l" meant that the inodes were brought into memory and once the inodes are cached, the glocks are not disposed of until the inodes are pushed out of the cache, thus extending the lifetime of the glocks, and thus bringing down the time for subsequent runs of "ls" considerably. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/glock.c')
-rw-r--r--fs/gfs2/glock.c66
1 files changed, 0 insertions, 66 deletions
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 438146904b58..fb1960b7fdde 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -971,8 +971,6 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret)
971 const struct gfs2_glock_operations *glops = gl->gl_ops; 971 const struct gfs2_glock_operations *glops = gl->gl_ops;
972 struct gfs2_holder *gh = gl->gl_req_gh; 972 struct gfs2_holder *gh = gl->gl_req_gh;
973 973
974 clear_bit(GLF_PREFETCH, &gl->gl_flags);
975
976 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); 974 gfs2_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags));
977 gfs2_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); 975 gfs2_assert_warn(sdp, queue_empty(gl, &gl->gl_holders));
978 gfs2_assert_warn(sdp, !ret); 976 gfs2_assert_warn(sdp, !ret);
@@ -1227,8 +1225,6 @@ restart:
1227 } 1225 }
1228 } 1226 }
1229 1227
1230 clear_bit(GLF_PREFETCH, &gl->gl_flags);
1231
1232 return error; 1228 return error;
1233} 1229}
1234 1230
@@ -1320,36 +1316,6 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
1320 spin_unlock(&gl->gl_spin); 1316 spin_unlock(&gl->gl_spin);
1321} 1317}
1322 1318
1323/**
1324 * gfs2_glock_prefetch - Try to prefetch a glock
1325 * @gl: the glock
1326 * @state: the state to prefetch in
1327 * @flags: flags passed to go_xmote_th()
1328 *
1329 */
1330
1331static void gfs2_glock_prefetch(struct gfs2_glock *gl, unsigned int state,
1332 int flags)
1333{
1334 const struct gfs2_glock_operations *glops = gl->gl_ops;
1335
1336 spin_lock(&gl->gl_spin);
1337
1338 if (test_bit(GLF_LOCK, &gl->gl_flags) || !list_empty(&gl->gl_holders) ||
1339 !list_empty(&gl->gl_waiters1) || !list_empty(&gl->gl_waiters2) ||
1340 !list_empty(&gl->gl_waiters3) ||
1341 relaxed_state_ok(gl->gl_state, state, flags)) {
1342 spin_unlock(&gl->gl_spin);
1343 return;
1344 }
1345
1346 set_bit(GLF_PREFETCH, &gl->gl_flags);
1347 set_bit(GLF_LOCK, &gl->gl_flags);
1348 spin_unlock(&gl->gl_spin);
1349
1350 glops->go_xmote_th(gl, state, flags);
1351}
1352
1353static void greedy_work(struct work_struct *work) 1319static void greedy_work(struct work_struct *work)
1354{ 1320{
1355 struct greedy *gr = container_of(work, struct greedy, gr_work.work); 1321 struct greedy *gr = container_of(work, struct greedy, gr_work.work);
@@ -1618,34 +1584,6 @@ void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs)
1618} 1584}
1619 1585
1620/** 1586/**
1621 * gfs2_glock_prefetch_num - prefetch a glock based on lock number
1622 * @sdp: the filesystem
1623 * @number: the lock number
1624 * @glops: the glock operations for the type of glock
1625 * @state: the state to acquire the glock in
1626 * @flags: modifier flags for the aquisition
1627 *
1628 * Returns: errno
1629 */
1630
1631void gfs2_glock_prefetch_num(struct gfs2_sbd *sdp, u64 number,
1632 const struct gfs2_glock_operations *glops,
1633 unsigned int state, int flags)
1634{
1635 struct gfs2_glock *gl;
1636 int error;
1637
1638 if (atomic_read(&sdp->sd_reclaim_count) <
1639 gfs2_tune_get(sdp, gt_reclaim_limit)) {
1640 error = gfs2_glock_get(sdp, number, glops, CREATE, &gl);
1641 if (!error) {
1642 gfs2_glock_prefetch(gl, state, flags);
1643 gfs2_glock_put(gl);
1644 }
1645 }
1646}
1647
1648/**
1649 * gfs2_lvb_hold - attach a LVB from a glock 1587 * gfs2_lvb_hold - attach a LVB from a glock
1650 * @gl: The glock in question 1588 * @gl: The glock in question
1651 * 1589 *
@@ -1781,15 +1719,11 @@ void gfs2_glock_cb(void *cb_data, unsigned int type, void *data)
1781 1719
1782static int demote_ok(struct gfs2_glock *gl) 1720static int demote_ok(struct gfs2_glock *gl)
1783{ 1721{
1784 struct gfs2_sbd *sdp = gl->gl_sbd;
1785 const struct gfs2_glock_operations *glops = gl->gl_ops; 1722 const struct gfs2_glock_operations *glops = gl->gl_ops;
1786 int demote = 1; 1723 int demote = 1;
1787 1724
1788 if (test_bit(GLF_STICKY, &gl->gl_flags)) 1725 if (test_bit(GLF_STICKY, &gl->gl_flags))
1789 demote = 0; 1726 demote = 0;
1790 else if (test_bit(GLF_PREFETCH, &gl->gl_flags))
1791 demote = time_after_eq(jiffies, gl->gl_stamp +
1792 gfs2_tune_get(sdp, gt_prefetch_secs) * HZ);
1793 else if (glops->go_demote_ok) 1727 else if (glops->go_demote_ok)
1794 demote = glops->go_demote_ok(gl); 1728 demote = glops->go_demote_ok(gl);
1795 1729