aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/libxfs/xfs_alloc.c69
-rw-r--r--fs/xfs/libxfs/xfs_alloc.h8
-rw-r--r--fs/xfs/libxfs/xfs_bmap.c3
-rw-r--r--fs/xfs/xfs_filestream.c3
4 files changed, 37 insertions, 46 deletions
diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 516162be1398..9b3e3681dfa9 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -1825,11 +1825,11 @@ xfs_alloc_compute_maxlevels(
1825xfs_extlen_t 1825xfs_extlen_t
1826xfs_alloc_longest_free_extent( 1826xfs_alloc_longest_free_extent(
1827 struct xfs_mount *mp, 1827 struct xfs_mount *mp,
1828 struct xfs_perag *pag) 1828 struct xfs_perag *pag,
1829 xfs_extlen_t need)
1829{ 1830{
1830 xfs_extlen_t need, delta = 0; 1831 xfs_extlen_t delta = 0;
1831 1832
1832 need = XFS_MIN_FREELIST_PAG(pag, mp);
1833 if (need > pag->pagf_flcount) 1833 if (need > pag->pagf_flcount)
1834 delta = need - pag->pagf_flcount; 1834 delta = need - pag->pagf_flcount;
1835 1835
@@ -1848,10 +1848,8 @@ xfs_alloc_fix_freelist(
1848 int flags) /* XFS_ALLOC_FLAG_... */ 1848 int flags) /* XFS_ALLOC_FLAG_... */
1849{ 1849{
1850 xfs_buf_t *agbp; /* agf buffer pointer */ 1850 xfs_buf_t *agbp; /* agf buffer pointer */
1851 xfs_agf_t *agf; /* a.g. freespace structure pointer */
1852 xfs_buf_t *agflbp;/* agfl buffer pointer */ 1851 xfs_buf_t *agflbp;/* agfl buffer pointer */
1853 xfs_agblock_t bno; /* freelist block */ 1852 xfs_agblock_t bno; /* freelist block */
1854 xfs_extlen_t delta; /* new blocks needed in freelist */
1855 int error; /* error result code */ 1853 int error; /* error result code */
1856 xfs_extlen_t longest;/* longest extent in allocation group */ 1854 xfs_extlen_t longest;/* longest extent in allocation group */
1857 xfs_mount_t *mp; /* file system mount point structure */ 1855 xfs_mount_t *mp; /* file system mount point structure */
@@ -1895,7 +1893,7 @@ xfs_alloc_fix_freelist(
1895 * total blocks, reject it. 1893 * total blocks, reject it.
1896 */ 1894 */
1897 need = XFS_MIN_FREELIST_PAG(pag, mp); 1895 need = XFS_MIN_FREELIST_PAG(pag, mp);
1898 longest = xfs_alloc_longest_free_extent(mp, pag); 1896 longest = xfs_alloc_longest_free_extent(mp, pag, need);
1899 if ((args->minlen + args->alignment + args->minalignslop - 1) > 1897 if ((args->minlen + args->alignment + args->minalignslop - 1) >
1900 longest || 1898 longest ||
1901 ((int)(pag->pagf_freeblks + pag->pagf_flcount - 1899 ((int)(pag->pagf_freeblks + pag->pagf_flcount -
@@ -1922,25 +1920,16 @@ xfs_alloc_fix_freelist(
1922 return 0; 1920 return 0;
1923 } 1921 }
1924 } 1922 }
1925 /* 1923
1926 * Figure out how many blocks we should have in the freelist. 1924
1927 */ 1925 /* If there isn't enough total space or single-extent, reject it. */
1928 agf = XFS_BUF_TO_AGF(agbp); 1926 need = XFS_MIN_FREELIST_PAG(pag, mp);
1929 need = XFS_MIN_FREELIST(agf, mp);
1930 /*
1931 * If there isn't enough total or single-extent, reject it.
1932 */
1933 if (!(flags & XFS_ALLOC_FLAG_FREEING)) { 1927 if (!(flags & XFS_ALLOC_FLAG_FREEING)) {
1934 delta = need > be32_to_cpu(agf->agf_flcount) ? 1928 longest = xfs_alloc_longest_free_extent(mp, pag, need);
1935 (need - be32_to_cpu(agf->agf_flcount)) : 0;
1936 longest = be32_to_cpu(agf->agf_longest);
1937 longest = (longest > delta) ? (longest - delta) :
1938 (be32_to_cpu(agf->agf_flcount) > 0 || longest > 0);
1939 if ((args->minlen + args->alignment + args->minalignslop - 1) > 1929 if ((args->minlen + args->alignment + args->minalignslop - 1) >
1940 longest || 1930 longest ||
1941 ((int)(be32_to_cpu(agf->agf_freeblks) + 1931 ((int)(pag->pagf_freeblks + pag->pagf_flcount -
1942 be32_to_cpu(agf->agf_flcount) - need - args->total) < 1932 need - args->total) < (int)args->minleft)) {
1943 (int)args->minleft)) {
1944 xfs_trans_brelse(tp, agbp); 1933 xfs_trans_brelse(tp, agbp);
1945 args->agbp = NULL; 1934 args->agbp = NULL;
1946 return 0; 1935 return 0;
@@ -1948,21 +1937,25 @@ xfs_alloc_fix_freelist(
1948 } 1937 }
1949 /* 1938 /*
1950 * Make the freelist shorter if it's too long. 1939 * Make the freelist shorter if it's too long.
1940 *
1941 * XXX (dgc): When we have lots of free space, does this buy us
1942 * anything other than extra overhead when we need to put more blocks
1943 * back on the free list? Maybe we should only do this when space is
1944 * getting low or the AGFL is more than half full?
1951 */ 1945 */
1952 while (be32_to_cpu(agf->agf_flcount) > need) { 1946 while (pag->pagf_flcount > need) {
1953 xfs_buf_t *bp; 1947 struct xfs_buf *bp;
1954 1948
1955 error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); 1949 error = xfs_alloc_get_freelist(tp, agbp, &bno, 0);
1956 if (error) 1950 if (error)
1957 return error; 1951 return error;
1958 if ((error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1))) 1952 error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1);
1953 if (error)
1959 return error; 1954 return error;
1960 bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); 1955 bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0);
1961 xfs_trans_binval(tp, bp); 1956 xfs_trans_binval(tp, bp);
1962 } 1957 }
1963 /* 1958
1964 * Initialize the args structure.
1965 */
1966 memset(&targs, 0, sizeof(targs)); 1959 memset(&targs, 0, sizeof(targs));
1967 targs.tp = tp; 1960 targs.tp = tp;
1968 targs.mp = mp; 1961 targs.mp = mp;
@@ -1971,18 +1964,18 @@ xfs_alloc_fix_freelist(
1971 targs.alignment = targs.minlen = targs.prod = targs.isfl = 1; 1964 targs.alignment = targs.minlen = targs.prod = targs.isfl = 1;
1972 targs.type = XFS_ALLOCTYPE_THIS_AG; 1965 targs.type = XFS_ALLOCTYPE_THIS_AG;
1973 targs.pag = pag; 1966 targs.pag = pag;
1974 if ((error = xfs_alloc_read_agfl(mp, tp, targs.agno, &agflbp))) 1967 error = xfs_alloc_read_agfl(mp, tp, targs.agno, &agflbp);
1968 if (error)
1975 return error; 1969 return error;
1976 /* 1970
1977 * Make the freelist longer if it's too short. 1971 /* Make the freelist longer if it's too short. */
1978 */ 1972 while (pag->pagf_flcount < need) {
1979 while (be32_to_cpu(agf->agf_flcount) < need) {
1980 targs.agbno = 0; 1973 targs.agbno = 0;
1981 targs.maxlen = need - be32_to_cpu(agf->agf_flcount); 1974 targs.maxlen = need - pag->pagf_flcount;
1982 /* 1975
1983 * Allocate as many blocks as possible at once. 1976 /* Allocate as many blocks as possible at once. */
1984 */ 1977 error = xfs_alloc_ag_vextent(&targs);
1985 if ((error = xfs_alloc_ag_vextent(&targs))) { 1978 if (error) {
1986 xfs_trans_brelse(tp, agflbp); 1979 xfs_trans_brelse(tp, agflbp);
1987 return error; 1980 return error;
1988 } 1981 }
diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
index d1b4b6a5c894..8815fc30f83d 100644
--- a/fs/xfs/libxfs/xfs_alloc.h
+++ b/fs/xfs/libxfs/xfs_alloc.h
@@ -128,12 +128,8 @@ typedef struct xfs_alloc_arg {
128#define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ 128#define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/
129#define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ 129#define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */
130 130
131/* 131xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp,
132 * Find the length of the longest extent in an AG. 132 struct xfs_perag *pag, xfs_extlen_t need);
133 */
134xfs_extlen_t
135xfs_alloc_longest_free_extent(struct xfs_mount *mp,
136 struct xfs_perag *pag);
137 133
138/* 134/*
139 * Compute and fill in value of m_ag_maxlevels. 135 * Compute and fill in value of m_ag_maxlevels.
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index aeffeaaac0ec..1ad4f1a62ce0 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -3507,7 +3507,8 @@ xfs_bmap_longest_free_extent(
3507 } 3507 }
3508 } 3508 }
3509 3509
3510 longest = xfs_alloc_longest_free_extent(mp, pag); 3510 longest = xfs_alloc_longest_free_extent(mp, pag,
3511 XFS_MIN_FREELIST_PAG(pag, mp));
3511 if (*blen < longest) 3512 if (*blen < longest)
3512 *blen = longest; 3513 *blen = longest;
3513 3514
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c
index da82f1cb4b9b..9ac5eaad47bc 100644
--- a/fs/xfs/xfs_filestream.c
+++ b/fs/xfs/xfs_filestream.c
@@ -196,7 +196,8 @@ xfs_filestream_pick_ag(
196 goto next_ag; 196 goto next_ag;
197 } 197 }
198 198
199 longest = xfs_alloc_longest_free_extent(mp, pag); 199 longest = xfs_alloc_longest_free_extent(mp, pag,
200 XFS_MIN_FREELIST_PAG(pag, mp));
200 if (((minlen && longest >= minlen) || 201 if (((minlen && longest >= minlen) ||
201 (!minlen && pag->pagf_freeblks >= minfree)) && 202 (!minlen && pag->pagf_freeblks >= minfree)) &&
202 (!pag->pagf_metadata || !(flags & XFS_PICK_USERDATA) || 203 (!pag->pagf_metadata || !(flags & XFS_PICK_USERDATA) ||