Blame view

fs/ocfs2/uptodate.c 17.7 KB
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  /* -*- mode: c; c-basic-offset: 8; -*-
   * vim: noexpandtab sw=8 ts=8 sts=0:
   *
   * uptodate.c
   *
   * Tracking the up-to-date-ness of a local buffer_head with respect to
   * the cluster.
   *
   * Copyright (C) 2002, 2004, 2005 Oracle.  All rights reserved.
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public
   * License as published by the Free Software Foundation; either
   * version 2 of the License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public
   * License along with this program; if not, write to the
   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   * Boston, MA 021110-1307, USA.
   *
   * Standard buffer head caching flags (uptodate, etc) are insufficient
   * in a clustered environment - a buffer may be marked up to date on
   * our local node but could have been modified by another cluster
   * member. As a result an additional (and performant) caching scheme
   * is required. A further requirement is that we consume as little
   * memory as possible - we never pin buffer_head structures in order
   * to cache them.
   *
   * We track the existence of up to date buffers on the inodes which
   * are associated with them. Because we don't want to pin
   * buffer_heads, this is only a (strong) hint and several other checks
   * are made in the I/O path to ensure that we don't use a stale or
   * invalid buffer without going to disk:
   *	- buffer_jbd is used liberally - if a bh is in the journal on
   *	  this node then it *must* be up to date.
   *	- the standard buffer_uptodate() macro is used to detect buffers
   *	  which may be invalid (even if we have an up to date tracking
   * 	  item for them)
   *
   * For a full understanding of how this code works together, one
   * should read the callers in dlmglue.c, the I/O functions in
   * buffer_head_io.c and ocfs2_journal_access in journal.c
   */
  
  #include <linux/fs.h>
  #include <linux/types.h>
  #include <linux/slab.h>
  #include <linux/highmem.h>
  #include <linux/buffer_head.h>
  #include <linux/rbtree.h>
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
56

ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
57
58
59
60
61
62
  #include <cluster/masklog.h>
  
  #include "ocfs2.h"
  
  #include "inode.h"
  #include "uptodate.h"
d701485a6   Tao Ma   ocfs2: Remove mas...
63
  #include "ocfs2_trace.h"
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
64
65
66
67
68
  
  struct ocfs2_meta_cache_item {
  	struct rb_node	c_node;
  	sector_t	c_block;
  };
1a5c4e2a0   Fabian Frederick   ocfs2: remove NUL...
69
  static struct kmem_cache *ocfs2_uptodate_cachep;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
70

8cb471e8f   Joel Becker   ocfs2: Take the i...
71
  u64 ocfs2_metadata_cache_owner(struct ocfs2_caching_info *ci)
6e5a3d753   Joel Becker   ocfs2: Change met...
72
73
74
75
76
  {
  	BUG_ON(!ci || !ci->ci_ops);
  
  	return ci->ci_ops->co_owner(ci);
  }
8cb471e8f   Joel Becker   ocfs2: Take the i...
77
78
79
80
81
82
  struct super_block *ocfs2_metadata_cache_get_super(struct ocfs2_caching_info *ci)
  {
  	BUG_ON(!ci || !ci->ci_ops);
  
  	return ci->ci_ops->co_get_super(ci);
  }
6e5a3d753   Joel Becker   ocfs2: Change met...
83
84
85
86
87
88
89
90
91
92
93
94
95
  static void ocfs2_metadata_cache_lock(struct ocfs2_caching_info *ci)
  {
  	BUG_ON(!ci || !ci->ci_ops);
  
  	ci->ci_ops->co_cache_lock(ci);
  }
  
  static void ocfs2_metadata_cache_unlock(struct ocfs2_caching_info *ci)
  {
  	BUG_ON(!ci || !ci->ci_ops);
  
  	ci->ci_ops->co_cache_unlock(ci);
  }
8cb471e8f   Joel Becker   ocfs2: Take the i...
96
  void ocfs2_metadata_cache_io_lock(struct ocfs2_caching_info *ci)
6e5a3d753   Joel Becker   ocfs2: Change met...
97
98
99
100
101
  {
  	BUG_ON(!ci || !ci->ci_ops);
  
  	ci->ci_ops->co_io_lock(ci);
  }
