aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@sgi.com>2005-09-02 02:58:38 -0400
committerNathan Scott <nathans@sgi.com>2005-09-02 02:58:38 -0400
commit51c91ed52b8a9a30fcb2a465b40c20a1f11735ba (patch)
treeedebb01cbfe550a2edb066d5b4185445cfff11ba /fs/xfs/linux-2.6
parent592cb26bda6fe69838529acf71e50a6dee7acbb4 (diff)
[XFS] add infrastructure for waiting on I/O completion at inode reclaim
time SGI-PV: 934766 SGI-Modid: xfs-linux:xfs-kern:196854a Signed-off-by: Christoph Hellwig <hch@sgi.com> Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6')
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c11
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c28
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h4
3 files changed, 29 insertions, 14 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index bd9aba1f2353..b55cb7f02e88 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -139,7 +139,7 @@ linvfs_unwritten_convert(
139 XFS_BUF_SET_FSPRIVATE(bp, NULL); 139 XFS_BUF_SET_FSPRIVATE(bp, NULL);
140 XFS_BUF_CLR_IODONE_FUNC(bp); 140 XFS_BUF_CLR_IODONE_FUNC(bp);
141 XFS_BUF_UNDATAIO(bp); 141 XFS_BUF_UNDATAIO(bp);
142 iput(LINVFS_GET_IP(vp)); 142 vn_iowake(vp);
143 pagebuf_iodone(bp, 0, 0); 143 pagebuf_iodone(bp, 0, 0);
144} 144}
145 145
@@ -448,14 +448,7 @@ xfs_map_unwritten(
448 if (!pb) 448 if (!pb)
449 return -EAGAIN; 449 return -EAGAIN;
450 450
451 /* Take a reference to the inode to prevent it from 451 atomic_inc(&LINVFS_GET_VP(inode)->v_iocount);
452 * being reclaimed while we have outstanding unwritten
453 * extent IO on it.
454 */
455 if ((igrab(inode)) != inode) {
456 pagebuf_free(pb);
457 return -EAGAIN;
458 }
459 452
460 /* Set the count to 1 initially, this will stop an I/O 453 /* Set the count to 1 initially, this will stop an I/O
461 * completion callout which happens before we have started 454 * completion callout which happens before we have started
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index 654da98de2a5..46afc86a2862 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -42,17 +42,33 @@ DEFINE_SPINLOCK(vnumber_lock);
42 */ 42 */
43#define NVSYNC 37 43#define NVSYNC 37
44#define vptosync(v) (&vsync[((unsigned long)v) % NVSYNC]) 44#define vptosync(v) (&vsync[((unsigned long)v) % NVSYNC])
45sv_t vsync[NVSYNC]; 45STATIC wait_queue_head_t vsync[NVSYNC];
46 46
47 47
48void 48void
49vn_init(void) 49vn_init(void)
50{ 50{
51 register sv_t *svp; 51 int i;
52 register int i;
53 52
54 for (svp = vsync, i = 0; i < NVSYNC; i++, svp++) 53 for (i = 0; i < NVSYNC; i++)
55 init_sv(svp, SV_DEFAULT, "vsy", i); 54 init_waitqueue_head(&vsync[i]);
55}
56
57void
58vn_iowait(
59 struct vnode *vp)
60{
61 wait_queue_head_t *wq = vptosync(vp);
62
63 wait_event(*wq, (atomic_read(&vp->v_iocount) == 0));
64}
65
66void
67vn_iowake(
68 struct vnode *vp)
69{
70 if (atomic_dec_and_test(&vp->v_iocount))
71 wake_up(vptosync(vp));
56} 72}
57 73
58/* 74/*
@@ -111,6 +127,8 @@ vn_initialize(
111 /* Initialize the first behavior and the behavior chain head. */ 127 /* Initialize the first behavior and the behavior chain head. */
112 vn_bhv_head_init(VN_BHV_HEAD(vp), "vnode"); 128 vn_bhv_head_init(VN_BHV_HEAD(vp), "vnode");
113 129
130 atomic_set(&vp->v_iocount, 0);
131
114#ifdef XFS_VNODE_TRACE 132#ifdef XFS_VNODE_TRACE
115 vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP); 133 vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP);
116#endif /* XFS_VNODE_TRACE */ 134#endif /* XFS_VNODE_TRACE */
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 4a74569a5690..9977afa38900 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -80,6 +80,7 @@ typedef struct vnode {
80 vnumber_t v_number; /* in-core vnode number */ 80 vnumber_t v_number; /* in-core vnode number */
81 vn_bhv_head_t v_bh; /* behavior head */ 81 vn_bhv_head_t v_bh; /* behavior head */
82 spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */ 82 spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */
83 atomic_t v_iocount; /* outstanding I/O count */
83#ifdef XFS_VNODE_TRACE 84#ifdef XFS_VNODE_TRACE
84 struct ktrace *v_trace; /* trace header structure */ 85 struct ktrace *v_trace; /* trace header structure */
85#endif 86#endif
@@ -506,6 +507,9 @@ extern int vn_revalidate(struct vnode *);
506extern void vn_revalidate_core(struct vnode *, vattr_t *); 507extern void vn_revalidate_core(struct vnode *, vattr_t *);
507extern void vn_remove(struct vnode *); 508extern void vn_remove(struct vnode *);
508 509
510extern void vn_iowait(struct vnode *vp);
511extern void vn_iowake(struct vnode *vp);
512
509static inline int vn_count(struct vnode *vp) 513static inline int vn_count(struct vnode *vp)
510{ 514{
511 return atomic_read(&LINVFS_GET_IP(vp)->i_count); 515 return atomic_read(&LINVFS_GET_IP(vp)->i_count);