diff options
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_lrw.c | 53 |
1 files changed, 26 insertions, 27 deletions
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index 82ab792c7fc9..b2a1beb33888 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
| @@ -724,34 +724,8 @@ start: | |||
| 724 | goto out_unlock_mutex; | 724 | goto out_unlock_mutex; |
| 725 | } | 725 | } |
| 726 | 726 | ||
| 727 | if (ioflags & IO_ISDIRECT) { | ||
| 728 | xfs_buftarg_t *target = | ||
| 729 | (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? | ||
| 730 | mp->m_rtdev_targp : mp->m_ddev_targp; | ||
| 731 | |||
| 732 | if ((pos & target->bt_smask) || (count & target->bt_smask)) { | ||
| 733 | xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); | ||
| 734 | return XFS_ERROR(-EINVAL); | ||
| 735 | } | ||
| 736 | |||
| 737 | if (!need_i_mutex && (VN_CACHED(vp) || pos > xip->i_size)) { | ||
| 738 | xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); | ||
| 739 | iolock = XFS_IOLOCK_EXCL; | ||
| 740 | locktype = VRWLOCK_WRITE; | ||
| 741 | need_i_mutex = 1; | ||
| 742 | mutex_lock(&inode->i_mutex); | ||
| 743 | xfs_ilock(xip, XFS_ILOCK_EXCL|iolock); | ||
| 744 | goto start; | ||
| 745 | } | ||
| 746 | } | ||
| 747 | |||
| 748 | new_size = pos + count; | ||
| 749 | if (new_size > xip->i_size) | ||
| 750 | io->io_new_size = new_size; | ||
| 751 | |||
| 752 | if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) && | 727 | if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) && |
| 753 | !(ioflags & IO_INVIS) && !eventsent)) { | 728 | !(ioflags & IO_INVIS) && !eventsent)) { |
| 754 | loff_t savedsize = pos; | ||
| 755 | int dmflags = FILP_DELAY_FLAG(file); | 729 | int dmflags = FILP_DELAY_FLAG(file); |
| 756 | 730 | ||
| 757 | if (need_i_mutex) | 731 | if (need_i_mutex) |
| @@ -774,10 +748,35 @@ start: | |||
| 774 | * event prevents another call to XFS_SEND_DATA, which is | 748 | * event prevents another call to XFS_SEND_DATA, which is |
| 775 | * what allows the size to change in the first place. | 749 | * what allows the size to change in the first place. |
| 776 | */ | 750 | */ |
| 777 | if ((file->f_flags & O_APPEND) && savedsize != xip->i_size) | 751 | if ((file->f_flags & O_APPEND) && pos != xip->i_size) |
| 778 | goto start; | 752 | goto start; |
| 779 | } | 753 | } |
| 780 | 754 | ||
| 755 | if (ioflags & IO_ISDIRECT) { | ||
| 756 | xfs_buftarg_t *target = | ||
| 757 | (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? | ||
| 758 | mp->m_rtdev_targp : mp->m_ddev_targp; | ||
| 759 | |||
| 760 | if ((pos & target->bt_smask) || (count & target->bt_smask)) { | ||
| 761 | xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); | ||
| 762 | return XFS_ERROR(-EINVAL); | ||
| 763 | } | ||
| 764 | |||
| 765 | if (!need_i_mutex && (VN_CACHED(vp) || pos > xip->i_size)) { | ||
| 766 | xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); | ||
| 767 | iolock = XFS_IOLOCK_EXCL; | ||
| 768 | locktype = VRWLOCK_WRITE; | ||
| 769 | need_i_mutex = 1; | ||
| 770 | mutex_lock(&inode->i_mutex); | ||
| 771 | xfs_ilock(xip, XFS_ILOCK_EXCL|iolock); | ||
| 772 | goto start; | ||
| 773 | } | ||
| 774 | } | ||
| 775 | |||
| 776 | new_size = pos + count; | ||
| 777 | if (new_size > xip->i_size) | ||
| 778 | io->io_new_size = new_size; | ||
| 779 | |||
| 781 | if (likely(!(ioflags & IO_INVIS))) { | 780 | if (likely(!(ioflags & IO_INVIS))) { |
| 782 | file_update_time(file); | 781 | file_update_time(file); |
| 783 | xfs_ichgtime_fast(xip, inode, | 782 | xfs_ichgtime_fast(xip, inode, |