8cb471e8f   Joel Becker   ocfs2: Take the i...
102
  void ocfs2_metadata_cache_io_unlock(struct ocfs2_caching_info *ci)
6e5a3d753   Joel Becker   ocfs2: Change met...
103
104
105
106
107
  {
  	BUG_ON(!ci || !ci->ci_ops);
  
  	ci->ci_ops->co_io_unlock(ci);
  }
66fb345dd   Joel Becker   ocfs2: move ip_la...
108
109
110
111
112
  static void ocfs2_metadata_cache_reset(struct ocfs2_caching_info *ci,
  				       int clear)
  {
  	ci->ci_flags |= OCFS2_CACHE_FL_INLINE;
  	ci->ci_num_cached = 0;
292dd27ec   Joel Becker   ocfs2: move ip_cr...
113
114
  	if (clear) {
  		ci->ci_created_trans = 0;
66fb345dd   Joel Becker   ocfs2: move ip_la...
115
  		ci->ci_last_trans = 0;
292dd27ec   Joel Becker   ocfs2: move ip_cr...
116
  	}
66fb345dd   Joel Becker   ocfs2: move ip_la...
117
  }
47460d65a   Joel Becker   ocfs2: Make the o...
118
  void ocfs2_metadata_cache_init(struct ocfs2_caching_info *ci,
6e5a3d753   Joel Becker   ocfs2: Change met...
119
  			       const struct ocfs2_caching_operations *ops)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
120
  {
6e5a3d753   Joel Becker   ocfs2: Change met...
121
122
123
  	BUG_ON(!ops);
  
  	ci->ci_ops = ops;
66fb345dd   Joel Becker   ocfs2: move ip_la...
124
125
126
127
128
129
130
  	ocfs2_metadata_cache_reset(ci, 1);
  }
  
  void ocfs2_metadata_cache_exit(struct ocfs2_caching_info *ci)
  {
  	ocfs2_metadata_cache_purge(ci);
  	ocfs2_metadata_cache_reset(ci, 1);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
131
  }
66fb345dd   Joel Becker   ocfs2: move ip_la...
132

ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
133
134
135
136
137
138
139
140
141
142
  /* No lock taken here as 'root' is not expected to be visible to other
   * processes. */
  static unsigned int ocfs2_purge_copied_metadata_tree(struct rb_root *root)
  {
  	unsigned int purged = 0;
  	struct rb_node *node;
  	struct ocfs2_meta_cache_item *item;
  
  	while ((node = rb_last(root)) != NULL) {
  		item = rb_entry(node, struct ocfs2_meta_cache_item, c_node);
d701485a6   Tao Ma   ocfs2: Remove mas...
143
144
  		trace_ocfs2_purge_copied_metadata_tree(
  					(unsigned long long) item->c_block);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
  
  		rb_erase(&item->c_node, root);
  		kmem_cache_free(ocfs2_uptodate_cachep, item);
  
  		purged++;
  	}
  	return purged;
  }
  
  /* Called from locking and called from ocfs2_clear_inode. Dump the
   * cache for a given inode.
   *
   * This function is a few more lines longer than necessary due to some
   * accounting done here, but I think it's worth tracking down those
   * bugs sooner -- Mark */
8cb471e8f   Joel Becker   ocfs2: Take the i...
160
  void ocfs2_metadata_cache_purge(struct ocfs2_caching_info *ci)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
