diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-15 01:57:32 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-15 01:57:32 -0400 |
commit | a80099a152d0719e2d8d750e07f4ffa991553d30 (patch) | |
tree | fc2d76c18e09220c0ddbdb6575662dd23e1782e0 | |
parent | bc243704fb3c97f3631994bbe543782a09482afb (diff) | |
parent | d6ab17f261919d212ec0a9e33d01f46df0ec1fde (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.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) | |||
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. */ |
118 | int | 118 | int |
119 | xfs_attr_get_ilocked( | 119 | xfs_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) |