diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-05 15:59:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-05 15:59:32 -0500 |
commit | 12e971b652e3166c3039e09ad2cb5568fc7f040a (patch) | |
tree | b1859ba656cc2577569b08f911a08f01ea0449e7 | |
parent | f842839cd85be149ff158bddf0260cd1a8db69e5 (diff) | |
parent | b4d8ad7fd3a18e6d92d4ebe858185c704604a57d (diff) |
Merge tag 'xfs-4.15-fixes-10' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull XFS fixes from Darrick Wong:
"I have just a few fixes for bugs and resource cleanup problems this
week:
- Fix resource cleanup of failed quota initialization
- Fix integer overflow problems wrt s_maxbytes"
* tag 'xfs-4.15-fixes-10' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
xfs: fix s_maxbytes overflow problems
xfs: quota: check result of register_shrinker()
xfs: quota: fix missed destroy of qi_tree_lock
-rw-r--r-- | fs/xfs/xfs_aops.c | 4 | ||||
-rw-r--r-- | fs/xfs/xfs_iomap.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_qm.c | 46 |
3 files changed, 33 insertions, 19 deletions
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 21e2d70884e1..4fc526a27a94 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c | |||
@@ -399,7 +399,7 @@ xfs_map_blocks( | |||
399 | (ip->i_df.if_flags & XFS_IFEXTENTS)); | 399 | (ip->i_df.if_flags & XFS_IFEXTENTS)); |
400 | ASSERT(offset <= mp->m_super->s_maxbytes); | 400 | ASSERT(offset <= mp->m_super->s_maxbytes); |
401 | 401 | ||
402 | if ((xfs_ufsize_t)offset + count > mp->m_super->s_maxbytes) | 402 | if (offset > mp->m_super->s_maxbytes - count) |
403 | count = mp->m_super->s_maxbytes - offset; | 403 | count = mp->m_super->s_maxbytes - offset; |
404 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); | 404 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); |
405 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 405 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
@@ -1312,7 +1312,7 @@ xfs_get_blocks( | |||
1312 | lockmode = xfs_ilock_data_map_shared(ip); | 1312 | lockmode = xfs_ilock_data_map_shared(ip); |
1313 | 1313 | ||
1314 | ASSERT(offset <= mp->m_super->s_maxbytes); | 1314 | ASSERT(offset <= mp->m_super->s_maxbytes); |
1315 | if ((xfs_ufsize_t)offset + size > mp->m_super->s_maxbytes) | 1315 | if (offset > mp->m_super->s_maxbytes - size) |
1316 | size = mp->m_super->s_maxbytes - offset; | 1316 | size = mp->m_super->s_maxbytes - offset; |
1317 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size); | 1317 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size); |
1318 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 1318 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 7ab52a8bc0a9..66e1edbfb2b2 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -1006,7 +1006,7 @@ xfs_file_iomap_begin( | |||
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | ASSERT(offset <= mp->m_super->s_maxbytes); | 1008 | ASSERT(offset <= mp->m_super->s_maxbytes); |
1009 | if ((xfs_fsize_t)offset + length > mp->m_super->s_maxbytes) | 1009 | if (offset > mp->m_super->s_maxbytes - length) |
1010 | length = mp->m_super->s_maxbytes - offset; | 1010 | length = mp->m_super->s_maxbytes - offset; |
1011 | offset_fsb = XFS_B_TO_FSBT(mp, offset); | 1011 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
1012 | end_fsb = XFS_B_TO_FSB(mp, offset + length); | 1012 | end_fsb = XFS_B_TO_FSB(mp, offset + length); |
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index ec952dfad359..b897b11afb2c 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c | |||
@@ -48,7 +48,7 @@ | |||
48 | STATIC int xfs_qm_init_quotainos(xfs_mount_t *); | 48 | STATIC int xfs_qm_init_quotainos(xfs_mount_t *); |
49 | STATIC int xfs_qm_init_quotainfo(xfs_mount_t *); | 49 | STATIC int xfs_qm_init_quotainfo(xfs_mount_t *); |
50 | 50 | ||
51 | 51 | STATIC void xfs_qm_destroy_quotainos(xfs_quotainfo_t *qi); | |
52 | STATIC void xfs_qm_dqfree_one(struct xfs_dquot *dqp); | 52 | STATIC void xfs_qm_dqfree_one(struct xfs_dquot *dqp); |
53 | /* | 53 | /* |
54 | * We use the batch lookup interface to iterate over the dquots as it | 54 | * We use the batch lookup interface to iterate over the dquots as it |
@@ -695,9 +695,17 @@ xfs_qm_init_quotainfo( | |||
695 | qinf->qi_shrinker.scan_objects = xfs_qm_shrink_scan; | 695 | qinf->qi_shrinker.scan_objects = xfs_qm_shrink_scan; |
696 | qinf->qi_shrinker.seeks = DEFAULT_SEEKS; | 696 | qinf->qi_shrinker.seeks = DEFAULT_SEEKS; |
697 | qinf->qi_shrinker.flags = SHRINKER_NUMA_AWARE; | 697 | qinf->qi_shrinker.flags = SHRINKER_NUMA_AWARE; |
698 | register_shrinker(&qinf->qi_shrinker); | 698 | |
699 | error = register_shrinker(&qinf->qi_shrinker); | ||
700 | if (error) | ||
701 | goto out_free_inos; | ||
702 | |||
699 | return 0; | 703 | return 0; |
700 | 704 | ||
705 | out_free_inos: | ||
706 | mutex_destroy(&qinf->qi_quotaofflock); | ||
707 | mutex_destroy(&qinf->qi_tree_lock); | ||
708 | xfs_qm_destroy_quotainos(qinf); | ||
701 | out_free_lru: | 709 | out_free_lru: |
702 | list_lru_destroy(&qinf->qi_lru); | 710 | list_lru_destroy(&qinf->qi_lru); |
703 | out_free_qinf: | 711 | out_free_qinf: |
@@ -706,7 +714,6 @@ out_free_qinf: | |||
706 | return error; | 714 | return error; |
707 | } | 715 | } |
708 | 716 | ||
709 | |||
710 | /* | 717 | /* |
711 | * Gets called when unmounting a filesystem or when all quotas get | 718 | * Gets called when unmounting a filesystem or when all quotas get |
712 | * turned off. | 719 | * turned off. |
@@ -723,19 +730,8 @@ xfs_qm_destroy_quotainfo( | |||
723 | 730 | ||
724 | unregister_shrinker(&qi->qi_shrinker); | 731 | unregister_shrinker(&qi->qi_shrinker); |
725 | list_lru_destroy(&qi->qi_lru); | 732 | list_lru_destroy(&qi->qi_lru); |
726 | 733 | xfs_qm_destroy_quotainos(qi); | |
727 | if (qi->qi_uquotaip) { | 734 | mutex_destroy(&qi->qi_tree_lock); |
728 | IRELE(qi->qi_uquotaip); | ||
729 | qi->qi_uquotaip = NULL; /* paranoia */ | ||
730 | } | ||
731 | if (qi->qi_gquotaip) { | ||
732 | IRELE(qi->qi_gquotaip); | ||
733 | qi->qi_gquotaip = NULL; | ||
734 | } | ||
735 | if (qi->qi_pquotaip) { | ||
736 | IRELE(qi->qi_pquotaip); | ||
737 | qi->qi_pquotaip = NULL; | ||
738 | } | ||
739 | mutex_destroy(&qi->qi_quotaofflock); | 735 | mutex_destroy(&qi->qi_quotaofflock); |
740 | kmem_free(qi); | 736 | kmem_free(qi); |
741 | mp->m_quotainfo = NULL; | 737 | mp->m_quotainfo = NULL; |
@@ -1600,6 +1596,24 @@ error_rele: | |||
1600 | } | 1596 | } |
1601 | 1597 | ||
1602 | STATIC void | 1598 | STATIC void |
1599 | xfs_qm_destroy_quotainos( | ||
1600 | xfs_quotainfo_t *qi) | ||
1601 | { | ||
1602 | if (qi->qi_uquotaip) { | ||
1603 | IRELE(qi->qi_uquotaip); | ||
1604 | qi->qi_uquotaip = NULL; /* paranoia */ | ||
1605 | } | ||
1606 | if (qi->qi_gquotaip) { | ||
1607 | IRELE(qi->qi_gquotaip); | ||
1608 | qi->qi_gquotaip = NULL; | ||
1609 | } | ||
1610 | if (qi->qi_pquotaip) { | ||
1611 | IRELE(qi->qi_pquotaip); | ||
1612 | qi->qi_pquotaip = NULL; | ||
1613 | } | ||
1614 | } | ||
1615 | |||
1616 | STATIC void | ||
1603 | xfs_qm_dqfree_one( | 1617 | xfs_qm_dqfree_one( |
1604 | struct xfs_dquot *dqp) | 1618 | struct xfs_dquot *dqp) |
1605 | { | 1619 | { |