diff options
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl.c | 20 | ||||
| -rw-r--r-- | fs/xfs/quota/xfs_qm.c | 46 | ||||
| -rw-r--r-- | fs/xfs/xfs_alloc.h | 16 | ||||
| -rw-r--r-- | fs/xfs/xfs_bmap.c | 61 | ||||
| -rw-r--r-- | fs/xfs/xfs_buf_item.c | 12 | ||||
| -rw-r--r-- | fs/xfs/xfs_extfree_item.c | 3 | ||||
| -rw-r--r-- | fs/xfs/xfs_iomap.c | 7 | ||||
| -rw-r--r-- | fs/xfs/xfs_log.h | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_log_cil.c | 15 | ||||
| -rw-r--r-- | fs/xfs/xfs_trans.c | 41 |
10 files changed, 152 insertions, 71 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index b06ede1d0bed..f5e2a19e0f8e 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
| @@ -985,10 +985,22 @@ xfs_ioctl_setattr( | |||
| 985 | 985 | ||
| 986 | /* | 986 | /* |
| 987 | * Extent size must be a multiple of the appropriate block | 987 | * Extent size must be a multiple of the appropriate block |
| 988 | * size, if set at all. | 988 | * size, if set at all. It must also be smaller than the |
| 989 | * maximum extent size supported by the filesystem. | ||
| 990 | * | ||
| 991 | * Also, for non-realtime files, limit the extent size hint to | ||
| 992 | * half the size of the AGs in the filesystem so alignment | ||
| 993 | * doesn't result in extents larger than an AG. | ||
| 989 | */ | 994 | */ |
| 990 | if (fa->fsx_extsize != 0) { | 995 | if (fa->fsx_extsize != 0) { |
| 991 | xfs_extlen_t size; | 996 | xfs_extlen_t size; |
| 997 | xfs_fsblock_t extsize_fsb; | ||
| 998 | |||
| 999 | extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize); | ||
| 1000 | if (extsize_fsb > MAXEXTLEN) { | ||
| 1001 | code = XFS_ERROR(EINVAL); | ||
| 1002 | goto error_return; | ||
| 1003 | } | ||
| 992 | 1004 | ||
| 993 | if (XFS_IS_REALTIME_INODE(ip) || | 1005 | if (XFS_IS_REALTIME_INODE(ip) || |
| 994 | ((mask & FSX_XFLAGS) && | 1006 | ((mask & FSX_XFLAGS) && |
| @@ -997,6 +1009,10 @@ xfs_ioctl_setattr( | |||
| 997 | mp->m_sb.sb_blocklog; | 1009 | mp->m_sb.sb_blocklog; |
| 998 | } else { | 1010 | } else { |
| 999 | size = mp->m_sb.sb_blocksize; | 1011 | size = mp->m_sb.sb_blocksize; |
| 1012 | if (extsize_fsb > mp->m_sb.sb_agblocks / 2) { | ||
| 1013 | code = XFS_ERROR(EINVAL); | ||
| 1014 | goto error_return; | ||
| 1015 | } | ||
| 1000 | } | 1016 | } |
| 1001 | 1017 | ||
| 1002 | if (fa->fsx_extsize % size) { | 1018 | if (fa->fsx_extsize % size) { |
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index f8e854b4fde8..206a2815ced6 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
| @@ -1863,12 +1863,14 @@ xfs_qm_dqreclaim_one(void) | |||
| 1863 | xfs_dquot_t *dqpout; | 1863 | xfs_dquot_t *dqpout; |
| 1864 | xfs_dquot_t *dqp; | 1864 | xfs_dquot_t *dqp; |
| 1865 | int restarts; | 1865 | int restarts; |
| 1866 | int startagain; | ||
| 1866 | 1867 | ||
| 1867 | restarts = 0; | 1868 | restarts = 0; |
| 1868 | dqpout = NULL; | 1869 | dqpout = NULL; |
| 1869 | 1870 | ||
| 1870 | /* lockorder: hashchainlock, freelistlock, mplistlock, dqlock, dqflock */ | 1871 | /* lockorder: hashchainlock, freelistlock, mplistlock, dqlock, dqflock */ |
| 1871 | startagain: | 1872 | again: |
| 1873 | startagain = 0; | ||
| 1872 | mutex_lock(&xfs_Gqm->qm_dqfrlist_lock); | 1874 | mutex_lock(&xfs_Gqm->qm_dqfrlist_lock); |
| 1873 | 1875 | ||
| 1874 | list_for_each_entry(dqp, &xfs_Gqm->qm_dqfrlist, q_freelist) { | 1876 | list_for_each_entry(dqp, &xfs_Gqm->qm_dqfrlist, q_freelist) { |
| @@ -1885,13 +1887,10 @@ startagain: | |||
| 1885 | ASSERT(! (dqp->dq_flags & XFS_DQ_INACTIVE)); | 1887 | ASSERT(! (dqp->dq_flags & XFS_DQ_INACTIVE)); |
| 1886 | 1888 | ||
| 1887 | trace_xfs_dqreclaim_want(dqp); | 1889 | trace_xfs_dqreclaim_want(dqp); |
| 1888 | |||
| 1889 | xfs_dqunlock(dqp); | ||
| 1890 | mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); | ||
| 1891 | if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) | ||
| 1892 | return NULL; | ||
| 1893 | XQM_STATS_INC(xqmstats.xs_qm_dqwants); | 1890 | XQM_STATS_INC(xqmstats.xs_qm_dqwants); |
| 1894 | goto startagain; | 1891 | restarts++; |
| 1892 | startagain = 1; | ||
| 1893 | goto dqunlock; | ||
| 1895 | } | 1894 | } |
| 1896 | 1895 | ||
| 1897 | /* | 1896 | /* |
| @@ -1906,23 +1905,20 @@ startagain: | |||
| 1906 | ASSERT(list_empty(&dqp->q_mplist)); | 1905 | ASSERT(list_empty(&dqp->q_mplist)); |
| 1907 | list_del_init(&dqp->q_freelist); | 1906 | list_del_init(&dqp->q_freelist); |
| 1908 | xfs_Gqm->qm_dqfrlist_cnt--; | 1907 | xfs_Gqm->qm_dqfrlist_cnt--; |
| 1909 | xfs_dqunlock(dqp); | ||
| 1910 | dqpout = dqp; | 1908 | dqpout = dqp; |
| 1911 | XQM_STATS_INC(xqmstats.xs_qm_dqinact_reclaims); | 1909 | XQM_STATS_INC(xqmstats.xs_qm_dqinact_reclaims); |
| 1912 | break; | 1910 | goto dqunlock; |
| 1913 | } | 1911 | } |
| 1914 | 1912 | ||
| 1915 | ASSERT(dqp->q_hash); | 1913 | ASSERT(dqp->q_hash); |
| 1916 | ASSERT(!list_empty(&dqp->q_mplist)); | 1914 | ASSERT(!list_empty(&dqp->q_mplist)); |
| 1917 | 1915 | ||
| 1918 | /* | 1916 | /* |
| 1919 | * Try to grab the flush lock. If this dquot is in the process of | 1917 | * Try to grab the flush lock. If this dquot is in the process |
| 1920 | * getting flushed to disk, we don't want to reclaim it. | 1918 | * of getting flushed to disk, we don't want to reclaim it. |
| 1921 | */ | 1919 | */ |
| 1922 | if (!xfs_dqflock_nowait(dqp)) { | 1920 | if (!xfs_dqflock_nowait(dqp)) |
| 1923 | xfs_dqunlock(dqp); | 1921 | goto dqunlock; |
| 1924 | continue; | ||
| 1925 | } | ||
| 1926 | 1922 | ||
| 1927 | /* | 1923 | /* |
| 1928 | * We have the flush lock so we know that this is not in the | 1924 | * We have the flush lock so we know that this is not in the |
| @@ -1944,8 +1940,7 @@ startagain: | |||
| 1944 | xfs_fs_cmn_err(CE_WARN, mp, | 1940 | xfs_fs_cmn_err(CE_WARN, mp, |
| 1945 | "xfs_qm_dqreclaim: dquot %p flush failed", dqp); | 1941 | "xfs_qm_dqreclaim: dquot %p flush failed", dqp); |
| 1946 | } | 1942 | } |
| 1947 | xfs_dqunlock(dqp); /* dqflush unlocks dqflock */ | 1943 | goto dqunlock; |
| 1948 | continue; | ||
| 1949 | } | 1944 | } |
| 1950 | 1945 | ||
| 1951 | /* | 1946 | /* |
| @@ -1967,13 +1962,8 @@ startagain: | |||
| 1967 | */ | 1962 | */ |
| 1968 | if (!mutex_trylock(&mp->m_quotainfo->qi_dqlist_lock)) { | 1963 | if (!mutex_trylock(&mp->m_quotainfo->qi_dqlist_lock)) { |
| 1969 | restarts++; | 1964 | restarts++; |
| 1970 | mutex_unlock(&dqp->q_hash->qh_lock); | 1965 | startagain = 1; |
| 1971 | xfs_dqfunlock(dqp); | 1966 | goto qhunlock; |
| 1972 | xfs_dqunlock(dqp); | ||
| 1973 | mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); | ||
| 1974 | if (restarts++ >= XFS_QM_RECLAIM_MAX_RESTARTS) | ||
| 1975 | return NULL; | ||
| 1976 | goto startagain; | ||
| 1977 | } | 1967 | } |
| 1978 | 1968 | ||
| 1979 | ASSERT(dqp->q_nrefs == 0); | 1969 | ASSERT(dqp->q_nrefs == 0); |
| @@ -1986,14 +1976,20 @@ startagain: | |||
| 1986 | xfs_Gqm->qm_dqfrlist_cnt--; | 1976 | xfs_Gqm->qm_dqfrlist_cnt--; |
| 1987 | dqpout = dqp; | 1977 | dqpout = dqp; |
| 1988 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); | 1978 | mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); |
| 1979 | qhunlock: | ||
| 1989 | mutex_unlock(&dqp->q_hash->qh_lock); | 1980 | mutex_unlock(&dqp->q_hash->qh_lock); |
| 1990 | dqfunlock: | 1981 | dqfunlock: |
| 1991 | xfs_dqfunlock(dqp); | 1982 | xfs_dqfunlock(dqp); |
| 1983 | dqunlock: | ||
| 1992 | xfs_dqunlock(dqp); | 1984 | xfs_dqunlock(dqp); |
| 1993 | if (dqpout) | 1985 | if (dqpout) |
| 1994 | break; | 1986 | break; |
| 1995 | if (restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) | 1987 | if (restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) |
| 1996 | return NULL; | 1988 | break; |
| 1989 | if (startagain) { | ||
| 1990 | mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); | ||
| 1991 | goto again; | ||
| 1992 | } | ||
| 1997 | } | 1993 | } |
| 1998 | mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); | 1994 | mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); |
| 1999 | return dqpout; | 1995 | return dqpout; |
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h index 0ab56b32c7eb..d0b3bc72005b 100644 --- a/fs/xfs/xfs_alloc.h +++ b/fs/xfs/xfs_alloc.h | |||
| @@ -75,6 +75,22 @@ typedef unsigned int xfs_alloctype_t; | |||
| 75 | #define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) | 75 | #define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) |
| 76 | 76 | ||