161
  {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
162
  	unsigned int tree, to_purge, purged;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
163
  	struct rb_root root = RB_ROOT;
6e5a3d753   Joel Becker   ocfs2: Change met...
164
165
166
  	BUG_ON(!ci || !ci->ci_ops);
  
  	ocfs2_metadata_cache_lock(ci);
47460d65a   Joel Becker   ocfs2: Make the o...
167
  	tree = !(ci->ci_flags & OCFS2_CACHE_FL_INLINE);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
168
  	to_purge = ci->ci_num_cached;
d701485a6   Tao Ma   ocfs2: Remove mas...
169
170
171
  	trace_ocfs2_metadata_cache_purge(
  		(unsigned long long)ocfs2_metadata_cache_owner(ci),
  		to_purge, tree);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
172
173
174
175
176
177
  
  	/* If we're a tree, save off the root so that we can safely
  	 * initialize the cache. We do the work to free tree members
  	 * without the spinlock. */
  	if (tree)
  		root = ci->ci_cache.ci_tree;
66fb345dd   Joel Becker   ocfs2: move ip_la...
178
  	ocfs2_metadata_cache_reset(ci, 0);
6e5a3d753   Joel Becker   ocfs2: Change met...
179
  	ocfs2_metadata_cache_unlock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
180
181
182
183
184
185
  
  	purged = ocfs2_purge_copied_metadata_tree(&root);
  	/* If possible, track the number wiped so that we can more
  	 * easily detect counting errors. Unfortunately, this is only
  	 * meaningful for trees. */
  	if (tree && purged != to_purge)
6e5a3d753   Joel Becker   ocfs2: Change met...
186
187
188
189
  		mlog(ML_ERROR, "Owner %llu, count = %u, purged = %u
  ",
  		     (unsigned long long)ocfs2_metadata_cache_owner(ci),
  		     to_purge, purged);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
  }
  
  /* Returns the index in the cache array, -1 if not found.
   * Requires ip_lock. */
  static int ocfs2_search_cache_array(struct ocfs2_caching_info *ci,
  				    sector_t item)
  {
  	int i;
  
  	for (i = 0; i < ci->ci_num_cached; i++) {
  		if (item == ci->ci_cache.ci_array[i])
  			return i;
  	}
  
  	return -1;
  }
  
  /* Returns the cache item if found, otherwise NULL.
   * Requires ip_lock. */
  static struct ocfs2_meta_cache_item *
  ocfs2_search_cache_tree(struct ocfs2_caching_info *ci,
  			sector_t block)
  {
  	struct rb_node * n = ci->ci_cache.ci_tree.rb_node;
  	struct ocfs2_meta_cache_item *item = NULL;
  
  	while (n) {
  		item = rb_entry(n, struct ocfs2_meta_cache_item, c_node);
  
  		if (block < item->c_block)
  			n = n->rb_left;
  		else if (block > item->c_block)
  			n = n->rb_right;
  		else
  			return item;
  	}
  
  	return NULL;
  }
8cb471e8f   Joel Becker   ocfs2: Take the i...
229
  static int ocfs2_buffer_cached(struct ocfs2_caching_info *ci,
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
230
231
232
233
  			       struct buffer_head *bh)
  {
  	int index = -1;
  	struct ocfs2_meta_cache_item *item = NULL;
6e5a3d753   Joel Becker   ocfs2: Change met...
234
  	ocfs2_metadata_cache_lock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
235

d701485a6   Tao Ma   ocfs2: Remove mas...
236
237
238
239
  	trace_ocfs2_buffer_cached_begin(
  		(unsigned long long)ocfs2_metadata_cache_owner(ci),
  		(unsigned long long) bh->b_blocknr,
  		!!(ci->ci_flags & OCFS2_CACHE_FL_INLINE));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
240

47460d65a   Joel Becker   ocfs2: Make the o...
241
  	if (ci->ci_flags & OCFS2_CACHE_FL_INLINE)
8cb471e8f   Joel Becker   ocfs2: Take the i...
242
  		index = ocfs2_search_cache_array(ci, bh->b_blocknr);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
243
  	else
8cb471e8f   Joel Becker   ocfs2: Take the i...
244
  		item = ocfs2_search_cache_tree(ci, bh->b_blocknr);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
245

6e5a3d753   Joel Becker   ocfs2: Change met...
246
  	ocfs2_metadata_cache_unlock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
247

d701485a6   Tao Ma   ocfs2: Remove mas...
248
  	trace_ocfs2_buffer_cached_end(index, item);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
249
250
251
252
253
  
  	return (index != -1) || (item != NULL);
  }
  
  /* Warning: even if it returns true, this does *not* guarantee that
2bd632165   Sunil Mushran   ocfs2/trivial: Re...
254
255
   * the block is stored in our inode metadata cache.
   *
aa9588741   Mark Fasheh   ocfs2: implement ...
256
257
   * This can be called under lock_buffer()
   */
