[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>
This commit is contained in:
parent
c1a073bdff
commit
56d433e430
|
@ -383,18 +383,34 @@ linvfs_clear_inode(
|
||||||
struct inode *inode)
|
struct inode *inode)
|
||||||
{
|
{
|
||||||
vnode_t *vp = LINVFS_GET_VP(inode);
|
vnode_t *vp = LINVFS_GET_VP(inode);
|
||||||
|
int error, cache;
|
||||||
|
|
||||||
if (vp) {
|
vn_trace_entry(vp, "clear_inode", (inst_t *)__return_address);
|
||||||
vn_rele(vp);
|
|
||||||
vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address);
|
ASSERT(vp->v_fbhv != NULL);
|
||||||
/*
|
|
||||||
* Do all our cleanup, and remove this vnode.
|
XFS_STATS_INC(vn_rele);
|
||||||
*/
|
XFS_STATS_INC(vn_remove);
|
||||||
vn_remove(vp);
|
XFS_STATS_INC(vn_reclaim);
|
||||||
}
|
XFS_STATS_DEC(vn_active);
|
||||||
|
|
||||||
|
VOP_INACTIVE(vp, NULL, cache);
|
||||||
|
|
||||||
|
VN_LOCK(vp);
|
||||||
|
vp->v_flag &= ~VMODIFIED;
|
||||||
|
VN_UNLOCK(vp, 0);
|
||||||
|
|
||||||
|
VOP_RECLAIM(vp, error);
|
||||||
|
if (error)
|
||||||
|
panic("vn_purge: cannot reclaim");
|
||||||
|
|
||||||
|
ASSERT(vp->v_fbhv == NULL);
|
||||||
|
|
||||||
|
#ifdef XFS_VNODE_TRACE
|
||||||
|
ktrace_free(vp->v_trace);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enqueue a work item to be picked up by the vfs xfssyncd thread.
|
* Enqueue a work item to be picked up by the vfs xfssyncd thread.
|
||||||
* Doing this has two advantages:
|
* Doing this has two advantages:
|
||||||
|
|
|
@ -71,39 +71,6 @@ vn_iowake(
|
||||||
wake_up(vptosync(vp));
|
wake_up(vptosync(vp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Clean a vnode of filesystem-specific data and prepare it for reuse.
|
|
||||||
*/
|
|
||||||
STATIC int
|
|
||||||
vn_reclaim(
|
|
||||||
struct vnode *vp)
|
|
||||||
{
|
|
||||||
int error;
|
|
||||||
|
|
||||||
XFS_STATS_INC(vn_reclaim);
|
|
||||||
vn_trace_entry(vp, "vn_reclaim", (inst_t *)__return_address);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Only make the VOP_RECLAIM call if there are behaviors
|
|
||||||
* to call.
|
|
||||||
*/
|
|
||||||
if (vp->v_fbhv) {
|
|
||||||
VOP_RECLAIM(vp, error);
|
|
||||||
if (error)
|
|
||||||
return -error;
|
|
||||||
}
|
|
||||||
ASSERT(vp->v_fbhv == NULL);
|
|
||||||
|
|
||||||
vp->v_fbhv = NULL;
|
|
||||||
|
|
||||||
#ifdef XFS_VNODE_TRACE
|
|
||||||
ktrace_free(vp->v_trace);
|
|
||||||
vp->v_trace = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct vnode *
|
struct vnode *
|
||||||
vn_initialize(
|
vn_initialize(
|
||||||
struct inode *inode)
|
struct inode *inode)
|
||||||
|
@ -197,51 +164,6 @@ vn_revalidate(
|
||||||
return -error;
|
return -error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* purge a vnode from the cache
|
|
||||||
* At this point the vnode is guaranteed to have no references (vn_count == 0)
|
|
||||||
* The caller has to make sure that there are no ways someone could
|
|
||||||
* get a handle (via vn_get) on the vnode (usually done via a mount/vfs lock).
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
vn_purge(
|
|
||||||
struct vnode *vp,
|
|
||||||
vmap_t *vmap)
|
|
||||||
{
|
|
||||||
vn_trace_entry(vp, "vn_purge", (inst_t *)__return_address);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check whether vp has already been reclaimed since our caller
|
|
||||||
* sampled its version while holding a filesystem cache lock that
|
|
||||||
* its VOP_RECLAIM function acquires.
|
|
||||||
*/
|
|
||||||
VN_LOCK(vp);
|
|
||||||
if (vp->v_number != vmap->v_number) {
|
|
||||||
VN_UNLOCK(vp, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Another process could have raced in and gotten this vnode...
|
|
||||||
*/
|
|
||||||
if (vn_count(vp) > 0) {
|
|
||||||
VN_UNLOCK(vp, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
XFS_STATS_DEC(vn_active);
|
|
||||||
VN_UNLOCK(vp, 0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Call VOP_RECLAIM and clean vp. The FSYNC_INVAL flag tells
|
|
||||||
* vp's filesystem to flush and invalidate all cached resources.
|
|
||||||
* When vn_reclaim returns, vp should have no private data,
|
|
||||||
* either in a system cache or attached to v_data.
|
|
||||||
*/
|
|
||||||
if (vn_reclaim(vp) != 0)
|
|
||||||
panic("vn_purge: cannot reclaim");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a reference to a referenced vnode.
|
* Add a reference to a referenced vnode.
|
||||||
*/
|
*/
|
||||||
|
@ -261,72 +183,6 @@ vn_hold(
|
||||||
return vp;
|
return vp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Call VOP_INACTIVE on last reference.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
vn_rele(
|
|
||||||
struct vnode *vp)
|
|
||||||
{
|
|
||||||
int vcnt;
|
|
||||||
int cache;
|
|
||||||
|
|
||||||
XFS_STATS_INC(vn_rele);
|
|
||||||
|
|
||||||
VN_LOCK(vp);
|
|
||||||
|
|
||||||
vn_trace_entry(vp, "vn_rele", (inst_t *)__return_address);
|
|
||||||
vcnt = vn_count(vp);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Since we always get called from put_inode we know
|
|
||||||
* that i_count won't be decremented after we
|
|
||||||
* return.
|
|
||||||
*/
|
|
||||||
if (!vcnt) {
|
|
||||||
VN_UNLOCK(vp, 0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Do not make the VOP_INACTIVE call if there
|
|
||||||
* are no behaviors attached to the vnode to call.
|
|
||||||
*/
|
|
||||||
if (vp->v_fbhv)
|
|
||||||
VOP_INACTIVE(vp, NULL, cache);
|
|
||||||
|
|
||||||
VN_LOCK(vp);
|
|
||||||
vp->v_flag &= ~VMODIFIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
VN_UNLOCK(vp, 0);
|
|
||||||
|
|
||||||
vn_trace_exit(vp, "vn_rele", (inst_t *)__return_address);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Finish the removal of a vnode.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
vn_remove(
|
|
||||||
struct vnode *vp)
|
|
||||||
{
|
|
||||||
vmap_t vmap;
|
|
||||||
|
|
||||||
/* Make sure we don't do this to the same vnode twice */
|
|
||||||
if (!(vp->v_fbhv))
|
|
||||||
return;
|
|
||||||
|
|
||||||
XFS_STATS_INC(vn_remove);
|
|
||||||
vn_trace_exit(vp, "vn_remove", (inst_t *)__return_address);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* After the following purge the vnode
|
|
||||||
* will no longer exist.
|
|
||||||
*/
|
|
||||||
VMAP(vp, vmap);
|
|
||||||
vn_purge(vp, &vmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef XFS_VNODE_TRACE
|
#ifdef XFS_VNODE_TRACE
|
||||||
|
|
||||||
#define KTRACE_ENTER(vp, vk, s, line, ra) \
|
#define KTRACE_ENTER(vp, vk, s, line, ra) \
|
||||||
|
|
|
@ -502,10 +502,8 @@ typedef struct vnode_map {
|
||||||
(vmap).v_number = (vp)->v_number, \
|
(vmap).v_number = (vp)->v_number, \
|
||||||
(vmap).v_ino = (vp)->v_inode.i_ino; }
|
(vmap).v_ino = (vp)->v_inode.i_ino; }
|
||||||
|
|
||||||
extern void vn_purge(struct vnode *, vmap_t *);
|
|
||||||
extern int vn_revalidate(struct vnode *);
|
extern int vn_revalidate(struct vnode *);
|
||||||
extern void vn_revalidate_core(struct vnode *, vattr_t *);
|
extern void vn_revalidate_core(struct vnode *, vattr_t *);
|
||||||
extern void vn_remove(struct vnode *);
|
|
||||||
|
|
||||||
extern void vn_iowait(struct vnode *vp);
|
extern void vn_iowait(struct vnode *vp);
|
||||||
extern void vn_iowake(struct vnode *vp);
|
extern void vn_iowake(struct vnode *vp);
|
||||||
|
@ -519,7 +517,6 @@ static inline int vn_count(struct vnode *vp)
|
||||||
* Vnode reference counting functions (and macros for compatibility).
|
* Vnode reference counting functions (and macros for compatibility).
|
||||||
*/
|
*/
|
||||||
extern vnode_t *vn_hold(struct vnode *);
|
extern vnode_t *vn_hold(struct vnode *);
|
||||||
extern void vn_rele(struct vnode *);
|
|
||||||
|
|
||||||
#if defined(XFS_VNODE_TRACE)
|
#if defined(XFS_VNODE_TRACE)
|
||||||
#define VN_HOLD(vp) \
|
#define VN_HOLD(vp) \
|
||||||
|
|
Loading…
Reference in a new issue