aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6
diff options
context:
space:
mode:
authorNathan Scott <nathans@sgi.com>2006-06-09 00:58:38 -0400
committerNathan Scott <nathans@sgi.com>2006-06-09 00:58:38 -0400
commit7d04a335b6b2d79e3742ffd28bd651204574e794 (patch)
tree2b687202ae47c5e0c70a2b921b77135066131d8d /fs/xfs/linux-2.6
parentb76963fac4a17b661bad46e5a57b0f918c6f0cd1 (diff)
[XFS] Shutdown the filesystem if all device paths have gone. Made
shutdown vop flags consistent with sync vop flags declarations too. SGI-PV: 939911 SGI-Modid: xfs-linux-melb:xfs-kern:26096a 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.c15
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_vfs.h7
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.c16
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h2
5 files changed, 33 insertions, 9 deletions
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 4d191ef39b67..1fcdc0abda6e 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -136,9 +136,10 @@ xfs_destroy_ioend(
136 136
137 for (bh = ioend->io_buffer_head; bh; bh = next) { 137 for (bh = ioend->io_buffer_head; bh; bh = next) {
138 next = bh->b_private; 138 next = bh->b_private;
139 bh->b_end_io(bh, ioend->io_uptodate); 139 bh->b_end_io(bh, !ioend->io_error);
140 } 140 }
141 141 if (unlikely(ioend->io_error))
142 vn_ioerror(ioend->io_vnode, ioend->io_error, __FILE__,__LINE__);
142 vn_iowake(ioend->io_vnode); 143 vn_iowake(ioend->io_vnode);
143 mempool_free(ioend, xfs_ioend_pool); 144 mempool_free(ioend, xfs_ioend_pool);
144} 145}
@@ -185,7 +186,7 @@ xfs_end_bio_unwritten(
185 size_t size = ioend->io_size; 186 size_t size = ioend->io_size;
186 int error; 187 int error;
187 188
188 if (ioend->io_uptodate) 189 if (likely(!ioend->io_error))
189 VOP_BMAP(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL, error); 190 VOP_BMAP(vp, offset, size, BMAPI_UNWRITTEN, NULL, NULL, error);
190 xfs_destroy_ioend(ioend); 191 xfs_destroy_ioend(ioend);
191} 192}
@@ -211,7 +212,7 @@ xfs_alloc_ioend(
211 * all the I/O from calling the completion routine too early. 212 * all the I/O from calling the completion routine too early.
212 */ 213 */
213 atomic_set(&ioend->io_remaining, 1); 214 atomic_set(&ioend->io_remaining, 1);
214 ioend->io_uptodate = 1; /* cleared if any I/O fails */ 215 ioend->io_error = 0;
215 ioend->io_list = NULL; 216 ioend->io_list = NULL;
216 ioend->io_type = type; 217 ioend->io_type = type;
217 ioend->io_vnode = vn_from_inode(inode); 218 ioend->io_vnode = vn_from_inode(inode);
@@ -271,16 +272,14 @@ xfs_end_bio(
271 if (bio->bi_size) 272 if (bio->bi_size)
272 return 1; 273 return 1;
273 274
274 ASSERT(ioend);
275 ASSERT(atomic_read(&bio->bi_cnt) >= 1); 275 ASSERT(atomic_read(&bio->bi_cnt) >= 1);
276 ioend->io_error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : error;
276 277
277 /* Toss bio and pass work off to an xfsdatad thread */ 278 /* Toss bio and pass work off to an xfsdatad thread */
278 if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
279 ioend->io_uptodate = 0;
280 bio->bi_private = NULL; 279 bio->bi_private = NULL;
281 bio->bi_end_io = NULL; 280 bio->bi_end_io = NULL;
282
283 bio_put(bio); 281 bio_put(bio);
282
284 xfs_finish_ioend(ioend); 283 xfs_finish_ioend(ioend);
285 return 0; 284 return 0;
286} 285}
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 60716543c68b..41c7d2da638a 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -30,7 +30,7 @@ typedef void (*xfs_ioend_func_t)(void *);
30typedef struct xfs_ioend { 30typedef struct xfs_ioend {
31 struct xfs_ioend *io_list; /* next ioend in chain */ 31 struct xfs_ioend *io_list; /* next ioend in chain */
32 unsigned int io_type; /* delalloc / unwritten */ 32 unsigned int io_type; /* delalloc / unwritten */
33 unsigned int io_uptodate; /* I/O status register */ 33 int io_error; /* I/O error code */
34 atomic_t io_remaining; /* hold count */ 34 atomic_t io_remaining; /* hold count */
35 struct vnode *io_vnode; /* file being written to */ 35 struct vnode *io_vnode; /* file being written to */
36 struct buffer_head *io_buffer_head;/* buffer linked list head */ 36 struct buffer_head *io_buffer_head;/* buffer linked list head */
diff --git a/fs/xfs/linux-2.6/xfs_vfs.h b/fs/xfs/linux-2.6/xfs_vfs.h
index 841200c03092..2ca05043a0fd 100644
--- a/fs/xfs/linux-2.6/xfs_vfs.h
+++ b/fs/xfs/linux-2.6/xfs_vfs.h
@@ -94,6 +94,13 @@ typedef enum {
94#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */ 94#define SYNC_REMOUNT 0x0080 /* remount readonly, no dummy LRs */
95#define SYNC_QUIESCE 0x0100 /* quiesce filesystem for a snapshot */ 95#define SYNC_QUIESCE 0x0100 /* quiesce filesystem for a snapshot */
96 96
97#define SHUTDOWN_META_IO_ERROR 0x0001 /* write attempt to metadata failed */
98#define SHUTDOWN_LOG_IO_ERROR 0x0002 /* write attempt to the log failed */
99#define SHUTDOWN_FORCE_UMOUNT 0x0004 /* shutdown from a forced unmount */
100#define SHUTDOWN_CORRUPT_INCORE 0x0008 /* corrupt in-memory data structures */
101#define SHUTDOWN_REMOTE_REQ 0x0010 /* shutdown came from remote cell */
102#define SHUTDOWN_DEVICE_REQ 0x0020 /* failed all paths to the device */
103
97typedef int (*vfs_mount_t)(bhv_desc_t *, 104typedef int (*vfs_mount_t)(bhv_desc_t *,
98 struct xfs_mount_args *, struct cred *); 105 struct xfs_mount_args *, struct cred *);
99typedef int (*vfs_parseargs_t)(bhv_desc_t *, char *, 106typedef int (*vfs_parseargs_t)(bhv_desc_t *, char *,
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c
index d27c25b27ccd..f17e39cff230 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.c
+++ b/fs/xfs/linux-2.6/xfs_vnode.c
@@ -54,6 +54,22 @@ vn_iowake(
54 wake_up(vptosync(vp)); 54 wake_up(vptosync(vp));
55} 55}
56 56
57/*
58 * Volume managers supporting multiple paths can send back ENODEV when the
59 * final path disappears. In this case continuing to fill the page cache
60 * with dirty data which cannot be written out is evil, so prevent that.
61 */
62void
63vn_ioerror(
64 struct vnode *vp,
65 int error,
66 char *f,
67 int l)
68{
69 if (unlikely(error == -ENODEV))
70 VFS_FORCE_SHUTDOWN(vp->v_vfsp, SHUTDOWN_DEVICE_REQ, f, l);
71}
72
57struct vnode * 73struct vnode *
58vn_initialize( 74vn_initialize(
59 struct inode *inode) 75 struct inode *inode)
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 2a8e16c22353..a64b7db67003 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -514,6 +514,8 @@ extern void vn_revalidate_core(struct vnode *, vattr_t *);
514extern void vn_iowait(struct vnode *vp); 514extern void vn_iowait(struct vnode *vp);
515extern void vn_iowake(struct vnode *vp); 515extern void vn_iowake(struct vnode *vp);
516 516
517extern void vn_ioerror(struct vnode *vp, int error, char *f, int l);
518
517static inline int vn_count(struct vnode *vp) 519static inline int vn_count(struct vnode *vp)
518{ 520{
519 return atomic_read(&vn_to_inode(vp)->i_count); 521 return atomic_read(&vn_to_inode(vp)->i_count);