8cb471e8f   Joel Becker   ocfs2: Take the i...
258
  int ocfs2_buffer_uptodate(struct ocfs2_caching_info *ci,
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
  			  struct buffer_head *bh)
  {
  	/* Doesn't matter if the bh is in our cache or not -- if it's
  	 * not marked uptodate then we know it can't have correct
  	 * data. */
  	if (!buffer_uptodate(bh))
  		return 0;
  
  	/* OCFS2 does not allow multiple nodes to be changing the same
  	 * block at the same time. */
  	if (buffer_jbd(bh))
  		return 1;
  
  	/* Ok, locally the buffer is marked as up to date, now search
  	 * our cache to see if we can trust that. */
8cb471e8f   Joel Becker   ocfs2: Take the i...
274
  	return ocfs2_buffer_cached(ci, bh);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
275
  }
8cb471e8f   Joel Becker   ocfs2: Take the i...
276
  /*
aa9588741   Mark Fasheh   ocfs2: implement ...
277
   * Determine whether a buffer is currently out on a read-ahead request.
47460d65a   Joel Becker   ocfs2: Make the o...
278
   * ci_io_sem should be held to serialize submitters with the logic here.
aa9588741   Mark Fasheh   ocfs2: implement ...
279
   */
8cb471e8f   Joel Becker   ocfs2: Take the i...
280
  int ocfs2_buffer_read_ahead(struct ocfs2_caching_info *ci,
aa9588741   Mark Fasheh   ocfs2: implement ...
281
282
  			    struct buffer_head *bh)
  {
8cb471e8f   Joel Becker   ocfs2: Take the i...
283
  	return buffer_locked(bh) && ocfs2_buffer_cached(ci, bh);
aa9588741   Mark Fasheh   ocfs2: implement ...
284
  }
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
285
286
287
288
  /* Requires ip_lock */
  static void ocfs2_append_cache_array(struct ocfs2_caching_info *ci,
  				     sector_t block)
  {
47460d65a   Joel Becker   ocfs2: Make the o...
289
  	BUG_ON(ci->ci_num_cached >= OCFS2_CACHE_INFO_MAX_ARRAY);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
290

d701485a6   Tao Ma   ocfs2: Remove mas...
291
292
293
  	trace_ocfs2_append_cache_array(
  		(unsigned long long)ocfs2_metadata_cache_owner(ci),
  		(unsigned long long)block, ci->ci_num_cached);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
  
  	ci->ci_cache.ci_array[ci->ci_num_cached] = block;
  	ci->ci_num_cached++;
  }
  
  /* By now the caller should have checked that the item does *not*
   * exist in the tree.
   * Requires ip_lock. */
  static void __ocfs2_insert_cache_tree(struct ocfs2_caching_info *ci,
  				      struct ocfs2_meta_cache_item *new)
  {
  	sector_t block = new->c_block;
  	struct rb_node *parent = NULL;
  	struct rb_node **p = &ci->ci_cache.ci_tree.rb_node;
  	struct ocfs2_meta_cache_item *tmp;
d701485a6   Tao Ma   ocfs2: Remove mas...
309
310
311
  	trace_ocfs2_insert_cache_tree(
  		(unsigned long long)ocfs2_metadata_cache_owner(ci),
  		(unsigned long long)block, ci->ci_num_cached);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
  
  	while(*p) {
  		parent = *p;
  
  		tmp = rb_entry(parent, struct ocfs2_meta_cache_item, c_node);
  
  		if (block < tmp->c_block)
  			p = &(*p)->rb_left;
  		else if (block > tmp->c_block)
  			p = &(*p)->rb_right;
  		else {
  			/* This should never happen! */
  			mlog(ML_ERROR, "Duplicate block %llu cached!
  ",
  			     (unsigned long long) block);
  			BUG();
  		}
  	}
  
  	rb_link_node(&new->c_node, parent, p);
  	rb_insert_color(&new->c_node, &ci->ci_cache.ci_tree);
  	ci->ci_num_cached++;
  }
6e5a3d753   Joel Becker   ocfs2: Change met...
335
  /* co_cache_lock() must be held */
8cb471e8f   Joel Becker   ocfs2: Take the i...
336
  static inline int ocfs2_insert_can_use_array(struct ocfs2_caching_info *ci)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
