aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-15 01:57:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-15 01:57:32 -0400
commita80099a152d0719e2d8d750e07f4ffa991553d30 (patch)
treefc2d76c18e09220c0ddbdb6575662dd23e1782e0
parentbc243704fb3c97f3631994bbe543782a09482afb (diff)
parentd6ab17f261919d212ec0a9e33d01f46df0ec1fde (diff)
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.c8
-rw-r--r--fs/xfs/libxfs/xfs_attr.c4
-rw-r--r--fs/xfs/libxfs/xfs_quota_defs.h2
-rw-r--r--fs/xfs/xfs_attr_list.c2
-rw-r--r--fs/xfs/xfs_dquot.c14
-rw-r--r--fs/xfs/xfs_symlink.c2
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)
610 loff_t length = size - offset; 610 loff_t length = size - offset;
611 loff_t ret; 611 loff_t ret;
612 612
613 /* Nothing to be found beyond the end of the file. */ 613 /* Nothing to be found before or beyond the end of the file. */
614 if (offset >= size) 614 if (offset < 0 || offset >= size)
615 return -ENXIO; 615 return -ENXIO;
616 616
617 while (length > 0) { 617 while (length > 0) {
@@ -656,8 +656,8 @@ iomap_seek_data(struct inode *inode, loff_t offset, const struct iomap_ops *ops)
656 loff_t length = size - offset; 656 loff_t length = size - offset;
657 loff_t ret; 657 loff_t ret;
658 658
659 /* Nothing to be found beyond the end of the file. */ 659 /* Nothing to be found before or beyond the end of the file. */
660 if (offset >= size) 660 if (offset < 0 || offset >= size)
661 return -ENXIO; 661 return -ENXIO;
662 662
663 while (length > 0) { 663 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(
114 * Overall external interface routines. 114 * Overall external interface routines.
115 *========================================================================*/ 115 *========================================================================*/
116 116
117/* Retrieve an extended attribute and its value. Must have iolock. */ 117/* Retrieve an extended attribute and its value. Must have ilock. */
118int 118int
119xfs_attr_get_ilocked( 119xfs_attr_get_ilocked(
120 struct xfs_inode *ip, 120 struct xfs_inode *ip,
121 struct xfs_da_args *args) 121 struct xfs_da_args *args)
122{ 122{
123 ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
124
123 if (!xfs_inode_hasattr(ip)) 125 if (!xfs_inode_hasattr(ip))
124 return -ENOATTR; 126 return -ENOATTR;
125 else if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) 127 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;
136 */ 136 */
137#define XFS_QMOPT_INHERIT 0x1000000 137#define XFS_QMOPT_INHERIT 0x1000000
138 138
139#define XFS_QMOPT_NOLOCK 0x2000000 /* don't ilock during dqget */
140
141/* 139/*
142 * flags to xfs_trans_mod_dquot. 140 * flags to xfs_trans_mod_dquot.
143 */ 141 */
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(
463{ 463{
464 struct xfs_inode *dp = context->dp; 464 struct xfs_inode *dp = context->dp;
465 465
466 ASSERT(xfs_isilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
467
466 /* 468 /*
467 * Decide on what work routines to call based on the inode size. 469 * Decide on what work routines to call based on the inode size.
468 */ 470 */
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(
472 struct xfs_mount *mp = dqp->q_mount; 472 struct xfs_mount *mp = dqp->q_mount;
473 xfs_dqid_t id = be32_to_cpu(dqp->q_core.d_id); 473 xfs_dqid_t id = be32_to_cpu(dqp->q_core.d_id);
474 struct xfs_trans *tp = (tpp ? *tpp : NULL); 474 struct xfs_trans *tp = (tpp ? *tpp : NULL);
475 uint lock_mode = 0; 475 uint lock_mode;
476 476
477 quotip = xfs_quota_inode(dqp->q_mount, dqp->dq_flags); 477 quotip = xfs_quota_inode(dqp->q_mount, dqp->dq_flags);
478 dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk; 478 dqp->q_fileoffset = (xfs_fileoff_t)id / mp->m_quotainfo->qi_dqperchunk;
479 479
480 ASSERT(!(flags & XFS_QMOPT_NOLOCK) || 480 lock_mode = xfs_ilock_data_map_shared(quotip);
481 xfs_isilocked(quotip, XFS_ILOCK_SHARED) ||
482 xfs_isilocked(quotip, XFS_ILOCK_EXCL));
483 if (!(flags & XFS_QMOPT_NOLOCK))
484 lock_mode = xfs_ilock_data_map_shared(quotip);
485 if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) { 481 if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) {
486 /* 482 /*
487 * Return if this type of quotas is turned off while we 483 * Return if this type of quotas is turned off while we
488 * didn't have the quota inode lock. 484 * didn't have the quota inode lock.
489 */ 485 */
490 if (lock_mode) 486 xfs_iunlock(quotip, lock_mode);
491 xfs_iunlock(quotip, lock_mode);
492 return -ESRCH; 487 return -ESRCH;
493 } 488 }
494 489
@@ -498,8 +493,7 @@ xfs_qm_dqtobp(
498 error = xfs_bmapi_read(quotip, dqp->q_fileoffset, 493 error = xfs_bmapi_read(quotip, dqp->q_fileoffset,
499 XFS_DQUOT_CLUSTER_SIZE_FSB, &map, &nmaps, 0); 494 XFS_DQUOT_CLUSTER_SIZE_FSB, &map, &nmaps, 0);
500 495
501 if (lock_mode) 496 xfs_iunlock(quotip, lock_mode);
502 xfs_iunlock(quotip, lock_mode);
503 if (error) 497 if (error)
504 return error; 498 return error;
505 499
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(
61 int fsblocks = 0; 61 int fsblocks = 0;
62 int offset; 62 int offset;
63 63
64 ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
65
64 fsblocks = xfs_symlink_blocks(mp, pathlen); 66 fsblocks = xfs_symlink_blocks(mp, pathlen);
65 error = xfs_bmapi_read(ip, 0, fsblocks, mval, &nmaps, 0); 67 error = xfs_bmapi_read(ip, 0, fsblocks, mval, &nmaps, 0);
66 if (error) 68 if (error)