|
|
| version 1.258, 2007/03/29 03:57:43 | version 1.259, 2007/03/30 04:04:14 |
|---|---|
| Line 224 xfs_read( | Line 224 xfs_read( |
| mp->m_rtdev_targp : mp->m_ddev_targp; | mp->m_rtdev_targp : mp->m_ddev_targp; |
| if ((*offset & target->bt_smask) || | if ((*offset & target->bt_smask) || |
| (size & target->bt_smask)) { | (size & target->bt_smask)) { |
| if (*offset == ip->i_d.di_size) { | if (*offset == ip->i_size) { |
| return (0); | return (0); |
| } | } |
| return -XFS_ERROR(EINVAL); | return -XFS_ERROR(EINVAL); |
| Line 387 xfs_splice_write( | Line 387 xfs_splice_write( |
| { | { |
| xfs_inode_t *ip = XFS_BHVTOI(bdp); | xfs_inode_t *ip = XFS_BHVTOI(bdp); |
| xfs_mount_t *mp = ip->i_mount; | xfs_mount_t *mp = ip->i_mount; |
| xfs_iocore_t *io = &ip->i_iocore; | |
| ssize_t ret; | ssize_t ret; |
| struct inode *inode = outfilp->f_mapping->host; | struct inode *inode = outfilp->f_mapping->host; |
| xfs_fsize_t isize; | xfs_fsize_t isize, new_size; |
| XFS_STATS_INC(xs_write_calls); | XFS_STATS_INC(xs_write_calls); |
| if (XFS_FORCED_SHUTDOWN(ip->i_mount)) | if (XFS_FORCED_SHUTDOWN(ip->i_mount)) |
| Line 410 xfs_splice_write( | Line 411 xfs_splice_write( |
| return -error; | return -error; |
| } | } |
| } | } |
| new_size = *ppos + count; | |
| xfs_ilock(ip, XFS_ILOCK_EXCL); | |
| if (new_size > ip->i_size) | |
| io->io_new_size = new_size; | |
| xfs_iunlock(ip, XFS_ILOCK_EXCL); | |
| xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore, | xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore, |
| pipe, count, *ppos, ioflags); | pipe, count, *ppos, ioflags); |
| ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); | ret = generic_file_splice_write(pipe, outfilp, ppos, count, flags); |
| Line 420 xfs_splice_write( | Line 429 xfs_splice_write( |
| if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize)) | if (unlikely(ret < 0 && ret != -EFAULT && *ppos > isize)) |
| *ppos = isize; | *ppos = isize; |
| if (*ppos > ip->i_d.di_size) { | if (*ppos > ip->i_size) { |
| xfs_ilock(ip, XFS_ILOCK_EXCL); | xfs_ilock(ip, XFS_ILOCK_EXCL); |
| if (*ppos > ip->i_d.di_size) { | if (*ppos > ip->i_size) |
| ip->i_d.di_size = *ppos; | ip->i_size = *ppos; |
| i_size_write(inode, *ppos); | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
| ip->i_update_core = 1; | } |
| ip->i_update_size = 1; | |
| } | if (io->io_new_size) { |
| xfs_ilock(ip, XFS_ILOCK_EXCL); | |
| io->io_new_size = 0; | |
| if (ip->i_d.di_size > ip->i_size) | |
| ip->i_d.di_size = ip->i_size; | |
| xfs_iunlock(ip, XFS_ILOCK_EXCL); | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
| } | } |
| xfs_iunlock(ip, XFS_IOLOCK_EXCL); | xfs_iunlock(ip, XFS_IOLOCK_EXCL); |
| Line 711 start: | Line 724 start: |
| goto out_unlock_mutex; | goto out_unlock_mutex; |
| } | } |
| isize = i_size_read(inode); | |
| if (ioflags & IO_ISDIRECT) { | if (ioflags & IO_ISDIRECT) { |
| xfs_buftarg_t *target = | xfs_buftarg_t *target = |
| (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? | (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? |
| Line 723 start: | Line 734 start: |
| return XFS_ERROR(-EINVAL); | return XFS_ERROR(-EINVAL); |
| } | } |
| if (!need_i_mutex && (VN_CACHED(vp) || pos > isize)) { | if (!need_i_mutex && (VN_CACHED(vp) || pos > xip->i_size)) { |
| xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); | xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); |
| iolock = XFS_IOLOCK_EXCL; | iolock = XFS_IOLOCK_EXCL; |
| locktype = VRWLOCK_WRITE; | locktype = VRWLOCK_WRITE; |
| Line 735 start: | Line 746 start: |
| } | } |
| new_size = pos + count; | new_size = pos + count; |
| if (new_size > isize) | if (new_size > xip->i_size) |
| io->io_new_size = new_size; | io->io_new_size = new_size; |
| if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) && | if ((DM_EVENT_ENABLED(vp->v_vfsp, xip, DM_EVENT_WRITE) && |
| Line 751 start: | Line 762 start: |
| pos, count, | pos, count, |
| dmflags, &locktype); | dmflags, &locktype); |
| if (error) { | if (error) { |
| xfs_iunlock(xip, iolock); | goto out_unlock_internal; |
| goto out_unlock_mutex; | |
| } | } |
| xfs_ilock(xip, XFS_ILOCK_EXCL); | xfs_ilock(xip, XFS_ILOCK_EXCL); |
| eventsent = 1; | eventsent = 1; |
| Line 764 start: | Line 774 start: |
| * event prevents another call to XFS_SEND_DATA, which is | * event prevents another call to XFS_SEND_DATA, which is |
| * what allows the size to change in the first place. | * what allows the size to change in the first place. |
| */ | */ |
| if ((file->f_flags & O_APPEND) && savedsize != isize) { | if ((file->f_flags & O_APPEND) && savedsize != xip->i_size) |
| goto start; | goto start; |
| } | |
| } | } |
| if (likely(!(ioflags & IO_INVIS))) { | if (likely(!(ioflags & IO_INVIS))) { |
| Line 784 start: | Line 793 start: |
| * to zero it out up to the new size. | * to zero it out up to the new size. |
| */ | */ |
| if (pos > isize) { | if (pos > xip->i_size) { |
| error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, isize); | error = xfs_zero_eof(BHV_TO_VNODE(bdp), io, pos, xip->i_size); |
| if (error) { | if (error) { |
| xfs_iunlock(xip, XFS_ILOCK_EXCL|iolock); | xfs_iunlock(xip, XFS_ILOCK_EXCL); |
| goto out_unlock_mutex; | goto out_unlock_internal; |
| } | } |
| } | } |
| xfs_iunlock(xip, XFS_ILOCK_EXCL); | xfs_iunlock(xip, XFS_ILOCK_EXCL); |
| Line 808 start: | Line 817 start: |
| if (likely(!error)) | if (likely(!error)) |
| error = -remove_suid(file->f_path.dentry); | error = -remove_suid(file->f_path.dentry); |
| if (unlikely(error)) { | if (unlikely(error)) { |
| xfs_iunlock(xip, iolock); | goto out_unlock_internal; |
| goto out_unlock_mutex; | |
| } | } |
| } | } |
| Line 879 retry: | Line 887 retry: |
| error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp, | error = XFS_SEND_NAMESP(xip->i_mount, DM_EVENT_NOSPACE, vp, |
| DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL, | DM_RIGHT_NULL, vp, DM_RIGHT_NULL, NULL, NULL, |
| 0, 0, 0); /* Delay flag intentionally unused */ | 0, 0, 0); /* Delay flag intentionally unused */ |
| if (error) | |
| goto out_nounlocks; | |
| if (need_i_mutex) | if (need_i_mutex) |
| mutex_lock(&inode->i_mutex); | mutex_lock(&inode->i_mutex); |
| xfs_rwlock(bdp, locktype); | xfs_rwlock(bdp, locktype); |
| pos = xip->i_d.di_size; | if (error) |
| goto out_unlock_internal; | |
| pos = xip->i_size; | |
| ret = 0; | ret = 0; |
| goto retry; | goto retry; |
| } | } |
| Line 893 retry: | Line 901 retry: |
| if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize)) | if (unlikely(ret < 0 && ret != -EFAULT && *offset > isize)) |
| *offset = isize; | *offset = isize; |
| if (*offset > xip->i_d.di_size) { | if (*offset > xip->i_size) { |
| xfs_ilock(xip, XFS_ILOCK_EXCL); | xfs_ilock(xip, XFS_ILOCK_EXCL); |
| if (*offset > xip->i_d.di_size) { | if (*offset > xip->i_size) |
| xip->i_d.di_size = *offset; | xip->i_size = *offset; |
| i_size_write(inode, *offset); | |
| xip->i_update_core = 1; | |
| xip->i_update_size = 1; | |
| } | |
| xfs_iunlock(xip, XFS_ILOCK_EXCL); | xfs_iunlock(xip, XFS_ILOCK_EXCL); |
| } | } |
| Line 922 retry: | Line 926 retry: |
| error = sync_page_range(inode, mapping, pos, ret); | error = sync_page_range(inode, mapping, pos, ret); |
| if (!error) | if (!error) |
| error = ret; | error = -ret; |
| return error; | if (need_i_mutex) |
| mutex_lock(&inode->i_mutex); | |
| xfs_rwlock(bdp, locktype); | |
| } | } |
| out_unlock_internal: | out_unlock_internal: |
| if (io->io_new_size) { | |
| xfs_ilock(xip, XFS_ILOCK_EXCL); | |
| io->io_new_size = 0; | |
| /* | |
| * If this was a direct or synchronous I/O that failed (such | |
| * as ENOSPC) then part of the I/O may have been written to | |
| * disk before the error occured. In this case the on-disk | |
| * file size may have been adjusted beyond the in-memory file | |
| * size and now needs to be truncated back. | |
| */ | |
| if (xip->i_d.di_size > xip->i_size) | |
| xip->i_d.di_size = xip->i_size; | |
| xfs_iunlock(xip, XFS_ILOCK_EXCL); | |
| } | |
| xfs_rwunlock(bdp, locktype); | xfs_rwunlock(bdp, locktype); |
| out_unlock_mutex: | out_unlock_mutex: |
| if (need_i_mutex) | if (need_i_mutex) |
| mutex_unlock(&inode->i_mutex); | mutex_unlock(&inode->i_mutex); |
| out_nounlocks: | |
| return -error; | return -error; |
| } | } |