337
  {
47460d65a   Joel Becker   ocfs2: Make the o...
338
339
  	return (ci->ci_flags & OCFS2_CACHE_FL_INLINE) &&
  		(ci->ci_num_cached < OCFS2_CACHE_INFO_MAX_ARRAY);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
340
  }
47460d65a   Joel Becker   ocfs2: Make the o...
341
  /* tree should be exactly OCFS2_CACHE_INFO_MAX_ARRAY wide. NULL the
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
342
   * pointers in tree after we use them - this allows caller to detect
6e5a3d753   Joel Becker   ocfs2: Change met...
343
344
345
   * when to free in case of error.
   *
   * The co_cache_lock() must be held. */
8cb471e8f   Joel Becker   ocfs2: Take the i...
346
  static void ocfs2_expand_cache(struct ocfs2_caching_info *ci,
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
347
348
349
  			       struct ocfs2_meta_cache_item **tree)
  {
  	int i;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
350

47460d65a   Joel Becker   ocfs2: Make the o...
351
  	mlog_bug_on_msg(ci->ci_num_cached != OCFS2_CACHE_INFO_MAX_ARRAY,
6e5a3d753   Joel Becker   ocfs2: Change met...
352
353
354
355
  			"Owner %llu, num cached = %u, should be %u
  ",
  			(unsigned long long)ocfs2_metadata_cache_owner(ci),
  			ci->ci_num_cached, OCFS2_CACHE_INFO_MAX_ARRAY);
47460d65a   Joel Becker   ocfs2: Make the o...
356
  	mlog_bug_on_msg(!(ci->ci_flags & OCFS2_CACHE_FL_INLINE),
6e5a3d753   Joel Becker   ocfs2: Change met...
357
358
359
  			"Owner %llu not marked as inline anymore!
  ",
  			(unsigned long long)ocfs2_metadata_cache_owner(ci));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
360
361
362
  
  	/* Be careful to initialize the tree members *first* because
  	 * once the ci_tree is used, the array is junk... */
47460d65a   Joel Becker   ocfs2: Make the o...
363
  	for (i = 0; i < OCFS2_CACHE_INFO_MAX_ARRAY; i++)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
364
  		tree[i]->c_block = ci->ci_cache.ci_array[i];
47460d65a   Joel Becker   ocfs2: Make the o...
365
  	ci->ci_flags &= ~OCFS2_CACHE_FL_INLINE;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
366
367
368
  	ci->ci_cache.ci_tree = RB_ROOT;
  	/* this will be set again by __ocfs2_insert_cache_tree */
  	ci->ci_num_cached = 0;
47460d65a   Joel Becker   ocfs2: Make the o...
369
  	for (i = 0; i < OCFS2_CACHE_INFO_MAX_ARRAY; i++) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
370
371
372
  		__ocfs2_insert_cache_tree(ci, tree[i]);
  		tree[i] = NULL;
  	}
d701485a6   Tao Ma   ocfs2: Remove mas...
373
374
375
  	trace_ocfs2_expand_cache(
  		(unsigned long long)ocfs2_metadata_cache_owner(ci),
  		ci->ci_flags, ci->ci_num_cached);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
376
377
378
379
  }
  
  /* Slow path function - memory allocation is necessary. See the
   * comment above ocfs2_set_buffer_uptodate for more information. */
8cb471e8f   Joel Becker   ocfs2: Take the i...
380
  static void __ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
381
382
383
384
  					sector_t block,
  					int expand_tree)
  {
  	int i;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
385
  	struct ocfs2_meta_cache_item *new = NULL;
47460d65a   Joel Becker   ocfs2: Make the o...
386
  	struct ocfs2_meta_cache_item *tree[OCFS2_CACHE_INFO_MAX_ARRAY] =
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
387
  		{ NULL, };
d701485a6   Tao Ma   ocfs2: Remove mas...
388
389
390
  	trace_ocfs2_set_buffer_uptodate(
  		(unsigned long long)ocfs2_metadata_cache_owner(ci),
  		(unsigned long long)block, expand_tree);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
391

afae00ab4   Sunil Mushran   ocfs2: fix gfp ma...
392
  	new = kmem_cache_alloc(ocfs2_uptodate_cachep, GFP_NOFS);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
393
394
395
396
397
398
399
400
401
  	if (!new) {
  		mlog_errno(-ENOMEM);
  		return;
  	}
  	new->c_block = block;
  
  	if (expand_tree) {
  		/* Do *not* allocate an array here - the removal code
  		 * has no way of tracking that. */
47460d65a   Joel Becker   ocfs2: Make the o...
402
  		for (i = 0; i < OCFS2_CACHE_INFO_MAX_ARRAY; i++) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
403
  			tree[i] = kmem_cache_alloc(ocfs2_uptodate_cachep,
afae00ab4   Sunil Mushran   ocfs2: fix gfp ma...
404
  						   GFP_NOFS);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
405
406
407
408
409
410
411
412
  			if (!tree[i]) {
  				mlog_errno(-ENOMEM);
  				goto out_free;
  			}
  
  			/* These are initialized in ocfs2_expand_cache! */
  		}
  	}
6e5a3d753   Joel Becker   ocfs2: Change met...
413
  	ocfs2_metadata_cache_lock(ci);
8cb471e8f   Joel Becker   ocfs2: Take the i...
414
  	if (ocfs2_insert_can_use_array(ci)) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
415
416
417
  		/* Ok, items were removed from the cache in between
  		 * locks. Detect this and revert back to the fast path */
  		ocfs2_append_cache_array(ci, block);
6e5a3d753   Joel Becker   ocfs2: Change met...
418
  		ocfs2_metadata_cache_unlock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
419
420
421
422
  		goto out_free;
  	}
  
  	if (expand_tree)
8cb471e8f   Joel Becker   ocfs2: Take the i...
423
  		ocfs2_expand_cache(ci, tree);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
424
425
  
  	__ocfs2_insert_cache_tree(ci, new);
6e5a3d753   Joel Becker   ocfs2: Change met...
426
  	ocfs2_metadata_cache_unlock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
427
428
429
430
431
432
433
434
435
  
  	new = NULL;
  out_free:
  	if (new)
  		kmem_cache_free(ocfs2_uptodate_cachep, new);
  
  	/* If these were used, then ocfs2_expand_cache re-set them to
  	 * NULL for us. */
  	if (tree[0]) {
47460d65a   Joel Becker   ocfs2: Make the o...
436
  		for (i = 0; i < OCFS2_CACHE_INFO_MAX_ARRAY; i++)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
437
438
439
440
441
  			if (tree[i])
  				kmem_cache_free(ocfs2_uptodate_cachep,
  						tree[i]);
  	}
  }
6e5a3d753   Joel Becker   ocfs2: Change met...
442
  /* Item insertion is guarded by co_io_lock(), so the insertion path takes
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
443
444
445
446
447
448
449
450
451
452
453
454
   * advantage of this by not rechecking for a duplicate insert during
   * the slow case. Additionally, if the cache needs to be bumped up to
   * a tree, the code will not recheck after acquiring the lock --
   * multiple paths cannot be expanding to a tree at the same time.
   *
   * The slow path takes into account that items can be removed
   * (including the whole tree wiped and reset) when this process it out
   * allocating memory. In those cases, it reverts back to the fast
   * path.
   *
   * Note that this function may actually fail to insert the block if
   * memory cannot be allocated. This is not fatal however (but may
aa9588741   Mark Fasheh   ocfs2: implement ...
455
456
457
458
459
   * result in a performance penalty)
   *
   * Readahead buffers can be passed in here before the I/O request is
   * completed.
   */
8cb471e8f   Joel Becker   ocfs2: Take the i...
460
  void ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
461
462
463
  			       struct buffer_head *bh)
  {
  	int expand;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
464
465
466
  
  	/* The block may very well exist in our cache already, so avoid
  	 * doing any more work in that case. */
8cb471e8f   Joel Becker   ocfs2: Take the i...
467
  	if (ocfs2_buffer_cached(ci, bh))
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
468
  		return;
d701485a6   Tao Ma   ocfs2: Remove mas...
469
470
471
  	trace_ocfs2_set_buffer_uptodate_begin(
  		(unsigned long long)ocfs2_metadata_cache_owner(ci),
  		(unsigned long long)bh->b_blocknr);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
472
473
  
  	/* No need to recheck under spinlock - insertion is guarded by
6e5a3d753   Joel Becker   ocfs2: Change met...
474
475
  	 * co_io_lock() */
  	ocfs2_metadata_cache_lock(ci);
8cb471e8f   Joel Becker   ocfs2: Take the i...
476
  	if (ocfs2_insert_can_use_array(ci)) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
477
478
479
  		/* Fast case - it's an array and there's a free
  		 * spot. */
  		ocfs2_append_cache_array(ci, bh->b_blocknr);
6e5a3d753   Joel Becker   ocfs2: Change met...
480
  		ocfs2_metadata_cache_unlock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
481
482
483
484
  		return;
  	}
  
  	expand = 0;
47460d65a   Joel Becker   ocfs2: Make the o...
485
  	if (ci->ci_flags & OCFS2_CACHE_FL_INLINE) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
486
487
488
  		/* We need to bump things up to a tree. */
  		expand = 1;
  	}
6e5a3d753   Joel Becker   ocfs2: Change met...
489
  	ocfs2_metadata_cache_unlock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
490

8cb471e8f   Joel Becker   ocfs2: Take the i...
491
  	__ocfs2_set_buffer_uptodate(ci, bh->b_blocknr, expand);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
492
493
494
495
  }
  
  /* Called against a newly allocated buffer. Most likely nobody should
   * be able to read this sort of metadata while it's still being
6e5a3d753   Joel Becker   ocfs2: Change met...
496
   * allocated, but this is careful to take co_io_lock() anyway. */
8cb471e8f   Joel Becker   ocfs2: Take the i...
497
  void ocfs2_set_new_buffer_uptodate(struct ocfs2_caching_info *ci,
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
498
499
  				   struct buffer_head *bh)
  {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
500
  	/* This should definitely *not* exist in our cache */
8cb471e8f   Joel Becker   ocfs2: Take the i...
501
  	BUG_ON(ocfs2_buffer_cached(ci, bh));
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
502
503
  
  	set_buffer_uptodate(bh);
6e5a3d753   Joel Becker   ocfs2: Change met...
504
  	ocfs2_metadata_cache_io_lock(ci);
8cb471e8f   Joel Becker   ocfs2: Take the i...
505
  	ocfs2_set_buffer_uptodate(ci, bh);
6e5a3d753   Joel Becker   ocfs2: Change met...
506
  	ocfs2_metadata_cache_io_unlock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
507
508
509
510
511
512
513
514
  }
  
  /* Requires ip_lock. */
  static void ocfs2_remove_metadata_array(struct ocfs2_caching_info *ci,
  					int index)
  {
  	sector_t *array = ci->ci_cache.ci_array;
  	int bytes;
47460d65a   Joel Becker   ocfs2: Make the o...
515
  	BUG_ON(index < 0 || index >= OCFS2_CACHE_INFO_MAX_ARRAY);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
516
517
  	BUG_ON(index >= ci->ci_num_cached);
  	BUG_ON(!ci->ci_num_cached);
d701485a6   Tao Ma   ocfs2: Remove mas...
518
519
520
  	trace_ocfs2_remove_metadata_array(
  		(unsigned long long)ocfs2_metadata_cache_owner(ci),
  		index, ci->ci_num_cached);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
  
  	ci->ci_num_cached--;
  
  	/* don't need to copy if the array is now empty, or if we
  	 * removed at the tail */
  	if (ci->ci_num_cached && index < ci->ci_num_cached) {
  		bytes = sizeof(sector_t) * (ci->ci_num_cached - index);
  		memmove(&array[index], &array[index + 1], bytes);
  	}
  }
  
  /* Requires ip_lock. */
  static void ocfs2_remove_metadata_tree(struct ocfs2_caching_info *ci,
  				       struct ocfs2_meta_cache_item *item)
  {
d701485a6   Tao Ma   ocfs2: Remove mas...
536
537
538
  	trace_ocfs2_remove_metadata_tree(
  		(unsigned long long)ocfs2_metadata_cache_owner(ci),
  		(unsigned long long)item->c_block);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
539
540
541
542
  
  	rb_erase(&item->c_node, &ci->ci_cache.ci_tree);
  	ci->ci_num_cached--;
  }
