aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6')
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c5
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h8
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c66
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h1
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 */
284STATIC int
285xfs_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
315void
316xfs_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
341void
342xfs_blkdev_issue_flush(
343 xfs_buftarg_t *buftarg)
344{
345 blkdev_issue_flush(buftarg->pbr_bdev, NULL);
346}
281 347
282STATIC struct inode * 348STATIC struct inode *
283linvfs_alloc_inode( 349linvfs_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 *);
132extern int xfs_blkdev_get(struct xfs_mount *, const char *, 132extern int xfs_blkdev_get(struct xfs_mount *, const char *,
133 struct block_device **); 133 struct block_device **);
134extern void xfs_blkdev_put(struct block_device *); 134extern void xfs_blkdev_put(struct block_device *);
135extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
135 136
136extern struct export_operations linvfs_export_ops; 137extern struct export_operations linvfs_export_ops;
137 138