On Tue, Nov 06, 2007 at 02:33:53AM -0800, akpm@linux-foundation.org wrote:
[mmotm.git] / fs / reiser4 / readahead.c
blob0be94b646640cbf6acc60d38762b584fa376b588
1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by
2 * reiser4/README */
4 #include "forward.h"
5 #include "tree.h"
6 #include "tree_walk.h"
7 #include "super.h"
8 #include "inode.h"
9 #include "key.h"
10 #include "znode.h"
12 #include <linux/swap.h> /* for totalram_pages */
14 void reiser4_init_ra_info(ra_info_t *rai)
16 rai->key_to_stop = *reiser4_min_key();
19 /* global formatted node readahead parameter. It can be set by mount option
20 * -o readahead:NUM:1 */
21 static inline int ra_adjacent_only(int flags)
23 return flags & RA_ADJACENT_ONLY;
26 /* this is used by formatted_readahead to decide whether read for right neighbor
27 * of node is to be issued. It returns 1 if right neighbor's first key is less
28 * or equal to readahead's stop key */
29 static int should_readahead_neighbor(znode * node, ra_info_t *info)
31 int result;
33 read_lock_dk(znode_get_tree(node));
34 result = keyle(znode_get_rd_key(node), &info->key_to_stop);
35 read_unlock_dk(znode_get_tree(node));
36 return result;
39 #define LOW_MEM_PERCENTAGE (5)
41 static int low_on_memory(void)
43 unsigned int freepages;
45 freepages = nr_free_pages();
46 return freepages < (totalram_pages * LOW_MEM_PERCENTAGE / 100);
49 /* start read for @node and for a few of its right neighbors */
50 void formatted_readahead(znode * node, ra_info_t *info)
52 struct formatted_ra_params *ra_params;
53 znode *cur;
54 int i;
55 int grn_flags;
56 lock_handle next_lh;
58 /* do nothing if node block number has not been assigned to node (which
59 * means it is still in cache). */
60 if (reiser4_blocknr_is_fake(znode_get_block(node)))
61 return;
63 ra_params = get_current_super_ra_params();
65 if (znode_page(node) == NULL)
66 jstartio(ZJNODE(node));
68 if (znode_get_level(node) != LEAF_LEVEL)
69 return;
71 /* don't waste memory for read-ahead when low on memory */
72 if (low_on_memory())
73 return;
75 /* We can have locked nodes on upper tree levels, in this situation lock
76 priorities do not help to resolve deadlocks, we have to use TRY_LOCK
77 here. */
78 grn_flags = (GN_CAN_USE_UPPER_LEVELS | GN_TRY_LOCK);
80 i = 0;
81 cur = zref(node);
82 init_lh(&next_lh);
83 while (i < ra_params->max) {
84 const reiser4_block_nr * nextblk;
86 if (!should_readahead_neighbor(cur, info))
87 break;
89 if (reiser4_get_right_neighbor
90 (&next_lh, cur, ZNODE_READ_LOCK, grn_flags))
91 break;
93 nextblk = znode_get_block(next_lh.node);
94 if (reiser4_blocknr_is_fake(nextblk) ||
95 (ra_adjacent_only(ra_params->flags)
96 && *nextblk != *znode_get_block(cur) + 1))
97 break;
99 zput(cur);
100 cur = zref(next_lh.node);
101 done_lh(&next_lh);
102 if (znode_page(cur) == NULL)
103 jstartio(ZJNODE(cur));
104 else
105 /* Do not scan read-ahead window if pages already
106 * allocated (and i/o already started). */
107 break;
109 i++;
111 zput(cur);
112 done_lh(&next_lh);
115 void reiser4_readdir_readahead_init(struct inode *dir, tap_t *tap)
117 reiser4_key *stop_key;
119 assert("nikita-3542", dir != NULL);
120 assert("nikita-3543", tap != NULL);
122 stop_key = &tap->ra_info.key_to_stop;
123 /* initialize readdir readahead information: include into readahead
124 * stat data of all files of the directory */
125 set_key_locality(stop_key, get_inode_oid(dir));
126 set_key_type(stop_key, KEY_SD_MINOR);
127 set_key_ordering(stop_key, get_key_ordering(reiser4_max_key()));
128 set_key_objectid(stop_key, get_key_objectid(reiser4_max_key()));
129 set_key_offset(stop_key, get_key_offset(reiser4_max_key()));
133 Local variables:
134 c-indentation-style: "K&R"
135 mode-name: "LC"
136 c-basic-offset: 8
137 tab-width: 8
138 fill-column: 80
139 End: