On Thursday 31 July 2014 at 14:19:43, Ivan Shapovalov wrote: > [...] > > Ivan Shapovalov (6): > reiser4: fix reiser4_post_{commit,write_back}_hook() and their invocations. > reiser4: make space_allocator's check_blocks() reusable. > reiser4: add an implementation of "block lists", splitted off the discard code. > reiser4: blocknr_list: use kmem_cache instead of kmalloc for allocating entries. > reiser4: blocknr_set: use kmem_cache instead of kmalloc for allocating entries. > reiser4: discard support: initial implementation using blocknr_list, without extent padding. > > [...] This is a diff between previous two patchsets and this one, for ease of reviewing. diff --git a/fs/reiser4/block_alloc.c b/fs/reiser4/block_alloc.c index 98080a1..324b11c 100644 --- a/fs/reiser4/block_alloc.c +++ b/fs/reiser4/block_alloc.c @@ -9,6 +9,7 @@ reiser4/README */ #include "block_alloc.h" #include "tree.h" #include "super.h" +#include "discard.h" #include <linux/types.h> /* for __u?? */ #include <linux/fs.h> /* for struct super_block */ @@ -1144,7 +1145,7 @@ void reiser4_post_write_back_hook(void) } while (ret == -E_REPEAT); if (ret) { - warning("intelfx-8", "discard atom failed (%ld)", ret); + warning("intelfx-8", "discard atom failed (%d)", ret); } atom = get_current_atom_locked(); diff --git a/fs/reiser4/discard.c b/fs/reiser4/discard.c index 8442619..7a07afc 100644 --- a/fs/reiser4/discard.c +++ b/fs/reiser4/discard.c @@ -53,23 +53,21 @@ * the atom's delete set becomes "the discard set" -- list of blocks that have * to be considered for discarding. * - * On atom commit we will generate a minimal superset of the discard set, - * comprised of whole erase units. - * * Discarding is performed before completing deferred deallocations, hence all * extents in the discard set are still marked as allocated and cannot contain * any data. Thus we can avoid any checks for blocks directly present in the * discard set. * - * However, we pad each extent from both sides to erase unit boundaries, and - * these paddings still have to be checked if they fall outside of initial - * extent (may not happen if block size > erase unit size). + * For now, we don't perform "padding" of extents to erase unit boundaries. + * This means if extents are not aligned with the device's erase unit lattice, + * the partial erase units at head and tail of extents are truncated by kernel + * (in blkdev_issue_discard()). * * So, at commit time the following actions take place: * - delete sets are merged to form the discard set; * - elements of the discard set are sorted; * - the discard set is iterated, joining any adjacent extents; - * - <TODO> + * - for each extent, a single call to blkdev_issue_discard() is done. */ #include "discard.h" @@ -98,92 +96,20 @@ static int discard_extent(txn_atom *atom UNUSED_ARG, { struct super_block *sb = reiser4_get_current_sb(); struct block_device *bdev = sb->s_bdev; - struct queue_limits *limits = &bdev_get_queue(bdev)->limits; - sector_t extent_start_sec, extent_end_sec, - unit_sec, request_start_sec = 0, request_len_sec = 0; - reiser4_block_nr unit_start_blk, unit_len_blk; - int ret, erase_unit_counter = 0; + sector_t extent_start_sec, extent_len_sec; const int sec_per_blk = sb->s_blocksize >> 9; - /* from blkdev_issue_discard(): - * Zero-sector (unknown) and one-sector granularities are the same. */ - const int granularity = max(limits->discard_granularity >> 9, 1U); - const int alignment = (bdev_discard_alignment(bdev) >> 9) % granularity; - /* we assume block = N * sector */ assert("intelfx-7", sec_per_blk > 0); /* convert extent to sectors */ extent_start_sec = *start * sec_per_blk; - extent_end_sec = (*start + *len) * sec_per_blk; + extent_len_sec = *len * sec_per_blk; - /* round down extent start sector to an erase unit boundary */ - unit_sec = extent_start_sec; - if (granularity > 1) { - sector_t tmp = extent_start_sec - alignment; - unit_sec -= sector_div(tmp, granularity); - } - - /* iterate over erase units in the extent */ - do { - /* considering erase unit: - * [unit_sec; unit_sec + granularity) */ - - /* calculate block range for erase unit: - * [unit_start_blk; unit_start_blk+unit_len_blk) */ - unit_start_blk = unit_sec; - do_div(unit_start_blk, sec_per_blk); - - if (granularity > 1) { - unit_len_blk = unit_sec + granularity - 1; - do_div(unit_len_blk, sec_per_blk); - ++unit_len_blk; - - assert("intelfx-22", unit_len_blk > unit_start_blk); - - unit_len_blk -= unit_start_blk; - } else { - unit_len_blk = 1; - } - - if (reiser4_check_blocks(&unit_start_blk, &unit_len_blk, 0)) { - /* OK. Add this unit to the accumulator. - * We accumulate discard units to call blkdev_issue_discard() - * not too frequently. */ - - if (request_len_sec > 0) { - request_len_sec += granularity; - } else { - request_start_sec = unit_sec; - request_len_sec = granularity; - } - } else { - /* This unit can't be discarded. Discard what's been accumulated - * so far. */ - if (request_len_sec > 0) { - ret = __discard_extent(bdev, request_start_sec, request_len_sec); - if (ret != 0) { - return ret; - } - request_len_sec = 0; - } - } - - unit_sec += granularity; - ++erase_unit_counter; - } while (unit_sec < extent_end_sec); - - /* Discard the last accumulated request. */ - if (request_len_sec > 0) { - ret = __discard_extent(bdev, request_start_sec, request_len_sec); - if (ret != 0) { - return ret; - } - } - - return 0; + /* discard the extent, don't pad it to erase unit boundaries for now */ + return __discard_extent(bdev, extent_start_sec, extent_len_sec); } int discard_atom(txn_atom *atom, struct list_head *processed_set) @@ -201,6 +127,7 @@ int discard_atom(txn_atom *atom, struct list_head *processed_set) if (list_empty(&atom->discard.delete_set)) { /* Nothing left to discard. */ + spin_unlock_atom(atom); return 0; } diff --git a/fs/reiser4/plugin/space/bitmap.c b/fs/reiser4/plugin/space/bitmap.c index 03bc5e7..3da3f6b 100644 --- a/fs/reiser4/plugin/space/bitmap.c +++ b/fs/reiser4/plugin/space/bitmap.c @@ -1259,8 +1259,7 @@ int reiser4_check_blocks_bitmap(const reiser4_block_nr * start, reiser4_block_nr end; bmap_nr_t bmap, end_bmap; - bmap_off_t offset; - bmap_off_t end_offset; + bmap_off_t offset, end_offset; const bmap_off_t max_offset = bmap_bit_count(super->s_blocksize); assert("intelfx-9", start != NULL); @@ -1270,9 +1269,8 @@ int reiser4_check_blocks_bitmap(const reiser4_block_nr * start, check_block_range(start, len); end = *start + *len - 1; } else { - /* end is used as temporary len here */ - end = 1; - check_block_range(start, &end); + /* on next line, end is used as temporary len for check_block_range() */ + end = 1; check_block_range(start, &end); end = *start; } diff --git a/fs/reiser4/txnmgr.h b/fs/reiser4/txnmgr.h index 05990d8..72b84a2 100644 --- a/fs/reiser4/txnmgr.h +++ b/fs/reiser4/txnmgr.h @@ -256,8 +256,10 @@ struct txn_atom { } nodiscard; struct { - /* The atom's delete set. It collects block numbers which were - deallocated with BA_DEFER, i. e. of ordinary nodes. */ + /* The atom's delete set. It collects all blocks that have been + deallocated (both immediate and deferred) during the transaction. + These blocks are considered for discarding at commit time. + For details see discard.c */ struct list_head delete_set; } discard; }; Thanks, -- Ivan Shapovalov / intelfx /
Attachment:
signature.asc
Description: This is a digitally signed message part.