diff options
Diffstat (limited to 'fs/ext4/balloc.c')
-rw-r--r-- | fs/ext4/balloc.c | 127 |
1 files changed, 74 insertions, 53 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 816f1dbaeb3c..48787e86d438 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -1640,20 +1640,24 @@ int ext4_should_retry_alloc(struct super_block *sb, int *retries) | |||
1640 | } | 1640 | } |
1641 | 1641 | ||
1642 | /** | 1642 | /** |
1643 | * ext4_new_blocks_old() -- core block(s) allocation function | 1643 | * ext4_old_new_blocks() -- core block bitmap based block allocation function |
1644 | * | ||
1644 | * @handle: handle to this transaction | 1645 | * @handle: handle to this transaction |
1645 | * @inode: file inode | 1646 | * @inode: file inode |
1646 | * @goal: given target block(filesystem wide) | 1647 | * @goal: given target block(filesystem wide) |
1647 | * @count: target number of blocks to allocate | 1648 | * @count: target number of blocks to allocate |
1648 | * @errp: error code | 1649 | * @errp: error code |
1649 | * | 1650 | * |
1650 | * ext4_new_blocks uses a goal block to assist allocation. It tries to | 1651 | * ext4_old_new_blocks uses a goal block to assist allocation and look up |
1651 | * allocate block(s) from the block group contains the goal block first. If that | 1652 | * the block bitmap directly to do block allocation. It tries to |
1652 | * fails, it will try to allocate block(s) from other block groups without | 1653 | * allocate block(s) from the block group contains the goal block first. If |
1653 | * any specific goal block. | 1654 | * that fails, it will try to allocate block(s) from other block groups |
1655 | * without any specific goal block. | ||
1656 | * | ||
1657 | * This function is called when -o nomballoc mount option is enabled | ||
1654 | * | 1658 | * |
1655 | */ | 1659 | */ |
1656 | ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode, | 1660 | ext4_fsblk_t ext4_old_new_blocks(handle_t *handle, struct inode *inode, |
1657 | ext4_fsblk_t goal, unsigned long *count, int *errp) | 1661 | ext4_fsblk_t goal, unsigned long *count, int *errp) |
1658 | { | 1662 | { |
1659 | struct buffer_head *bitmap_bh = NULL; | 1663 | struct buffer_head *bitmap_bh = NULL; |
@@ -1923,78 +1927,95 @@ out: | |||
1923 | return 0; | 1927 | return 0; |
1924 | } | 1928 | } |
1925 | 1929 | ||
1926 | ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode, | 1930 | #define EXT4_META_BLOCK 0x1 |
1927 | ext4_fsblk_t goal, int *errp) | ||
1928 | { | ||
1929 | struct ext4_allocation_request ar; | ||
1930 | ext4_fsblk_t ret; | ||
1931 | |||
1932 | if (!test_opt(inode->i_sb, MBALLOC)) { | ||
1933 | unsigned long count = 1; | ||
1934 | ret = ext4_new_blocks_old(handle, inode, goal, &count, errp); | ||
1935 | return ret; | ||
1936 | } | ||
1937 | 1931 | ||
1938 | memset(&ar, 0, sizeof(ar)); | 1932 | static ext4_fsblk_t do_blk_alloc(handle_t *handle, struct inode *inode, |
1939 | ar.inode = inode; | ||
1940 | ar.goal = goal; | ||
1941 | ar.len = 1; | ||
1942 | ret = ext4_mb_new_blocks(handle, &ar, errp); | ||
1943 | return ret; | ||
1944 | } | ||
1945 | ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, | ||
1946 | ext4_fsblk_t goal, unsigned long *count, int *errp) | ||
1947 | { | ||
1948 | struct ext4_allocation_request ar; | ||
1949 | ext4_fsblk_t ret; | ||
1950 | |||
1951 | if (!test_opt(inode->i_sb, MBALLOC)) { | ||
1952 | ret = ext4_new_blocks_old(handle, inode, goal, count, errp); | ||
1953 | return ret; | ||
1954 | } | ||
1955 | |||
1956 | memset(&ar, 0, sizeof(ar)); | ||
1957 | ar.inode = inode; | ||
1958 | ar.goal = goal; | ||
1959 | ar.len = *count; | ||
1960 | ret = ext4_mb_new_blocks(handle, &ar, errp); | ||
1961 | *count = ar.len; | ||
1962 | return ret; | ||
1963 | } | ||
1964 | |||
1965 | ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, | ||
1966 | ext4_lblk_t iblock, ext4_fsblk_t goal, | 1933 | ext4_lblk_t iblock, ext4_fsblk_t goal, |
1967 | unsigned long *count, int *errp) | 1934 | unsigned long *count, int *errp, int flags) |
1968 | { | 1935 | { |
1969 | struct ext4_allocation_request ar; | 1936 | struct ext4_allocation_request ar; |
1970 | ext4_fsblk_t ret; | 1937 | ext4_fsblk_t ret; |
1971 | 1938 | ||
1972 | if (!test_opt(inode->i_sb, MBALLOC)) { | 1939 | if (!test_opt(inode->i_sb, MBALLOC)) { |
1973 | ret = ext4_new_blocks_old(handle, inode, goal, count, errp); | 1940 | return ext4_old_new_blocks(handle, inode, goal, count, errp); |
1974 | return ret; | ||
1975 | } | 1941 | } |
1976 | 1942 | ||
1977 | memset(&ar, 0, sizeof(ar)); | 1943 | memset(&ar, 0, sizeof(ar)); |
1978 | /* Fill with neighbour allocated blocks */ | 1944 | /* Fill with neighbour allocated blocks */ |
1979 | ar.lleft = 0; | ||
1980 | ar.pleft = 0; | ||
1981 | ar.lright = 0; | ||
1982 | ar.pright = 0; | ||
1983 | 1945 | ||
1984 | ar.inode = inode; | 1946 | ar.inode = inode; |
1985 | ar.goal = goal; | 1947 | ar.goal = goal; |
1986 | ar.len = *count; | 1948 | ar.len = *count; |
1987 | ar.logical = iblock; | 1949 | ar.logical = iblock; |
1988 | if (S_ISREG(inode->i_mode)) | 1950 | |
1951 | if (S_ISREG(inode->i_mode) && !(flags & EXT4_META_BLOCK)) | ||
1952 | /* enable in-core preallocation for data block allocation */ | ||
1989 | ar.flags = EXT4_MB_HINT_DATA; | 1953 | ar.flags = EXT4_MB_HINT_DATA; |
1990 | else | 1954 | else |
1991 | /* disable in-core preallocation for non-regular files */ | 1955 | /* disable in-core preallocation for non-regular files */ |
1992 | ar.flags = 0; | 1956 | ar.flags = 0; |
1957 | |||
1993 | ret = ext4_mb_new_blocks(handle, &ar, errp); | 1958 | ret = ext4_mb_new_blocks(handle, &ar, errp); |
1994 | *count = ar.len; | 1959 | *count = ar.len; |
1995 | return ret; | 1960 | return ret; |
1996 | } | 1961 | } |
1997 | 1962 | ||
1963 | /* | ||
1964 | * ext4_new_meta_block() -- allocate block for meta data (indexing) blocks | ||
1965 | * | ||
1966 | * @handle: handle to this transaction | ||
1967 | * @inode: file inode | ||
1968 | * @goal: given target block(filesystem wide) | ||
1969 | * @errp: error code | ||
1970 | * | ||
1971 | * Return allocated block number on success | ||
1972 | */ | ||
1973 | ext4_fsblk_t ext4_new_meta_block(handle_t *handle, struct inode *inode, | ||
1974 | ext4_fsblk_t goal, int *errp) | ||
1975 | { | ||
1976 | unsigned long count = 1; | ||
1977 | return do_blk_alloc(handle, inode, 0, goal, | ||
1978 | &count, errp, EXT4_META_BLOCK); | ||
1979 | } | ||
1980 | |||
1981 | /* | ||
1982 | * ext4_new_meta_blocks() -- allocate block for meta data (indexing) blocks | ||
1983 | * | ||
1984 | * @handle: handle to this transaction | ||
1985 | * @inode: file inode | ||
1986 | * @goal: given target block(filesystem wide) | ||
1987 | * @count: total number of blocks need | ||
1988 | * @errp: error code | ||
1989 | * | ||
1990 | * Return 1st allocated block numberon success, *count stores total account | ||
1991 | * error stores in errp pointer | ||
1992 | */ | ||
1993 | ext4_fsblk_t ext4_new_meta_blocks(handle_t *handle, struct inode *inode, | ||
1994 | ext4_fsblk_t goal, unsigned long *count, int *errp) | ||
1995 | { | ||
1996 | return do_blk_alloc(handle, inode, 0, goal, | ||
1997 | count, errp, EXT4_META_BLOCK); | ||
1998 | } | ||
1999 | |||
2000 | /* | ||
2001 | * ext4_new_blocks() -- allocate data blocks | ||
2002 | * | ||
2003 | * @handle: handle to this transaction | ||
2004 | * @inode: file inode | ||
2005 | * @goal: given target block(filesystem wide) | ||
2006 | * @count: total number of blocks need | ||
2007 | * @errp: error code | ||
2008 | * | ||
2009 | * Return 1st allocated block numberon success, *count stores total account | ||
2010 | * error stores in errp pointer | ||
2011 | */ | ||
2012 | |||
2013 | ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, | ||
2014 | ext4_lblk_t iblock, ext4_fsblk_t goal, | ||
2015 | unsigned long *count, int *errp) | ||
2016 | { | ||
2017 | return do_blk_alloc(handle, inode, iblock, goal, count, errp, 0); | ||
2018 | } | ||
1998 | 2019 | ||
1999 | /** | 2020 | /** |
2000 | * ext4_count_free_blocks() -- count filesystem free blocks | 2021 | * ext4_count_free_blocks() -- count filesystem free blocks |