Commit 63c642fd authored by Nathan Scott's avatar Nathan Scott Committed by Christoph Hellwig

[XFS] Fix vmtruncate abuse in the XFS setattr ATTR_SIZE operation.

SGI Modid: xfs-linux:xfs-kern:170344a
parent a9bbe1cf
...@@ -247,10 +247,11 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh) ...@@ -247,10 +247,11 @@ static inline void set_buffer_unwritten_io(struct buffer_head *bh)
#define howmany(x, y) (((x)+((y)-1))/(y)) #define howmany(x, y) (((x)+((y)-1))/(y))
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) #define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
static inline void xfs_stack_trace(void) #define xfs_stack_trace() dump_stack()
{
dump_stack(); #define xfs_itruncate_data(ip, off) \
} (-vmtruncate(LINVFS_GET_IP(XFS_ITOV(ip)), (off)))
/* Move the kernel do_div definition off to one side */ /* Move the kernel do_div definition off to one side */
......
...@@ -680,18 +680,12 @@ xfs_setattr( ...@@ -680,18 +680,12 @@ xfs_setattr(
* once it is a part of the transaction. * once it is a part of the transaction.
*/ */
if (mask & XFS_AT_SIZE) { if (mask & XFS_AT_SIZE) {
if (vap->va_size > ip->i_d.di_size) { code = 0;
if (vap->va_size > ip->i_d.di_size)
code = xfs_igrow_start(ip, vap->va_size, credp); code = xfs_igrow_start(ip, vap->va_size, credp);
xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_iunlock(ip, XFS_ILOCK_EXCL);
} else if (vap->va_size <= ip->i_d.di_size) { if (!code)
xfs_iunlock(ip, XFS_ILOCK_EXCL); code = xfs_itruncate_data(ip, vap->va_size);
xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE,
(xfs_fsize_t)vap->va_size);
code = 0;
} else {
xfs_iunlock(ip, XFS_ILOCK_EXCL);
code = 0;
}
if (code) { if (code) {
ASSERT(tp == NULL); ASSERT(tp == NULL);
lock_flags &= ~XFS_ILOCK_EXCL; lock_flags &= ~XFS_ILOCK_EXCL;
......
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