Commit cd4816fe authored by Nathan Scott's avatar Nathan Scott Committed by Stephen Lord

[XFS] Implement support for unwritten extents in XFS.

SGI Modid: 2.5.x-xfs:slinx:141508a
parent 1d1c803e
This diff is collapsed.
......@@ -66,5 +66,6 @@ extern struct file_operations linvfs_dir_operations;
extern struct address_space_operations linvfs_aops;
extern int linvfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
extern void linvfs_unwritten_done(struct buffer_head *, int);
#endif /* __XFS_IOPS_H__ */
......@@ -69,6 +69,20 @@
#define STATIC static
#endif
/*
* State flag for unwritten extent buffers.
*
* We need to be able to distinguish between these and delayed
* allocate buffers within XFS. The generic IO path code does
* not need to distinguish - we use the BH_Delay flag for both
* delalloc and these ondisk-uninitialised buffers.
*/
BUFFER_FNS(PrivateStart, unwritten);
static inline void set_buffer_unwritten_io(struct buffer_head *bh)
{
bh->b_end_io = linvfs_unwritten_done;
}
#define restricted_chown xfs_params.restrict_chown
#define irix_sgid_inherit xfs_params.sgid_inherit
#define irix_symlink_mode xfs_params.symlink_mode
......
......@@ -121,7 +121,8 @@ pb_trace_func(
STATIC kmem_cache_t *pagebuf_cache;
STATIC void pagebuf_daemon_wakeup(int);
STATIC void pagebuf_delwri_queue(page_buf_t *, int);
STATIC struct workqueue_struct *pagebuf_workqueue;
STATIC struct workqueue_struct *pagebuf_logio_workqueue;
STATIC struct workqueue_struct *pagebuf_dataio_workqueue;
/*
* Pagebuf module configuration parameters, exported via
......@@ -785,6 +786,25 @@ pagebuf_get( /* allocate a buffer */
return (pb);
}
/*
* Create a skeletal pagebuf (no pages associated with it).
*/
page_buf_t *
pagebuf_lookup(
struct pb_target *target,
loff_t ioff,
size_t isize,
page_buf_flags_t flags)
{
page_buf_t *pb;
pb = pagebuf_allocate(flags);
if (pb) {
_pagebuf_initialize(pb, target, ioff, isize, flags);
}
return pb;
}
/*
* If we are not low on memory then do the readahead in a deadlock
* safe manner.
......@@ -1131,6 +1151,7 @@ pagebuf_iodone_work(
void
pagebuf_iodone(
page_buf_t *pb,
int dataio,
int schedule)
{
pb->pb_flags &= ~(PBF_READ | PBF_WRITE);
......@@ -1143,7 +1164,8 @@ pagebuf_iodone(
if ((pb->pb_iodone) || (pb->pb_flags & PBF_ASYNC)) {
if (schedule) {
INIT_WORK(&pb->pb_iodone_work, pagebuf_iodone_work, pb);
queue_work(pagebuf_workqueue, &pb->pb_iodone_work);
queue_work(dataio ? pagebuf_dataio_workqueue :
pagebuf_logio_workqueue, &pb->pb_iodone_work);
} else {
pagebuf_iodone_work(pb);
}
......@@ -1268,7 +1290,7 @@ bio_end_io_pagebuf(
if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) {
pb->pb_locked = 0;
pagebuf_iodone(pb, 1);
pagebuf_iodone(pb, 0, 1);
}
bio_put(bio);
......@@ -1412,7 +1434,7 @@ pagebuf_iorequest( /* start real I/O */
if (atomic_dec_and_test(&pb->pb_io_remaining) == 1) {
pb->pb_locked = 0;
pagebuf_iodone(pb, 0);
pagebuf_iodone(pb, 0, 0);
}
return 0;
......@@ -1734,13 +1756,21 @@ pagebuf_daemon_start(void)
{
int rval;
pagebuf_workqueue = create_workqueue("pagebuf");
if (!pagebuf_workqueue)
pagebuf_logio_workqueue = create_workqueue("xfslogd");
if (!pagebuf_logio_workqueue)
return -ENOMEM;
pagebuf_dataio_workqueue = create_workqueue("xfsdatad");
if (!pagebuf_dataio_workqueue) {
destroy_workqueue(pagebuf_logio_workqueue);
return -ENOMEM;
}
rval = kernel_thread(pagebuf_daemon, NULL, CLONE_FS|CLONE_FILES);
if (rval < 0)
destroy_workqueue(pagebuf_workqueue);
if (rval < 0) {
destroy_workqueue(pagebuf_logio_workqueue);
destroy_workqueue(pagebuf_dataio_workqueue);
}
return rval;
}
......@@ -1756,7 +1786,8 @@ pagebuf_daemon_stop(void)
pbd_active = 0;
wake_up_interruptible(&pbd_waitq);
wait_event_interruptible(pbd_waitq, pbd_active);
destroy_workqueue(pagebuf_workqueue);
destroy_workqueue(pagebuf_logio_workqueue);
destroy_workqueue(pagebuf_dataio_workqueue);
}
......
......@@ -169,8 +169,8 @@ typedef page_buf_bmap_t pb_bmap_t;
* This buffer structure is used by the page cache buffer management routines
* to refer to an assembly of pages forming a logical buffer. The actual
* I/O is performed with buffer_head or bio structures, as required by drivers,
* for drivers which do not understand this structure. The buffer structure is
* used on temporary basis only, and discarded when released.
* for drivers which do not understand this structure. The buffer structure is
* used on temporary basis only, and discarded when released.
*
* The real data storage is recorded in the page cache. Metadata is
* hashed to the inode for the block device on which the file system resides.
......@@ -245,6 +245,13 @@ extern page_buf_t *pagebuf_get( /* allocate a buffer */
page_buf_flags_t); /* PBF_LOCK, PBF_READ, */
/* PBF_ASYNC */
extern page_buf_t *pagebuf_lookup(
struct pb_target *,
loff_t, /* starting offset of range */
size_t, /* length of range */
page_buf_flags_t); /* PBF_READ, PBF_WRITE, */
/* PBF_FORCEIO, _PBF_LOCKABLE */
extern page_buf_t *pagebuf_get_empty( /* allocate pagebuf struct with */
/* no memory or disk address */
struct pb_target *); /* mount point "fake" inode */
......@@ -300,6 +307,7 @@ static inline int pagebuf_geterror(page_buf_t *pb)
extern void pagebuf_iodone( /* mark buffer I/O complete */
page_buf_t *, /* buffer to mark */
int, /* use data/log helper thread. */
int); /* run completion locally, or in
* a helper thread. */
......
......@@ -163,15 +163,17 @@ extern inline xfs_caddr_t xfs_buf_offset(page_buf_t *bp, size_t offset)
#define XFS_BUF_SET_PTR(bp, val, count) \
pagebuf_associate_memory(bp, val, count)
#define XFS_BUF_ADDR(bp) ((bp)->pb_bn)
#define XFS_BUF_OFFSET(bp) ((bp)->pb_file_offset >> 9)
#define XFS_BUF_SET_ADDR(bp, blk) \
((bp)->pb_bn = (page_buf_daddr_t)(blk))
#define XFS_BUF_OFFSET(bp) ((bp)->pb_file_offset)
#define XFS_BUF_SET_OFFSET(bp, off) \
((bp)->pb_file_offset = (off))
#define XFS_BUF_COUNT(bp) ((bp)->pb_count_desired)
#define XFS_BUF_SET_COUNT(bp, cnt) \
((bp)->pb_count_desired = cnt)
((bp)->pb_count_desired = (cnt))
#define XFS_BUF_SIZE(bp) ((bp)->pb_buffer_length)
#define XFS_BUF_SET_SIZE(bp, cnt) \
((bp)->pb_buffer_length = cnt)
((bp)->pb_buffer_length = (cnt))
#define XFS_BUF_SET_VTYPE_REF(bp, type, ref)
#define XFS_BUF_SET_VTYPE(bp, type)
#define XFS_BUF_SET_REF(bp, ref)
......@@ -242,7 +244,7 @@ static inline void xfs_buf_relse(page_buf_t *bp)
#define xfs_biodone(pb) \
pagebuf_iodone(pb, 0)
pagebuf_iodone(pb, 0, 0)
#define xfs_incore(buftarg,blkno,len,lockit) \
pagebuf_find(buftarg, blkno ,len, lockit)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment