diff options
Diffstat (limited to 'fs/xfs/linux-2.6')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.c | 5 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.h | 8 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.c | 66 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_super.h | 1 |
4 files changed, 76 insertions, 4 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 188cbbd5b74a..4663f7dbff1c 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -1295,6 +1295,11 @@ _pagebuf_ioapply( | |||
1295 | rw = (pb->pb_flags & PBF_READ) ? READ : WRITE; | 1295 | rw = (pb->pb_flags & PBF_READ) ? READ : WRITE; |
1296 | } | 1296 | } |
1297 | 1297 | ||
1298 | if (pb->pb_flags & PBF_ORDERED) { | ||
1299 | ASSERT(!(pb->pb_flags & PBF_READ)); | ||
1300 | rw = WRITE_BARRIER; | ||
1301 | } | ||
1302 | |||
1298 | /* Special code path for reading a sub page size pagebuf in -- | 1303 | /* Special code path for reading a sub page size pagebuf in -- |
1299 | * we populate up the whole page, and hence the other metadata | 1304 | * we populate up the whole page, and hence the other metadata |
1300 | * in the same page. This optimization is only valid when the | 1305 | * in the same page. This optimization is only valid when the |
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 39c8ca122534..fa21d1f9cb0b 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h | |||
@@ -74,7 +74,7 @@ typedef enum page_buf_flags_e { /* pb_flags values */ | |||
74 | PBF_DELWRI = (1 << 6), /* buffer has dirty pages */ | 74 | PBF_DELWRI = (1 << 6), /* buffer has dirty pages */ |
75 | PBF_STALE = (1 << 7), /* buffer has been staled, do not find it */ | 75 | PBF_STALE = (1 << 7), /* buffer has been staled, do not find it */ |
76 | PBF_FS_MANAGED = (1 << 8), /* filesystem controls freeing memory */ | 76 | PBF_FS_MANAGED = (1 << 8), /* filesystem controls freeing memory */ |
77 | PBF_FLUSH = (1 << 11), /* flush disk write cache */ | 77 | PBF_ORDERED = (1 << 11), /* use ordered writes */ |
78 | PBF_READ_AHEAD = (1 << 12), /* asynchronous read-ahead */ | 78 | PBF_READ_AHEAD = (1 << 12), /* asynchronous read-ahead */ |
79 | 79 | ||
80 | /* flags used only as arguments to access routines */ | 80 | /* flags used only as arguments to access routines */ |
@@ -383,9 +383,9 @@ extern void pagebuf_trace( | |||
383 | #define XFS_BUF_UNASYNC(x) ((x)->pb_flags &= ~PBF_ASYNC) | 383 | #define XFS_BUF_UNASYNC(x) ((x)->pb_flags &= ~PBF_ASYNC) |
384 | #define XFS_BUF_ISASYNC(x) ((x)->pb_flags & PBF_ASYNC) | 384 | #define XFS_BUF_ISASYNC(x) ((x)->pb_flags & PBF_ASYNC) |
385 | 385 | ||
386 | #define XFS_BUF_FLUSH(x) ((x)->pb_flags |= PBF_FLUSH) | 386 | #define XFS_BUF_ORDERED(x) ((x)->pb_flags |= PBF_ORDERED) |
387 | #define XFS_BUF_UNFLUSH(x) ((x)->pb_flags &= ~PBF_FLUSH) | 387 | #define XFS_BUF_UNORDERED(x) ((x)->pb_flags &= ~PBF_ORDERED) |
388 | #define XFS_BUF_ISFLUSH(x) ((x)->pb_flags & PBF_FLUSH) | 388 | #define XFS_BUF_ISORDERED(x) ((x)->pb_flags & PBF_ORDERED) |
389 | 389 | ||
390 | #define XFS_BUF_SHUT(x) printk("XFS_BUF_SHUT not implemented yet\n") | 390 | #define XFS_BUF_SHUT(x) printk("XFS_BUF_SHUT not implemented yet\n") |
391 | #define XFS_BUF_UNSHUT(x) printk("XFS_BUF_UNSHUT not implemented yet\n") | 391 | #define XFS_BUF_UNSHUT(x) printk("XFS_BUF_UNSHUT not implemented yet\n") |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 2302454d8d47..d2701cc624b9 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -278,6 +278,72 @@ xfs_blkdev_put( | |||
278 | close_bdev_excl(bdev); | 278 | close_bdev_excl(bdev); |
279 | } | 279 | } |
280 | 280 | ||
281 | /* | ||
282 | * Try to write out the superblock using barriers. | ||
283 | */ | ||
284 | STATIC int | ||
285 | xfs_barrier_test( | ||
286 | xfs_mount_t *mp) | ||
287 | { | ||
288 | xfs_buf_t *sbp = xfs_getsb(mp, 0); | ||
289 | int error; | ||
290 | |||
291 | XFS_BUF_UNDONE(sbp); | ||
292 | XFS_BUF_UNREAD(sbp); | ||
293 | XFS_BUF_UNDELAYWRITE(sbp); | ||
294 | XFS_BUF_WRITE(sbp); | ||
295 | XFS_BUF_UNASYNC(sbp); | ||
296 | XFS_BUF_ORDERED(sbp); | ||
297 | |||
298 | xfsbdstrat(mp, sbp); | ||
299 | error = xfs_iowait(sbp); | ||
300 | |||
301 | /* | ||
302 | * Clear all the flags we set and possible error state in the | ||
303 | * buffer. We only did the write to try out whether barriers | ||
304 | * worked and shouldn't leave any traces in the superblock | ||
305 | * buffer. | ||
306 | */ | ||
307 | XFS_BUF_DONE(sbp); | ||
308 | XFS_BUF_ERROR(sbp, 0); | ||
309 | XFS_BUF_UNORDERED(sbp); | ||
310 | |||
311 | xfs_buf_relse(sbp); | ||
312 | return error; | ||
313 | } | ||
314 | |||
315 | void | ||
316 | xfs_mountfs_check_barriers(xfs_mount_t *mp) | ||
317 | { | ||
318 | int error; | ||
319 | |||
320 | if (mp->m_logdev_targp != mp->m_ddev_targp) { | ||
321 | xfs_fs_cmn_err(CE_NOTE, mp, | ||
322 | "Disabling barriers, not supported with external log device"); | ||
323 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | ||
324 | } | ||
325 | |||
326 | if (mp->m_ddev_targp->pbr_bdev->bd_disk->queue->ordered == | ||
327 | QUEUE_ORDERED_NONE) { | ||
328 | xfs_fs_cmn_err(CE_NOTE, mp, | ||
329 | "Disabling barriers, not supported by the underlying device"); | ||
330 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | ||
331 | } | ||
332 | |||
333 | error = xfs_barrier_test(mp); | ||
334 | if (error) { | ||
335 | xfs_fs_cmn_err(CE_NOTE, mp, | ||
336 | "Disabling barriers, trial barrier write failed"); | ||
337 | mp->m_flags &= ~XFS_MOUNT_BARRIER; | ||
338 | } | ||
339 | } | ||
340 | |||
341 | void | ||
342 | xfs_blkdev_issue_flush( | ||
343 | xfs_buftarg_t *buftarg) | ||
344 | { | ||
345 | blkdev_issue_flush(buftarg->pbr_bdev, NULL); | ||
346 | } | ||
281 | 347 | ||
282 | STATIC struct inode * | 348 | STATIC struct inode * |
283 | linvfs_alloc_inode( | 349 | linvfs_alloc_inode( |
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h index ec7e0035c731..ad77e3743e04 100644 --- a/fs/xfs/linux-2.6/xfs_super.h +++ b/fs/xfs/linux-2.6/xfs_super.h | |||
@@ -132,6 +132,7 @@ extern void xfs_flush_device(struct xfs_inode *); | |||
132 | extern int xfs_blkdev_get(struct xfs_mount *, const char *, | 132 | extern int xfs_blkdev_get(struct xfs_mount *, const char *, |
133 | struct block_device **); | 133 | struct block_device **); |
134 | extern void xfs_blkdev_put(struct block_device *); | 134 | extern void xfs_blkdev_put(struct block_device *); |
135 | extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); | ||
135 | 136 | ||
136 | extern struct export_operations linvfs_export_ops; | 137 | extern struct export_operations linvfs_export_ops; |
137 | 138 | ||