Re: [PATCHv7 0/6] reiser4: discard support: simplified and race-free initial implementation.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.


[Index of Archives]     [Linux File System Development]     [Linux BTRFS]     [Linux NFS]     [Linux Filesystems]     [Ext4 Filesystem]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Resources]

  Powered by Linux