diff options
author | Nathan Scott <nathans@sgi.com> | 2006-03-30 22:08:59 -0500 |
---|---|---|
committer | Nathan Scott <nathans@sgi.com> | 2006-03-30 22:08:59 -0500 |
commit | 1b895840ce93fd2d150a86c800a3085eaab4eb9e (patch) | |
tree | 2f1c664ca2f948ec8c47f2c66e03cb21f2b9a45c /fs/xfs/linux-2.6/xfs_file.c | |
parent | 3bbcc8e3976f8bba2fd607c8850d7dfe7e332fda (diff) |
[XFS] Provide XFS support for the splice syscall.
Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_file.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 113 |
1 files changed, 80 insertions, 33 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 85997b1205f5..ae4c4754ed31 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -69,7 +69,6 @@ __xfs_file_read( | |||
69 | return rval; | 69 | return rval; |
70 | } | 70 | } |
71 | 71 | ||
72 | |||
73 | STATIC ssize_t | 72 | STATIC ssize_t |
74 | xfs_file_aio_read( | 73 | xfs_file_aio_read( |
75 | struct kiocb *iocb, | 74 | struct kiocb *iocb, |
@@ -90,7 +89,6 @@ xfs_file_aio_read_invis( | |||
90 | return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); | 89 | return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); |
91 | } | 90 | } |
92 | 91 | ||
93 | |||
94 | STATIC inline ssize_t | 92 | STATIC inline ssize_t |
95 | __xfs_file_write( | 93 | __xfs_file_write( |
96 | struct kiocb *iocb, | 94 | struct kiocb *iocb, |
@@ -113,7 +111,6 @@ __xfs_file_write( | |||
113 | return rval; | 111 | return rval; |
114 | } | 112 | } |
115 | 113 | ||
116 | |||
117 | STATIC ssize_t | 114 | STATIC ssize_t |
118 | xfs_file_aio_write( | 115 | xfs_file_aio_write( |
119 | struct kiocb *iocb, | 116 | struct kiocb *iocb, |
@@ -134,7 +131,6 @@ xfs_file_aio_write_invis( | |||
134 | return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); | 131 | return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); |
135 | } | 132 | } |
136 | 133 | ||
137 | |||
138 | STATIC inline ssize_t | 134 | STATIC inline ssize_t |
139 | __xfs_file_readv( | 135 | __xfs_file_readv( |
140 | struct file *file, | 136 | struct file *file, |
@@ -179,7 +175,6 @@ xfs_file_readv_invis( | |||
179 | return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos); | 175 | return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos); |
180 | } | 176 | } |
181 | 177 | ||
182 | |||
183 | STATIC inline ssize_t | 178 | STATIC inline ssize_t |
184 | __xfs_file_writev( | 179 | __xfs_file_writev( |
185 | struct file *file, | 180 | struct file *file, |
@@ -204,7 +199,6 @@ __xfs_file_writev( | |||
204 | return rval; | 199 | return rval; |
205 | } | 200 | } |
206 | 201 | ||
207 | |||
208 | STATIC ssize_t | 202 | STATIC ssize_t |
209 | xfs_file_writev( | 203 | xfs_file_writev( |
210 | struct file *file, | 204 | struct file *file, |
@@ -228,7 +222,7 @@ xfs_file_writev_invis( | |||
228 | STATIC ssize_t | 222 | STATIC ssize_t |
229 | xfs_file_sendfile( | 223 | xfs_file_sendfile( |
230 | struct file *filp, | 224 | struct file *filp, |
231 | loff_t *ppos, | 225 | loff_t *pos, |
232 | size_t count, | 226 | size_t count, |
233 | read_actor_t actor, | 227 | read_actor_t actor, |
234 | void *target) | 228 | void *target) |
@@ -236,10 +230,80 @@ xfs_file_sendfile( | |||
236 | vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); | 230 | vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); |
237 | ssize_t rval; | 231 | ssize_t rval; |
238 | 232 | ||
239 | VOP_SENDFILE(vp, filp, ppos, 0, count, actor, target, NULL, rval); | 233 | VOP_SENDFILE(vp, filp, pos, 0, count, actor, target, NULL, rval); |
240 | return rval; | 234 | return rval; |
241 | } | 235 | } |
242 | 236 | ||
237 | STATIC ssize_t | ||
238 | xfs_file_sendfile_invis( | ||
239 | struct file *filp, | ||
240 | loff_t *pos, | ||
241 | size_t count, | ||
242 | read_actor_t actor, | ||
243 | void *target) | ||
244 | { | ||
245 | vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); | ||
246 | ssize_t rval; | ||
247 | |||
248 | VOP_SENDFILE(vp, filp, pos, IO_INVIS, count, actor, target, NULL, rval); | ||
249 | return rval; | ||
250 | } | ||
251 | |||
252 | STATIC ssize_t | ||
253 | xfs_file_splice_read( | ||
254 | struct file *infilp, | ||
255 | struct inode *pipe, | ||
256 | size_t len, | ||
257 | unsigned int flags) | ||
258 | { | ||
259 | vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); | ||
260 | ssize_t rval; | ||
261 | |||
262 | VOP_SPLICE_READ(vp, infilp, pipe, len, flags, 0, NULL, rval); | ||
263 | return rval; | ||
264 | } | ||
265 | |||
266 | STATIC ssize_t | ||
267 | xfs_file_splice_read_invis( | ||
268 | struct file *infilp, | ||
269 | struct inode *pipe, | ||
270 | size_t len, | ||
271 | unsigned int flags) | ||
272 | { | ||
273 | vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode); | ||
274 | ssize_t rval; | ||
275 | |||
276 | VOP_SPLICE_READ(vp, infilp, pipe, len, flags, IO_INVIS, NULL, rval); | ||
277 | return rval; | ||
278 | } | ||
279 | |||
280 | STATIC ssize_t | ||
281 | xfs_file_splice_write( | ||
282 | struct inode *pipe, | ||
283 | struct file *outfilp, | ||
284 | size_t len, | ||
285 | unsigned int flags) | ||
286 | { | ||
287 | vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); | ||
288 | ssize_t rval; | ||
289 | |||
290 | VOP_SPLICE_WRITE(vp, pipe, outfilp, len, flags, 0, NULL, rval); | ||
291 | return rval; | ||
292 | } | ||
293 | |||
294 | STATIC ssize_t | ||
295 | xfs_file_splice_write_invis( | ||
296 | struct inode *pipe, | ||
297 | struct file *outfilp, | ||
298 | size_t len, | ||
299 | unsigned int flags) | ||
300 | { | ||
301 | vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode); | ||
302 | ssize_t rval; | ||
303 | |||
304 | VOP_SPLICE_WRITE(vp, pipe, outfilp, len, flags, IO_INVIS, NULL, rval); | ||
305 | return rval; | ||
306 | } | ||
243 | 307 | ||
244 | STATIC int | 308 | STATIC int |
245 | xfs_file_open( | 309 | xfs_file_open( |
@@ -251,13 +315,10 @@ xfs_file_open( | |||
251 | 315 | ||
252 | if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) | 316 | if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) |
253 | return -EFBIG; | 317 | return -EFBIG; |
254 | |||
255 | ASSERT(vp); | ||
256 | VOP_OPEN(vp, NULL, error); | 318 | VOP_OPEN(vp, NULL, error); |
257 | return -error; | 319 | return -error; |
258 | } | 320 | } |
259 | 321 | ||
260 | |||
261 | STATIC int | 322 | STATIC int |
262 | xfs_file_release( | 323 | xfs_file_release( |
263 | struct inode *inode, | 324 | struct inode *inode, |
@@ -271,7 +332,6 @@ xfs_file_release( | |||
271 | return -error; | 332 | return -error; |
272 | } | 333 | } |
273 | 334 | ||
274 | |||
275 | STATIC int | 335 | STATIC int |
276 | xfs_file_fsync( | 336 | xfs_file_fsync( |
277 | struct file *filp, | 337 | struct file *filp, |
@@ -285,21 +345,11 @@ xfs_file_fsync( | |||
285 | 345 | ||
286 | if (datasync) | 346 | if (datasync) |
287 | flags |= FSYNC_DATA; | 347 | flags |= FSYNC_DATA; |
288 | |||
289 | ASSERT(vp); | ||
290 | VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error); | 348 | VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error); |
291 | return -error; | 349 | return -error; |
292 | } | 350 | } |
293 | 351 | ||
294 | /* | ||
295 | * xfs_file_readdir maps to VOP_READDIR(). | ||
296 | * We need to build a uio, cred, ... | ||
297 | */ | ||
298 | |||
299 | #define nextdp(dp) ((struct xfs_dirent *)((char *)(dp) + (dp)->d_reclen)) | ||
300 | |||
301 | #ifdef CONFIG_XFS_DMAPI | 352 | #ifdef CONFIG_XFS_DMAPI |
302 | |||
303 | STATIC struct page * | 353 | STATIC struct page * |
304 | xfs_vm_nopage( | 354 | xfs_vm_nopage( |
305 | struct vm_area_struct *area, | 355 | struct vm_area_struct *area, |
@@ -319,10 +369,8 @@ xfs_vm_nopage( | |||
319 | 369 | ||
320 | return filemap_nopage(area, address, type); | 370 | return filemap_nopage(area, address, type); |
321 | } | 371 | } |
322 | |||
323 | #endif /* CONFIG_XFS_DMAPI */ | 372 | #endif /* CONFIG_XFS_DMAPI */ |
324 | 373 | ||
325 | |||
326 | STATIC int | 374 | STATIC int |
327 | xfs_file_readdir( | 375 | xfs_file_readdir( |
328 | struct file *filp, | 376 | struct file *filp, |
@@ -330,7 +378,7 @@ xfs_file_readdir( | |||
330 | filldir_t filldir) | 378 | filldir_t filldir) |
331 | { | 379 | { |
332 | int error = 0; | 380 | int error = 0; |
333 | vnode_t *vp; | 381 | vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); |
334 | uio_t uio; | 382 | uio_t uio; |
335 | iovec_t iov; | 383 | iovec_t iov; |
336 | int eof = 0; | 384 | int eof = 0; |
@@ -340,9 +388,6 @@ xfs_file_readdir( | |||
340 | xfs_off_t start_offset, curr_offset; | 388 | xfs_off_t start_offset, curr_offset; |
341 | xfs_dirent_t *dbp = NULL; | 389 | xfs_dirent_t *dbp = NULL; |
342 | 390 | ||
343 | vp = vn_from_inode(filp->f_dentry->d_inode); | ||
344 | ASSERT(vp); | ||
345 | |||
346 | /* Try fairly hard to get memory */ | 391 | /* Try fairly hard to get memory */ |
347 | do { | 392 | do { |
348 | if ((read_buf = (caddr_t)kmalloc(rlen, GFP_KERNEL))) | 393 | if ((read_buf = (caddr_t)kmalloc(rlen, GFP_KERNEL))) |
@@ -387,7 +432,7 @@ xfs_file_readdir( | |||
387 | } | 432 | } |
388 | size -= dbp->d_reclen; | 433 | size -= dbp->d_reclen; |
389 | curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */; | 434 | curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */; |
390 | dbp = nextdp(dbp); | 435 | dbp = (xfs_dirent_t *)((char *)dbp + dbp->d_reclen); |
391 | } | 436 | } |
392 | } | 437 | } |
393 | done: | 438 | done: |
@@ -402,7 +447,6 @@ done: | |||
402 | return -error; | 447 | return -error; |
403 | } | 448 | } |
404 | 449 | ||
405 | |||
406 | STATIC int | 450 | STATIC int |
407 | xfs_file_mmap( | 451 | xfs_file_mmap( |
408 | struct file *filp, | 452 | struct file *filp, |
@@ -457,11 +501,10 @@ xfs_file_ioctl_invis( | |||
457 | unsigned int cmd, | 501 | unsigned int cmd, |
458 | unsigned long arg) | 502 | unsigned long arg) |
459 | { | 503 | { |
460 | int error; | ||
461 | struct inode *inode = filp->f_dentry->d_inode; | 504 | struct inode *inode = filp->f_dentry->d_inode; |
462 | vnode_t *vp = vn_from_inode(inode); | 505 | vnode_t *vp = vn_from_inode(inode); |
506 | int error; | ||
463 | 507 | ||
464 | ASSERT(vp); | ||
465 | VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error); | 508 | VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error); |
466 | VMODIFY(vp); | 509 | VMODIFY(vp); |
467 | 510 | ||
@@ -537,6 +580,8 @@ const struct file_operations xfs_file_operations = { | |||
537 | .aio_read = xfs_file_aio_read, | 580 | .aio_read = xfs_file_aio_read, |
538 | .aio_write = xfs_file_aio_write, | 581 | .aio_write = xfs_file_aio_write, |
539 | .sendfile = xfs_file_sendfile, | 582 | .sendfile = xfs_file_sendfile, |
583 | .splice_read = xfs_file_splice_read, | ||
584 | .splice_write = xfs_file_splice_write, | ||
540 | .unlocked_ioctl = xfs_file_ioctl, | 585 | .unlocked_ioctl = xfs_file_ioctl, |
541 | #ifdef CONFIG_COMPAT | 586 | #ifdef CONFIG_COMPAT |
542 | .compat_ioctl = xfs_file_compat_ioctl, | 587 | .compat_ioctl = xfs_file_compat_ioctl, |
@@ -558,7 +603,9 @@ const struct file_operations xfs_invis_file_operations = { | |||
558 | .writev = xfs_file_writev_invis, | 603 | .writev = xfs_file_writev_invis, |
559 | .aio_read = xfs_file_aio_read_invis, | 604 | .aio_read = xfs_file_aio_read_invis, |
560 | .aio_write = xfs_file_aio_write_invis, | 605 | .aio_write = xfs_file_aio_write_invis, |
561 | .sendfile = xfs_file_sendfile, | 606 | .sendfile = xfs_file_sendfile_invis, |
607 | .splice_read = xfs_file_splice_read_invis, | ||
608 | .splice_write = xfs_file_splice_write_invis, | ||
562 | .unlocked_ioctl = xfs_file_ioctl_invis, | 609 | .unlocked_ioctl = xfs_file_ioctl_invis, |
563 | #ifdef CONFIG_COMPAT | 610 | #ifdef CONFIG_COMPAT |
564 | .compat_ioctl = xfs_file_compat_invis_ioctl, | 611 | .compat_ioctl = xfs_file_compat_invis_ioctl, |