8cb471e8f   Joel Becker   ocfs2: Take the i...
543
  static void ocfs2_remove_block_from_cache(struct ocfs2_caching_info *ci,
ac11c8271   Tao Ma   ocfs2: Add helper...
544
  					  sector_t block)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
545
546
  {
  	int index;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
547
  	struct ocfs2_meta_cache_item *item = NULL;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
548

6e5a3d753   Joel Becker   ocfs2: Change met...
549
  	ocfs2_metadata_cache_lock(ci);
d701485a6   Tao Ma   ocfs2: Remove mas...
550
551
552
553
  	trace_ocfs2_remove_block_from_cache(
  		(unsigned long long)ocfs2_metadata_cache_owner(ci),
  		(unsigned long long) block, ci->ci_num_cached,
  		ci->ci_flags);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
554

47460d65a   Joel Becker   ocfs2: Make the o...
555
  	if (ci->ci_flags & OCFS2_CACHE_FL_INLINE) {
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
556
557
558
559
560
561
562
563
  		index = ocfs2_search_cache_array(ci, block);
  		if (index != -1)
  			ocfs2_remove_metadata_array(ci, index);
  	} else {
  		item = ocfs2_search_cache_tree(ci, block);
  		if (item)
  			ocfs2_remove_metadata_tree(ci, item);
  	}
6e5a3d753   Joel Becker   ocfs2: Change met...
564
  	ocfs2_metadata_cache_unlock(ci);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
565
566
567
568
  
  	if (item)
  		kmem_cache_free(ocfs2_uptodate_cachep, item);
  }
ac11c8271   Tao Ma   ocfs2: Add helper...
569
570
571
572
573
  /*
   * Called when we remove a chunk of metadata from an inode. We don't
   * bother reverting things to an inlined array in the case of a remove
   * which moves us back under the limit.
   */
8cb471e8f   Joel Becker   ocfs2: Take the i...
574
  void ocfs2_remove_from_cache(struct ocfs2_caching_info *ci,
ac11c8271   Tao Ma   ocfs2: Add helper...
575
576
577
  			     struct buffer_head *bh)
  {
  	sector_t block = bh->b_blocknr;
8cb471e8f   Joel Becker   ocfs2: Take the i...
578
  	ocfs2_remove_block_from_cache(ci, block);
ac11c8271   Tao Ma   ocfs2: Add helper...
579
580
581
  }
  
  /* Called when we remove xattr clusters from an inode. */
8cb471e8f   Joel Becker   ocfs2: Take the i...
582
  void ocfs2_remove_xattr_clusters_from_cache(struct ocfs2_caching_info *ci,
ac11c8271   Tao Ma   ocfs2: Add helper...
583
584
585
  					    sector_t block,
  					    u32 c_len)
  {
8cb471e8f   Joel Becker   ocfs2: Take the i...
586
587
  	struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
  	unsigned int i, b_len = ocfs2_clusters_to_blocks(sb, 1) * c_len;
ac11c8271   Tao Ma   ocfs2: Add helper...
588
589
  
  	for (i = 0; i < b_len; i++, block++)
8cb471e8f   Joel Becker   ocfs2: Take the i...
590
  		ocfs2_remove_block_from_cache(ci, block);
ac11c8271   Tao Ma   ocfs2: Add helper...
591
  }
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
592
593
594
595
  int __init init_ocfs2_uptodate_cache(void)
  {
  	ocfs2_uptodate_cachep = kmem_cache_create("ocfs2_uptodate",
  				  sizeof(struct ocfs2_meta_cache_item),
20c2df83d   Paul Mundt   mm: Remove slab d...
596
  				  0, SLAB_HWCACHE_ALIGN, NULL);
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
597
598
  	if (!ocfs2_uptodate_cachep)
  		return -ENOMEM;
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
599
600
  	return 0;
  }
0c6c98fb1   Adrian Bunk   [PATCH] OCFS2: __...
601
  void exit_ocfs2_uptodate_cache(void)
ccd979bdb   Mark Fasheh   [PATCH] OCFS2: Th...
602
603
604
605
  {
  	if (ocfs2_uptodate_cachep)
  		kmem_cache_destroy(ocfs2_uptodate_cachep);
  }