diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-15 08:57:32 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-15 08:57:32 +0300 |
commit | a80099a152d0719e2d8d750e07f4ffa991553d30 (patch) | |
tree | fc2d76c18e09220c0ddbdb6575662dd23e1782e0 | |
parent | bc243704fb3c97f3631994bbe543782a09482afb (diff) | |
parent | d6ab17f261919d212ec0a9e33d01f46df0ec1fde (diff) | |
download | linux-a80099a152d0719e2d8d750e07f4ffa991553d30.tar.xz |
Merge tag 'xfs-4.13-merge-6' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull XFS fixes from Darrick Wong:
"Largely debugging and regression fixes.
- Add some locking assertions for the _ilock helpers.
- Revert the XFS_QMOPT_NOLOCK patch; after discussion with hch the
online fsck patch that would have needed it has been redesigned and
no longer needs it.
- Fix behavioral regression of SEEK_HOLE/DATA with negative offsets
to match 4.12-era XFS behavior"
* tag 'xfs-4.13-merge-6' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
vfs: in iomap seek_{hole,data}, return -ENXIO for negative offsets
Revert "xfs: grab dquots without taking the ilock"
xfs: assert locking precondition in xfs_readlink_bmap_ilocked
xfs: assert locking precondŃ–tion in xfs_attr_list_int_ilocked
xfs: fixup xfs_attr_get_ilocked
-rw-r--r-- | fs/iomap.c | 8 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_attr.c | 4 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_quota_defs.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_attr_list.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_dquot.c | 14 | ||||
-rw-r--r-- | fs/xfs/xfs_symlink.c | 2 |
6 files changed, 15 insertions, 17 deletions
diff --git a/fs/iomap.c b/fs/iomap.c index 173222863aca..039266128b7f 100644 --- a/fs/iomap.c +++ b/fs/iomap.c @@ -610,8 +610,8 @@ iomap_seek_hole(struct inode *inode, loff_t offset, const struct iomap_ops *ops) loff_t length = size - offset; loff_t ret; - /* Nothing to be found beyond the end of the file. */ - if (offset >= size) + /* Nothing to be found before or beyond the end of the file. */ + if (offset < 0 || offset >= size) return -ENXIO; while (length > 0) { @@ -656,8 +656,8 @@ iomap_seek_data(struct inode *inode, loff_t offset, const struct iomap_ops *ops) loff_t length = size - offset; loff_t ret; - /* Nothing to be found beyond the end of the file. */ - if (offset >= size) + /* Nothing to be found before or beyond the end of the file. */ + if (offset < 0 || offset >= size) return -ENXIO; while (length > 0) { diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index ef8a1c75a467..de7b9bd30bec 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -114,12 +114,14 @@ xfs_inode_hasattr( * Overall external interface routines. *========================================================================*/ -/* Retrieve an extended attribute and its value. Must have iolock. */ +/* Retrieve an extended attribute and its value. Must have ilock. */ int xfs_attr_get_ilocked( struct xfs_inode *ip, struct xfs_da_args *args) { + ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); + if (!xfs_inode_hasattr(ip)) return -ENOATTR; else if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h index 2834574cb6e7..d69c772271cb 100644 --- a/fs/xfs/libxfs/xfs_quota_defs.h +++ b/fs/xfs/libxfs/xfs_quota_defs.h @@ -136,8 +136,6 @@ typedef uint16_t xfs_qwarncnt_t; */ #define XFS_QMOPT_INHERIT 0x1000000 -#define XFS_QMOPT_NOLOCK 0x2000000 /* don't ilock during dqget */ - /* * flags to xfs_trans_mod_dquot. */ diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 545eca508d42..7740c8a5e736 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -463,6 +463,8 @@ xfs_attr_list_int_ilocked( { struct xfs_inode *dp = context->dp; + ASSERT(xfs_isilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); + /* * Decide on what work routines to call based on the inode size. */ diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index f89f7b5241e6..fd2ef8c2c9a7 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -472,23 +472,18 @@ xfs_qm_dqtobp( struct xfs_mount *mp = dqp->q_mount; xfs_dqid_t id = be32_to_cpu(dqp->q_core.d_id); struct xfs_trans *tp = (tpp ? *tpp : NULL); - uint lock_mode = 0; + uint lock_mode; quotip = xfs_quota_inode(dqp->q_mount, dqp->dq_flags); dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk; - ASSERT(!(flags & XFS_QMOPT_NOLOCK) || - xfs_isilocked(quotip, XFS_ILOCK_SHARED) || - xfs_isilocked(quotip, XFS_ILOCK_EXCL)); - if (!(flags & XFS_QMOPT_NOLOCK)) - lock_mode = xfs_ilock_data_map_shared(quotip); + lock_mode = xfs_ilock_data_map_shared(quotip); if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) { /* * Return if this type of quotas is turned off while we * didn't have the quota inode lock. */ - if (lock_mode) - xfs_iunlock(quotip, lock_mode); + xfs_iunlock(quotip, lock_mode); return -ESRCH; } @@ -498,8 +493,7 @@ xfs_qm_dqtobp( error = xfs_bmapi_read(quotip, dqp->q_fileoffset, XFS_DQUOT_CLUSTER_SIZE_FSB, &map, &nmaps, 0); - if (lock_mode) - xfs_iunlock(quotip, lock_mode); + xfs_iunlock(quotip, lock_mode); if (error) return error; diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 12cd9cf7de41..23a50d7aa46a 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -61,6 +61,8 @@ xfs_readlink_bmap_ilocked( int fsblocks = 0; int offset; + ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); + fsblocks = xfs_symlink_blocks(mp, pathlen); error = xfs_bmapi_read(ip, 0, fsblocks, mval, &nmaps, 0); if (error) |