aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@sgi.com>2005-09-04 18:23:54 -0400
committerNathan Scott <nathans@sgi.com>2005-09-04 18:23:54 -0400
commit56d433e430eb399a4b6d0e73d28af6e1d4713547 (patch)
treed43aa8b457e52d80254e8c621b01ecc5b20d05ab /fs/xfs
parentc1a073bdff997216eac25254a2716faf640e4e8d (diff)
[XFS] streamline the clear_inode path
SGI-PV: 940531 SGI-Modid: xfs-linux:xfs-kern:196888a Signed-off-by: Christoph Hellwig <hch@sgi.com> Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c34
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c144
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h3
3 files changed, 25 insertions, 156 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 1a0bcbbc0a86..9b40a2799f7e 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -383,17 +383,33 @@ linvfs_clear_inode(
383 struct inode *inode) 383 struct inode *inode)
384{ 384{
385 vnode_t *vp = LINVFS_GET_VP(inode); 385 vnode_t *vp = LINVFS_GET_VP(inode);
386 int error, cache;
386 387
387 if (vp) { 388 vn_trace_entry(vp, "clear_inode", (inst_t *)__return_address);
388 vn_rele(vp); 389
389 vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); 390 ASSERT(vp->v_fbhv != NULL);
390 /* 391
391 * Do all our cleanup, and remove this vnode. 392 XFS_STATS_INC(vn_rele);
392 */ 393 XFS_STATS_INC(vn_remove);
393 vn_remove(vp); 394 XFS_STATS_INC(vn_reclaim);
394 } 395 XFS_STATS_DEC(vn_active);
395}
396 396
397 VOP_INACTIVE(vp, NULL, cache);
398
399 VN_LOCK(vp);
400 vp->v_flag &= ~VMODIFIED;
401 VN_UNLOCK(vp, 0);
402
403 VOP_RECLAIM(vp, error);
404 if (error)
405 panic("vn_purge: cannot reclaim");
406
407 ASSERT(vp->v_fbhv == NULL);
408
409#ifdef XFS_VNODE_TRACE
410 ktrace_free(vp->v_trace);
411#endif
412}
397 413
398/* 414/*
399 * Enqueue a work item to be picked up by the vfs xfssyncd thread. 415 * Enqueue a work item to be picked up by the vfs xfssyncd thread.
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index 46afc86a2862..268f45bf6a9a 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -71,39 +71,6 @@ vn_iowake(
71 wake_up(vptosync(vp)); 71 wake_up(vptosync(vp));
72} 72}
73 73
74/*
75 * Clean a vnode of filesystem-specific data and prepare it for reuse.
76 */
77STATIC int
78vn_reclaim(
79 struct vnode *vp)
80{
81 int error;
82
83 XFS_STATS_INC(vn_reclaim);
84 vn_trace_entry(vp, "vn_reclaim", (inst_t *)__return_address);
85
86 /*
87 * Only make the VOP_RECLAIM call if there are behaviors
88 * to call.
89 */
90 if (vp->v_fbhv) {
91 VOP_RECLAIM(vp, error);
92 if (error)
93 return -error;
94 }
95 ASSERT(vp->v_fbhv == NULL);
96
97 vp->v_fbhv = NULL;
98
99#ifdef XFS_VNODE_TRACE
100 ktrace_free(vp->v_trace);
101 vp->v_trace = NULL;
102#endif
103
104 return 0;
105}
106
107struct vnode * 74struct vnode *
108vn_initialize( 75vn_initialize(
109 struct inode *inode) 76 struct inode *inode)
@@ -198,51 +165,6 @@ vn_revalidate(
198} 165}
199 166
200/* 167/*
201 * purge a vnode from the cache
202 * At this point the vnode is guaranteed to have no references (vn_count == 0)
203 * The caller has to make sure that there are no ways someone could
204 * get a handle (via vn_get) on the vnode (usually done via a mount/vfs lock).
205 */
206void
207vn_purge(
208 struct vnode *vp,
209 vmap_t *vmap)
210{
211 vn_trace_entry(vp, "vn_purge", (inst_t *)__return_address);
212
213 /*
214 * Check whether vp has already been reclaimed since our caller
215 * sampled its version while holding a filesystem cache lock that
216 * its VOP_RECLAIM function acquires.
217 */
218 VN_LOCK(vp);
219 if (vp->v_number != vmap->v_number) {
220 VN_UNLOCK(vp, 0);
221 return;
222 }
223
224 /*
225 * Another process could have raced in and gotten this vnode...
226 */
227 if (vn_count(vp) > 0) {
228 VN_UNLOCK(vp, 0);
229 return;
230 }
231
232 XFS_STATS_DEC(vn_active);
233 VN_UNLOCK(vp, 0);
234
235 /*
236 * Call VOP_RECLAIM and clean vp. The FSYNC_INVAL flag tells
237 * vp's filesystem to flush and invalidate all cached resources.
238 * When vn_reclaim returns, vp should have no private data,
239 * either in a system cache or attached to v_data.
240 */
241 if (vn_reclaim(vp) != 0)
242 panic("vn_purge: cannot reclaim");
243}
244
245/*
246 * Add a reference to a referenced vnode. 168 * Add a reference to a referenced vnode.
247 */ 169 */
248struct vnode * 170struct vnode *
@@ -261,72 +183,6 @@ vn_hold(
261 return vp; 183 return vp;
262} 184}
263 185
264/*
265 * Call VOP_INACTIVE on last reference.
266 */
267void
268vn_rele(
269 struct vnode *vp)
270{
271 int vcnt;
272 int cache;
273
274 XFS_STATS_INC(vn_rele);
275
276 VN_LOCK(vp);
277
278 vn_trace_entry(vp, "vn_rele", (inst_t *)__return_address);
279 vcnt = vn_count(vp);
280
281 /*
282 * Since we always get called from put_inode we know
283 * that i_count won't be decremented after we
284 * return.
285 */
286 if (!vcnt) {
287 VN_UNLOCK(vp, 0);
288
289 /*
290 * Do not make the VOP_INACTIVE call if there
291 * are no behaviors attached to the vnode to call.
292 */
293 if (vp->v_fbhv)
294 VOP_INACTIVE(vp, NULL, cache);
295
296 VN_LOCK(vp);
297 vp->v_flag &= ~VMODIFIED;
298 }
299
300 VN_UNLOCK(vp, 0);
301
302 vn_trace_exit(vp, "vn_rele", (inst_t *)__return_address);
303}
304
305/*
306 * Finish the removal of a vnode.
307 */
308void
309vn_remove(
310 struct vnode *vp)
311{
312 vmap_t vmap;
313
314 /* Make sure we don't do this to the same vnode twice */
315 if (!(vp->v_fbhv))
316 return;
317
318 XFS_STATS_INC(vn_remove);
319 vn_trace_exit(vp, "vn_remove", (inst_t *)__return_address);
320
321 /*
322 * After the following purge the vnode
323 * will no longer exist.
324 */
325 VMAP(vp, vmap);
326 vn_purge(vp, &vmap);
327}
328
329
330#ifdef XFS_VNODE_TRACE 186#ifdef XFS_VNODE_TRACE
331 187
332#define KTRACE_ENTER(vp, vk, s, line, ra) \ 188#define KTRACE_ENTER(vp, vk, s, line, ra) \
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 9977afa38900..35f306cebb87 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -502,10 +502,8 @@ typedef struct vnode_map {
502 (vmap).v_number = (vp)->v_number, \ 502 (vmap).v_number = (vp)->v_number, \
503 (vmap).v_ino = (vp)->v_inode.i_ino; } 503 (vmap).v_ino = (vp)->v_inode.i_ino; }
504 504
505extern void vn_purge(struct vnode *, vmap_t *);
506extern int vn_revalidate(struct vnode *); 505extern int vn_revalidate(struct vnode *);
507extern void vn_revalidate_core(struct vnode *, vattr_t *); 506extern void vn_revalidate_core(struct vnode *, vattr_t *);
508extern void vn_remove(struct vnode *);
509 507
510extern void vn_iowait(struct vnode *vp); 508extern void vn_iowait(struct vnode *vp);
511extern void vn_iowake(struct vnode *vp); 509extern void vn_iowake(struct vnode *vp);
@@ -519,7 +517,6 @@ static inline int vn_count(struct vnode *vp)
519 * Vnode reference counting functions (and macros for compatibility). 517 * Vnode reference counting functions (and macros for compatibility).
520 */ 518 */
521extern vnode_t *vn_hold(struct vnode *); 519extern vnode_t *vn_hold(struct vnode *);
522extern void vn_rele(struct vnode *);
523 520
524#if defined(XFS_VNODE_TRACE) 521#if defined(XFS_VNODE_TRACE)
525#define VN_HOLD(vp) \ 522#define VN_HOLD(vp) \