diff options
author | Christoph Hellwig <hch@infradead.org> | 2010-02-15 04:44:47 -0500 |
---|---|---|
committer | Alex Elder <aelder@sgi.com> | 2010-03-01 17:34:29 -0500 |
commit | 00258e36b2d33b1b5cef7b489e06c5e0a9df58b5 (patch) | |
tree | 0c5908b2bb005c52582cffe8bbc5c75c77659db4 /fs/xfs | |
parent | dda35b8f84d209784041bbad47f9e195a08a7527 (diff) |
xfs: remove wrappers for read/write file operations
Currently the aio_read, aio_write, splice_read and splice_write file
operations are divided into a low-level routine doing all the work
and one that implements the Linux file operations and does minimal
argument wrapping. This is a leftover from the days of the vnode
operations layer and can be removed to simplify the code a lot.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Alex Elder <aelder@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_file.c | 285 |
1 files changed, 114 insertions, 171 deletions
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 51fc510828a4..1eb561a10e26 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -96,28 +96,34 @@ xfs_iozero( | |||
96 | return (-status); | 96 | return (-status); |
97 | } | 97 | } |
98 | 98 | ||
99 | ssize_t /* bytes read, or (-) error */ | 99 | STATIC ssize_t |
100 | xfs_read( | 100 | xfs_file_aio_read( |
101 | xfs_inode_t *ip, | ||
102 | struct kiocb *iocb, | 101 | struct kiocb *iocb, |
103 | const struct iovec *iovp, | 102 | const struct iovec *iovp, |
104 | unsigned int segs, | 103 | unsigned long nr_segs, |
105 | loff_t *offset, | 104 | loff_t pos) |
106 | int ioflags) | ||
107 | { | 105 | { |
108 | struct file *file = iocb->ki_filp; | 106 | struct file *file = iocb->ki_filp; |
109 | struct inode *inode = file->f_mapping->host; | 107 | struct inode *inode = file->f_mapping->host; |
110 | xfs_mount_t *mp = ip->i_mount; | 108 | struct xfs_inode *ip = XFS_I(inode); |
109 | struct xfs_mount *mp = ip->i_mount; | ||
111 | size_t size = 0; | 110 | size_t size = 0; |
112 | ssize_t ret = 0; | 111 | ssize_t ret = 0; |
112 | int ioflags = 0; | ||
113 | xfs_fsize_t n; | 113 | xfs_fsize_t n; |
114 | unsigned long seg; | 114 | unsigned long seg; |
115 | 115 | ||
116 | |||
117 | XFS_STATS_INC(xs_read_calls); | 116 | XFS_STATS_INC(xs_read_calls); |
118 | 117 | ||
118 | BUG_ON(iocb->ki_pos != pos); | ||
119 | |||
120 | if (unlikely(file->f_flags & O_DIRECT)) | ||
121 | ioflags |= IO_ISDIRECT; | ||
122 | if (file->f_mode & FMODE_NOCMTIME) | ||
123 | ioflags |= IO_INVIS; | ||
124 | |||
119 | /* START copy & waste from filemap.c */ | 125 | /* START copy & waste from filemap.c */ |
120 | for (seg = 0; seg < segs; seg++) { | 126 | for (seg = 0; seg < nr_segs; seg++) { |
121 | const struct iovec *iv = &iovp[seg]; | 127 | const struct iovec *iv = &iovp[seg]; |
122 | 128 | ||
123 | /* | 129 | /* |
@@ -134,17 +140,16 @@ xfs_read( | |||
134 | xfs_buftarg_t *target = | 140 | xfs_buftarg_t *target = |
135 | XFS_IS_REALTIME_INODE(ip) ? | 141 | XFS_IS_REALTIME_INODE(ip) ? |
136 | mp->m_rtdev_targp : mp->m_ddev_targp; | 142 | mp->m_rtdev_targp : mp->m_ddev_targp; |
137 | if ((*offset & target->bt_smask) || | 143 | if ((iocb->ki_pos & target->bt_smask) || |
138 | (size & target->bt_smask)) { | 144 | (size & target->bt_smask)) { |
139 | if (*offset == ip->i_size) { | 145 | if (iocb->ki_pos == ip->i_size) |
140 | return (0); | 146 | return 0; |
141 | } | ||
142 | return -XFS_ERROR(EINVAL); | 147 | return -XFS_ERROR(EINVAL); |
143 | } | 148 | } |
144 | } | 149 | } |
145 | 150 | ||
146 | n = XFS_MAXIOFFSET(mp) - *offset; | 151 | n = XFS_MAXIOFFSET(mp) - iocb->ki_pos; |
147 | if ((n <= 0) || (size == 0)) | 152 | if (n <= 0 || size == 0) |
148 | return 0; | 153 | return 0; |
149 | 154 | ||
150 | if (n < size) | 155 | if (n < size) |
@@ -161,7 +166,7 @@ xfs_read( | |||
161 | int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); | 166 | int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags); |
162 | int iolock = XFS_IOLOCK_SHARED; | 167 | int iolock = XFS_IOLOCK_SHARED; |
163 | 168 | ||
164 | ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, ip, *offset, size, | 169 | ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, ip, iocb->ki_pos, size, |
165 | dmflags, &iolock); | 170 | dmflags, &iolock); |
166 | if (ret) { | 171 | if (ret) { |
167 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | 172 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); |
@@ -172,9 +177,11 @@ xfs_read( | |||
172 | } | 177 | } |
173 | 178 | ||
174 | if (unlikely(ioflags & IO_ISDIRECT)) { | 179 | if (unlikely(ioflags & IO_ISDIRECT)) { |
175 | if (inode->i_mapping->nrpages) | 180 | if (inode->i_mapping->nrpages) { |
176 | ret = -xfs_flushinval_pages(ip, (*offset & PAGE_CACHE_MASK), | 181 | ret = -xfs_flushinval_pages(ip, |
177 | -1, FI_REMAPF_LOCKED); | 182 | (iocb->ki_pos & PAGE_CACHE_MASK), |
183 | -1, FI_REMAPF_LOCKED); | ||
184 | } | ||
178 | mutex_unlock(&inode->i_mutex); | 185 | mutex_unlock(&inode->i_mutex); |
179 | if (ret) { | 186 | if (ret) { |
180 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); | 187 | xfs_iunlock(ip, XFS_IOLOCK_SHARED); |
@@ -182,10 +189,9 @@ xfs_read( | |||
182 | } | 189 | } |
183 | } | 190 | } |
184 | 191 | ||
185 | trace_xfs_file_read(ip, size, *offset, ioflags); | 192 | trace_xfs_file_read(ip, size, iocb->ki_pos, ioflags); |
186 | 193 | ||
187 | iocb->ki_pos = *offset; | 194 | ret = generic_file_aio_read(iocb, iovp, nr_segs, iocb->ki_pos); |
188 | ret = generic_file_aio_read(iocb, iovp, segs, *offset); | ||
189 | if (ret > 0) | 195 | if (ret > 0) |
190 | XFS_STATS_ADD(xs_read_bytes, ret); | 196 | XFS_STATS_ADD(xs_read_bytes, ret); |
191 | 197 | ||
@@ -193,20 +199,24 @@ xfs_read( | |||
193 | return ret; | 199 | return ret; |
194 | } | 200 | } |
195 | 201 | ||
196 | ssize_t | 202 | STATIC ssize_t |
197 | xfs_splice_read( | 203 | xfs_file_splice_read( |
198 | xfs_inode_t *ip, | ||
199 | struct file *infilp, | 204 | struct file *infilp, |
200 | loff_t *ppos, | 205 | loff_t *ppos, |
201 | struct pipe_inode_info *pipe, | 206 | struct pipe_inode_info *pipe, |
202 | size_t count, | 207 | size_t count, |
203 | int flags, | 208 | unsigned int flags) |
204 | int ioflags) | ||
205 | { | 209 | { |
206 | xfs_mount_t *mp = ip->i_mount; | 210 | struct xfs_inode *ip = XFS_I(infilp->f_mapping->host); |
211 | struct xfs_mount *mp = ip->i_mount; | ||
212 | int ioflags = 0; | ||
207 | ssize_t ret; | 213 | ssize_t ret; |
208 | 214 | ||
209 | XFS_STATS_INC(xs_read_calls); | 215 | XFS_STATS_INC(xs_read_calls); |
216 | |||
217 | if (infilp->f_mode & FMODE_NOCMTIME) | ||
218 | ioflags |= IO_INVIS; | ||
219 | |||
210 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 220 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
211 | return -EIO; | 221 | return -EIO; |
212 | 222 | ||
@@ -234,22 +244,26 @@ xfs_splice_read( | |||
234 | return ret; | 244 | return ret; |
235 | } | 245 | } |
236 | 246 | ||
237 | ssize_t | 247 | STATIC ssize_t |
238 | xfs_splice_write( | 248 | xfs_file_splice_write( |
239 | xfs_inode_t *ip, | ||
240 | struct pipe_inode_info *pipe, | 249 | struct pipe_inode_info *pipe, |
241 | struct file *outfilp, | 250 | struct file *outfilp, |
242 | loff_t *ppos, | 251 | loff_t *ppos, |
243 | size_t count, | 252 | size_t count, |
244 | int flags, | 253 | unsigned int flags) |
245 | int ioflags) | ||
246 | { | 254 | { |
247 | xfs_mount_t *mp = ip->i_mount; | ||
248 | ssize_t ret; | ||
249 | struct inode *inode = outfilp->f_mapping->host; | 255 | struct inode *inode = outfilp->f_mapping->host; |
256 | struct xfs_inode *ip = XFS_I(inode); | ||
257 | struct xfs_mount *mp = ip->i_mount; | ||
250 | xfs_fsize_t isize, new_size; | 258 | xfs_fsize_t isize, new_size; |
259 | int ioflags = 0; | ||
260 | ssize_t ret; | ||
251 | 261 | ||
252 | XFS_STATS_INC(xs_write_calls); | 262 | XFS_STATS_INC(xs_write_calls); |
263 | |||
264 | if (outfilp->f_mode & FMODE_NOCMTIME) | ||
265 | ioflags |= IO_INVIS; | ||
266 | |||
253 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | 267 | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
254 | return -EIO; | 268 | return -EIO; |
255 | 269 | ||
@@ -484,42 +498,43 @@ out_lock: | |||
484 | return error; | 498 | return error; |
485 | } | 499 | } |
486 | 500 | ||
487 | ssize_t /* bytes written, or (-) error */ | 501 | STATIC ssize_t |
488 | xfs_write( | 502 | xfs_file_aio_write( |
489 | struct xfs_inode *xip, | ||
490 | struct kiocb *iocb, | 503 | struct kiocb *iocb, |
491 | const struct iovec *iovp, | 504 | const struct iovec *iovp, |
492 | unsigned int nsegs, | 505 | unsigned long nr_segs, |
493 | loff_t *offset, | 506 | loff_t pos) |
494 | int ioflags) | ||
495 | { | 507 | { |
496 | struct file *file = iocb->ki_filp; | 508 | struct file *file = iocb->ki_filp; |
497 | struct address_space *mapping = file->f_mapping; | 509 | struct address_space *mapping = file->f_mapping; |
498 | struct inode *inode = mapping->host; | 510 | struct inode *inode = mapping->host; |
499 | unsigned long segs = nsegs; | 511 | struct xfs_inode *ip = XFS_I(inode); |
500 | xfs_mount_t *mp; | 512 | struct xfs_mount *mp = ip->i_mount; |
501 | ssize_t ret = 0, error = 0; | 513 | ssize_t ret = 0, error = 0; |
514 | int ioflags = 0; | ||
502 | xfs_fsize_t isize, new_size; | 515 | xfs_fsize_t isize, new_size; |
503 | int iolock; | 516 | int iolock; |
504 | int eventsent = 0; | 517 | int eventsent = 0; |
505 | size_t ocount = 0, count; | 518 | size_t ocount = 0, count; |
506 | loff_t pos; | ||
507 | int need_i_mutex; | 519 | int need_i_mutex; |
508 | 520 | ||
509 | XFS_STATS_INC(xs_write_calls); | 521 | XFS_STATS_INC(xs_write_calls); |
510 | 522 | ||
511 | error = generic_segment_checks(iovp, &segs, &ocount, VERIFY_READ); | 523 | BUG_ON(iocb->ki_pos != pos); |
524 | |||
525 | if (unlikely(file->f_flags & O_DIRECT)) | ||
526 | ioflags |= IO_ISDIRECT; | ||
527 | if (file->f_mode & FMODE_NOCMTIME) | ||
528 | ioflags |= IO_INVIS; | ||
529 | |||
530 | error = generic_segment_checks(iovp, &nr_segs, &ocount, VERIFY_READ); | ||
512 | if (error) | 531 | if (error) |
513 | return error; | 532 | return error; |
514 | 533 | ||
515 | count = ocount; | 534 | count = ocount; |
516 | pos = *offset; | ||
517 | |||
518 | if (count == 0) | 535 | if (count == 0) |
519 | return 0; | 536 | return 0; |
520 | 537 | ||
521 | mp = xip->i_mount; | ||
522 | |||
523 | xfs_wait_for_freeze(mp, SB_FREEZE_WRITE); | 538 | xfs_wait_for_freeze(mp, SB_FREEZE_WRITE); |
524 | 539 | ||
525 | if (XFS_FORCED_SHUTDOWN(mp)) | 540 | if (XFS_FORCED_SHUTDOWN(mp)) |
@@ -535,30 +550,30 @@ relock: | |||
535 | mutex_lock(&inode->i_mutex); | 550 | mutex_lock(&inode->i_mutex); |
536 | } | 551 | } |
537 | 552 | ||
538 | xfs_ilock(xip, XFS_ILOCK_EXCL|iolock); | 553 | xfs_ilock(ip, XFS_ILOCK_EXCL|iolock); |
539 | 554 | ||
540 | start: | 555 | start: |
541 | error = -generic_write_checks(file, &pos, &count, | 556 | error = -generic_write_checks(file, &pos, &count, |
542 | S_ISBLK(inode->i_mode)); | 557 | S_ISBLK(inode->i_mode)); |
543 | if (error) { | 558 | if (error) { |
544 | xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); | 559 | xfs_iunlock(ip, XFS_ILOCK_EXCL|iolock); |
545 | goto out_unlock_mutex; | 560 | goto out_unlock_mutex; |
546 | } | 561 | } |
547 | 562 | ||
548 | if ((DM_EVENT_ENABLED(xip, DM_EVENT_WRITE) && | 563 | if ((DM_EVENT_ENABLED(ip, DM_EVENT_WRITE) && |
549 | !(ioflags & IO_INVIS) && !eventsent)) { | 564 | !(ioflags & IO_INVIS) && !eventsent)) { |
550 | int dmflags = FILP_DELAY_FLAG(file); | 565 | int dmflags = FILP_DELAY_FLAG(file); |
551 | 566 | ||
552 | if (need_i_mutex) | 567 | if (need_i_mutex) |
553 | dmflags |= DM_FLAGS_IMUX; | 568 | dmflags |= DM_FLAGS_IMUX; |
554 | 569 | ||
555 | xfs_iunlock(xip, XFS_ILOCK_EXCL); | 570 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
556 | error = XFS_SEND_DATA(xip->i_mount, DM_EVENT_WRITE, xip, | 571 | error = XFS_SEND_DATA(ip->i_mount, DM_EVENT_WRITE, ip, |
557 | pos, count, dmflags, &iolock); | 572 | pos, count, dmflags, &iolock); |
558 | if (error) { | 573 | if (error) { |
559 | goto out_unlock_internal; | 574 | goto out_unlock_internal; |
560 | } | 575 | } |
561 | xfs_ilock(xip, XFS_ILOCK_EXCL); | 576 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
562 | eventsent = 1; | 577 | eventsent = 1; |
563 | 578 | ||
564 | /* | 579 | /* |
@@ -568,33 +583,33 @@ start: | |||
568 | * event prevents another call to XFS_SEND_DATA, which is | 583 | * event prevents another call to XFS_SEND_DATA, which is |
569 | * what allows the size to change in the first place. | 584 | * what allows the size to change in the first place. |
570 | */ | 585 | */ |
571 | if ((file->f_flags & O_APPEND) && pos != xip->i_size) | 586 | if ((file->f_flags & O_APPEND) && pos != ip->i_size) |
572 | goto start; | 587 | goto start; |
573 | } | 588 | } |
574 | 589 | ||
575 | if (ioflags & IO_ISDIRECT) { | 590 | if (ioflags & IO_ISDIRECT) { |
576 | xfs_buftarg_t *target = | 591 | xfs_buftarg_t *target = |
577 | XFS_IS_REALTIME_INODE(xip) ? | 592 | XFS_IS_REALTIME_INODE(ip) ? |
578 | mp->m_rtdev_targp : mp->m_ddev_targp; | 593 | mp->m_rtdev_targp : mp->m_ddev_targp; |
579 | 594 | ||
580 | if ((pos & target->bt_smask) || (count & target->bt_smask)) { | 595 | if ((pos & target->bt_smask) || (count & target->bt_smask)) { |
581 | xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); | 596 | xfs_iunlock(ip, XFS_ILOCK_EXCL|iolock); |
582 | return XFS_ERROR(-EINVAL); | 597 | return XFS_ERROR(-EINVAL); |
583 | } | 598 | } |
584 | 599 | ||
585 | if (!need_i_mutex && (mapping->nrpages || pos > xip->i_size)) { | 600 | if (!need_i_mutex && (mapping->nrpages || pos > ip->i_size)) { |
586 | xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); | 601 | xfs_iunlock(ip, XFS_ILOCK_EXCL|iolock); |
587 | iolock = XFS_IOLOCK_EXCL; | 602 | iolock = XFS_IOLOCK_EXCL; |
588 | need_i_mutex = 1; | 603 | need_i_mutex = 1; |
589 | mutex_lock(&inode->i_mutex); | 604 | mutex_lock(&inode->i_mutex); |
590 | xfs_ilock(xip, XFS_ILOCK_EXCL|iolock); | 605 | xfs_ilock(ip, XFS_ILOCK_EXCL|iolock); |
591 | goto start; | 606 | goto start; |
592 | } | 607 | } |
593 | } | 608 | } |
594 | 609 | ||
595 | new_size = pos + count; | 610 | new_size = pos + count; |
596 | if (new_size > xip->i_size) | 611 | if (new_size > ip->i_size) |
597 | xip->i_new_size = new_size; | 612 | ip->i_new_size = new_size; |
598 | 613 | ||
599 | if (likely(!(ioflags & IO_INVIS))) | 614 | if (likely(!(ioflags & IO_INVIS))) |
600 | file_update_time(file); | 615 | file_update_time(file); |
@@ -608,14 +623,14 @@ start: | |||
608 | * to zero it out up to the new size. | 623 | * to zero it out up to the new size. |
609 | */ | 624 | */ |
610 | 625 | ||
611 | if (pos > xip->i_size) { | 626 | if (pos > ip->i_size) { |
612 | error = xfs_zero_eof(xip, pos, xip->i_size); | 627 | error = xfs_zero_eof(ip, pos, ip->i_size); |
613 | if (error) { | 628 | if (error) { |
614 | xfs_iunlock(xip, XFS_ILOCK_EXCL); | 629 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
615 | goto out_unlock_internal; | 630 | goto out_unlock_internal; |
616 | } | 631 | } |
617 | } | 632 | } |
618 | xfs_iunlock(xip, XFS_ILOCK_EXCL); | 633 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
619 | 634 | ||
620 | /* | 635 | /* |
621 | * If we're writing the file then make sure to clear the | 636 | * If we're writing the file then make sure to clear the |
@@ -633,7 +648,7 @@ start: | |||
633 | if ((ioflags & IO_ISDIRECT)) { | 648 | if ((ioflags & IO_ISDIRECT)) { |
634 | if (mapping->nrpages) { | 649 | if (mapping->nrpages) { |
635 | WARN_ON(need_i_mutex == 0); | 650 | WARN_ON(need_i_mutex == 0); |
636 | error = xfs_flushinval_pages(xip, | 651 | error = xfs_flushinval_pages(ip, |
637 | (pos & PAGE_CACHE_MASK), | 652 | (pos & PAGE_CACHE_MASK), |
638 | -1, FI_REMAPF_LOCKED); | 653 | -1, FI_REMAPF_LOCKED); |
639 | if (error) | 654 | if (error) |
@@ -642,16 +657,16 @@ start: | |||
642 | 657 | ||
643 | if (need_i_mutex) { | 658 | if (need_i_mutex) { |
644 | /* demote the lock now the cached pages are gone */ | 659 | /* demote the lock now the cached pages are gone */ |
645 | xfs_ilock_demote(xip, XFS_IOLOCK_EXCL); | 660 | xfs_ilock_demote(ip, XFS_IOLOCK_EXCL); |
646 | mutex_unlock(&inode->i_mutex); | 661 | mutex_unlock(&inode->i_mutex); |
647 | 662 | ||
648 | iolock = XFS_IOLOCK_SHARED; | 663 | iolock = XFS_IOLOCK_SHARED; |
649 | need_i_mutex = 0; | 664 | need_i_mutex = 0; |
650 | } | 665 | } |
651 | 666 | ||
652 | trace_xfs_file_direct_write(xip, count, *offset, ioflags); | 667 | trace_xfs_file_direct_write(ip, count, iocb->ki_pos, ioflags); |
653 | ret = generic_file_direct_write(iocb, iovp, | 668 | ret = generic_file_direct_write(iocb, iovp, |
654 | &segs, pos, offset, count, ocount); | 669 | &nr_segs, pos, &iocb->ki_pos, count, ocount); |
655 | 670 | ||
656 | /* | 671 | /* |
657 | * direct-io write to a hole: fall through to buffered I/O | 672 | * direct-io write to a hole: fall through to buffered I/O |
@@ -664,7 +679,7 @@ start: | |||
664 | count -= ret; | 679 | count -= ret; |
665 | 680 | ||
666 | ioflags &= ~IO_ISDIRECT; | 681 | ioflags &= ~IO_ISDIRECT; |
667 | xfs_iunlock(xip, iolock); | 682 | xfs_iunlock(ip, iolock); |
668 | goto relock; | 683 | goto relock; |
669 | } | 684 | } |
670 | } else { | 685 | } else { |
@@ -672,15 +687,15 @@ start: | |||
672 | ssize_t ret2 = 0; | 687 | ssize_t ret2 = 0; |
673 | 688 | ||
674 | write_retry: | 689 | write_retry: |
675 | trace_xfs_file_buffered_write(xip, count, *offset, ioflags); | 690 | trace_xfs_file_buffered_write(ip, count, iocb->ki_pos, ioflags); |
676 | ret2 = generic_file_buffered_write(iocb, iovp, segs, | 691 | ret2 = generic_file_buffered_write(iocb, iovp, nr_segs, |
677 | pos, offset, count, ret); | 692 | pos, &iocb->ki_pos, count, ret); |
678 | /* | 693 | /* |
679 | * if we just got an ENOSPC, flush the inode now we | 694 | * if we just got an ENOSPC, flush the inode now we |
680 | * aren't holding any page locks and retry *once* | 695 | * aren't holding any page locks and retry *once* |
681 | */ | 696 | */ |
682 | if (ret2 == -ENOSPC && !enospc) { | 697 | if (ret2 == -ENOSPC && !enospc) { |
683 | error = xfs_flush_pages(xip, 0, -1, 0, FI_NONE); | 698 | error = xfs_flush_pages(ip, 0, -1, 0, FI_NONE); |
684 | if (error) | 699 | if (error) |
685 | goto out_unlock_internal; | 700 | goto out_unlock_internal; |
686 | enospc = 1; | 701 | enospc = 1; |
@@ -692,27 +707,27 @@ write_retry: | |||
692 | current->backing_dev_info = NULL; | 707 | current->backing_dev_info = NULL; |
693 | 708 | ||
694 | isize = i_size_read(inode); | 709 | isize = i_size_read(inode); |
695 | if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize)) | 710 | if (unlikely(ret < 0 && ret != -EFAULT && iocb->ki_pos > isize)) |
696 | *offset = isize; | 711 | iocb->ki_pos = isize; |
697 | 712 | ||
698 | if (*offset > xip->i_size) { | 713 | if (iocb->ki_pos > ip->i_size) { |
699 | xfs_ilock(xip, XFS_ILOCK_EXCL); | 714 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
700 | if (*offset > xip->i_size) | 715 | if (iocb->ki_pos > ip->i_size) |
701 | xip->i_size = *offset; | 716 | ip->i_size = iocb->ki_pos; |
702 | xfs_iunlock(xip, XFS_ILOCK_EXCL); | 717 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
703 | } | 718 | } |
704 | 719 | ||
705 | if (ret == -ENOSPC && | 720 | if (ret == -ENOSPC && |
706 | DM_EVENT_ENABLED(xip, DM_EVENT_NOSPACE) && !(ioflags & IO_INVIS)) { | 721 | DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE) && !(ioflags & IO_INVIS)) { |
707 | xfs_iunlock(xip, iolock); | 722 | xfs_iunlock(ip, iolock); |
708 | if (need_i_mutex) | 723 | if (need_i_mutex) |
709 | mutex_unlock(&inode->i_mutex); | 724 | mutex_unlock(&inode->i_mutex); |
710 | error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, xip, | 725 | error = XFS_SEND_NAMESP(ip->i_mount, DM_EVENT_NOSPACE, ip, |
711 | DM_RIGHT_NULL, xip, DM_RIGHT_NULL, NULL, NULL, | 726 | DM_RIGHT_NULL, ip, DM_RIGHT_NULL, NULL, NULL, |
712 | 0, 0, 0); /* Delay flag intentionally unused */ | 727 | 0, 0, 0); /* Delay flag intentionally unused */ |
713 | if (need_i_mutex) | 728 | if (need_i_mutex) |
714 | mutex_lock(&inode->i_mutex); | 729 | mutex_lock(&inode->i_mutex); |
715 | xfs_ilock(xip, iolock); | 730 | xfs_ilock(ip, iolock); |
716 | if (error) | 731 | if (error) |
717 | goto out_unlock_internal; | 732 | goto out_unlock_internal; |
718 | goto start; | 733 | goto start; |
@@ -729,7 +744,7 @@ write_retry: | |||
729 | loff_t end = pos + ret - 1; | 744 | loff_t end = pos + ret - 1; |
730 | int error2; | 745 | int error2; |
731 | 746 | ||
732 | xfs_iunlock(xip, iolock); | 747 | xfs_iunlock(ip, iolock); |
733 | if (need_i_mutex) | 748 | if (need_i_mutex) |
734 | mutex_unlock(&inode->i_mutex); | 749 | mutex_unlock(&inode->i_mutex); |
735 | 750 | ||
@@ -738,17 +753,17 @@ write_retry: | |||
738 | error = error2; | 753 | error = error2; |
739 | if (need_i_mutex) | 754 | if (need_i_mutex) |
740 | mutex_lock(&inode->i_mutex); | 755 | mutex_lock(&inode->i_mutex); |
741 | xfs_ilock(xip, iolock); | 756 | xfs_ilock(ip, iolock); |
742 | 757 | ||
743 | error2 = xfs_fsync(xip); | 758 | error2 = xfs_fsync(ip); |
744 | if (!error) | 759 | if (!error) |
745 | error = error2; | 760 | error = error2; |
746 | } | 761 | } |
747 | 762 | ||
748 | out_unlock_internal: | 763 | out_unlock_internal: |
749 | if (xip->i_new_size) { | 764 | if (ip->i_new_size) { |
750 | xfs_ilock(xip, XFS_ILOCK_EXCL); | 765 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
751 | xip->i_new_size = 0; | 766 | ip->i_new_size = 0; |
752 | /* | 767 | /* |
753 | * If this was a direct or synchronous I/O that failed (such | 768 | * If this was a direct or synchronous I/O that failed (such |
754 | * as ENOSPC) then part of the I/O may have been written to | 769 | * as ENOSPC) then part of the I/O may have been written to |
@@ -756,89 +771,17 @@ write_retry: | |||
756 | * file size may have been adjusted beyond the in-memory file | 771 | * file size may have been adjusted beyond the in-memory file |
757 | * size and now needs to be truncated back. | 772 | * size and now needs to be truncated back. |
758 | */ | 773 | */ |
759 | if (xip->i_d.di_size > xip->i_size) | 774 | if (ip->i_d.di_size > ip->i_size) |
760 | xip->i_d.di_size = xip->i_size; | 775 | ip->i_d.di_size = ip->i_size; |
761 | xfs_iunlock(xip, XFS_ILOCK_EXCL); | 776 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
762 | } | 777 | } |
763 | xfs_iunlock(xip, iolock); | 778 | xfs_iunlock(ip, iolock); |
764 | out_unlock_mutex: | 779 | out_unlock_mutex: |
765 | if (need_i_mutex) | 780 | if (need_i_mutex) |
766 | mutex_unlock(&inode->i_mutex); | 781 | mutex_unlock(&inode->i_mutex); |
767 | return -error; | 782 | return -error; |
768 | } | 783 | } |
769 | 784 | ||
770 | STATIC ssize_t | ||
771 | xfs_file_aio_read( | ||
772 | struct kiocb *iocb, | ||
773 | const struct iovec *iov, | ||
774 | unsigned long nr_segs, | ||
775 | loff_t pos) | ||
776 | { | ||
777 | struct file *file = iocb->ki_filp; | ||
778 | int ioflags = 0; | ||
779 | |||
780 | BUG_ON(iocb->ki_pos != pos); | ||
781 | if (unlikely(file->f_flags & O_DIRECT)) | ||
782 | ioflags |= IO_ISDIRECT; | ||
783 | if (file->f_mode & FMODE_NOCMTIME) | ||
784 | ioflags |= IO_INVIS; | ||
785 | return xfs_read(XFS_I(file->f_path.dentry->d_inode), iocb, iov, | ||
786 | nr_segs, &iocb->ki_pos, ioflags); | ||
787 | } | ||
788 | |||
789 | STATIC ssize_t | ||
790 | xfs_file_aio_write( | ||
791 | struct kiocb *iocb, | ||
792 | const struct iovec *iov, | ||
793 | unsigned long nr_segs, | ||
794 | loff_t pos) | ||
795 | { | ||
796 | struct file *file = iocb->ki_filp; | ||
797 | int ioflags = 0; | ||
798 | |||
799 | BUG_ON(iocb->ki_pos != pos); | ||
800 | if (unlikely(file->f_flags & O_DIRECT)) | ||
801 | ioflags |= IO_ISDIRECT; | ||
802 | if (file->f_mode & FMODE_NOCMTIME) | ||
803 | ioflags |= IO_INVIS; | ||
804 | return xfs_write(XFS_I(file->f_mapping->host), iocb, iov, nr_segs, | ||
805 | &iocb->ki_pos, ioflags); | ||
806 | } | ||
807 | |||
808 | STATIC ssize_t | ||
809 | xfs_file_splice_read( | ||
810 | struct file *infilp, | ||
811 | loff_t *ppos, | ||
812 | struct pipe_inode_info *pipe, | ||
813 | size_t len, | ||
814 | unsigned int flags) | ||
815 | { | ||
816 | int ioflags = 0; | ||
817 | |||
818 | if (infilp->f_mode & FMODE_NOCMTIME) | ||
819 | ioflags |= IO_INVIS; | ||
820 | |||
821 | return xfs_splice_read(XFS_I(infilp->f_path.dentry->d_inode), | ||
822 | infilp, ppos, pipe, len, flags, ioflags); | ||
823 | } | ||
824 | |||
825 | STATIC ssize_t | ||
826 | xfs_file_splice_write( | ||
827 | struct pipe_inode_info *pipe, | ||
828 | struct file *outfilp, | ||
829 | loff_t *ppos, | ||
830 | size_t len, | ||
831 | unsigned int flags) | ||
832 | { | ||
833 | int ioflags = 0; | ||
834 | |||
835 | if (outfilp->f_mode & FMODE_NOCMTIME) | ||
836 | ioflags |= IO_INVIS; | ||
837 | |||
838 | return xfs_splice_write(XFS_I(outfilp->f_path.dentry->d_inode), | ||
839 | pipe, outfilp, ppos, len, flags, ioflags); | ||
840 | } | ||
841 | |||
842 | STATIC int | 785 | STATIC int |
843 | xfs_file_open( | 786 | xfs_file_open( |
844 | struct inode *inode, | 787 | struct inode *inode, |