Skip to contentSkip to conversation

Add fallocate support

PATCH In review Yan Zheng 2 participants 2 messages Oct 27, 2008 – Oct 29, 2008 Btrfs file system

lore
Share & tools
lore

Yan Zheng

author
#0 lore raw

PATCH 4/4 Add fallocate support

Hello,

This patch adds fallocate support.

---

fs/btrfs/ctree.h +5 -0
diff -urp 4/fs/btrfs/ctree.h 5/fs/btrfs/ctree.h
@@ -455,6 +455,7 @@ struct btrfs_root_item {
 
 #define BTRFS_FILE_EXTENT_REG 0
 #define BTRFS_FILE_EXTENT_INLINE 1
+#define BTRFS_FILE_EXTENT_PREALLOC 2
 
 struct btrfs_file_extent_item {
 	__le64 generation;
@@ -830,6 +831,7 @@ struct btrfs_root {
 #define BTRFS_INODE_NODATASUM		(1 << 0)
 #define BTRFS_INODE_NODATACOW		(1 << 1)
 #define BTRFS_INODE_READONLY		(1 << 2)
+#define BTRFS_INODE_PREALLOC		(1 << 3)
 #define btrfs_clear_flag(inode, flag)	(BTRFS_I(inode)->flags &= \
 					 ~BTRFS_INODE_##flag)
 #define btrfs_set_flag(inode, flag)	(BTRFS_I(inode)->flags |= \
@@ -1861,6 +1863,9 @@ extern struct file_operations btrfs_file
 int btrfs_drop_extents(struct btrfs_trans_handle *trans,
 		       struct btrfs_root *root, struct inode *inode,
 		       u64 start, u64 end, u64 inline_limit, u64 *hint_block);
+int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
+			      struct btrfs_root *root,
+			      struct inode *inode, u64 start, u64 end);
 int btrfs_release_file(struct inode *inode, struct file *file);
 
 /* tree-defrag.c */
fs/btrfs/extent_io.c +9 -3
diff -urp 4/fs/btrfs/extent_io.c 5/fs/btrfs/extent_io.c
@@ -1817,6 +1817,8 @@ printk("2bad mapping end %Lu cur %Lu\n",
 		sector = (em->block_start + extent_offset) >> 9;
 		bdev = em->bdev;
 		block_start = em->block_start;
+		if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags))
+			block_start = EXTENT_MAP_HOLE;
 		free_extent_map(em);
 		em = NULL;
 
@@ -2535,14 +2537,18 @@ sector_t extent_bmap(struct address_spac
 	struct inode *inode = mapping->host;
 	u64 start = iblock << inode->i_blkbits;
 	sector_t sector = 0;
+	size_t blksize = (1 << inode->i_blkbits);
 	struct extent_map *em;
 
-	em = get_extent(inode, NULL, 0, start, (1 << inode->i_blkbits), 0);
+	lock_extent(&BTRFS_I(inode)->io_tree, start, start + blksize - 1,
+		    GFP_NOFS);
+	em = get_extent(inode, NULL, 0, start, blksize, 0);
+	unlock_extent(&BTRFS_I(inode)->io_tree, start, start + blksize - 1,
+		      GFP_NOFS);
 	if (!em || IS_ERR(em))
 		return 0;
 
-	if (em->block_start == EXTENT_MAP_INLINE ||
-	    em->block_start == EXTENT_MAP_HOLE)
+	if (em->block_start > EXTENT_MAP_LAST_BYTE)
 		goto out;
 
 	sector = (em->block_start + start - em->start) >> inode->i_blkbits;
fs/btrfs/extent_map.h +1 -0
diff -urp 4/fs/btrfs/extent_map.h 5/fs/btrfs/extent_map.h
@@ -11,6 +11,7 @@
 /* bits for the flags field */
 #define EXTENT_FLAG_PINNED 0 /* this entry not yet on disk, don't free it */
 #define EXTENT_FLAG_VACANCY 1 /* no file extent item found */
+#define EXTENT_FLAG_PREALLOC 2 /* pre-allocated extent */
 
 struct extent_map {
 	struct rb_node rb_node;
fs/btrfs/extent-tree.c +6 -8
diff -urp 4/fs/btrfs/extent-tree.c 5/fs/btrfs/extent-tree.c
@@ -3415,9 +3415,7 @@ walk_down:
 next:
 		level--;
 		btrfs_release_path(extent_root, path);
-		if (need_resched()) {
-			cond_resched();
-		}
+		cond_resched();
 	}
 	/* reached lowest level */
 	ret = 1;
@@ -3528,9 +3526,7 @@ found:
 		}
 
 		btrfs_release_path(extent_root, path);
-		if (need_resched()) {
-			cond_resched();
-		}
+		cond_resched();
 	}
 	/* reached max tree level, but no tree root found. */
 	BUG();
@@ -3693,6 +3689,7 @@ static int noinline replace_one_extent(s
 	u32 nritems;
 	int nr_scaned = 0;
 	int extent_locked = 0;
+	int extent_type;
 	int ret;
 
 	memcpy(&key, leaf_key, sizeof(key));
@@ -3765,8 +3762,9 @@ next:
 		}
 		fi = btrfs_item_ptr(leaf, path->slots[0],
 				    struct btrfs_file_extent_item);
-		if ((btrfs_file_extent_type(leaf, fi) !=
-		     BTRFS_FILE_EXTENT_REG) ||
+		extent_type = btrfs_file_extent_type(leaf, fi);
+		if ((extent_type != BTRFS_FILE_EXTENT_REG &&
+		     extent_type != BTRFS_FILE_EXTENT_PREALLOC) ||
 		    (btrfs_file_extent_disk_bytenr(leaf, fi) !=
 		     extent_key->objectid)) {
 			path->slots[0]++;
fs/btrfs/file.c +232 -1

245 lines not on this page · raw message

fs/btrfs/inode.c +230 -58

403 lines not on this page · raw message

fs/btrfs/ioctl.c +2 -1
diff -urp 4/fs/btrfs/ioctl.c 5/fs/btrfs/ioctl.c
@@ -723,7 +723,8 @@ long btrfs_ioctl_clone(struct file *file
 			extent = btrfs_item_ptr(leaf, slot,
 						struct btrfs_file_extent_item);
 			found_type = btrfs_file_extent_type(leaf, extent);
-			if (found_type == BTRFS_FILE_EXTENT_REG) {
+			if (found_type == BTRFS_FILE_EXTENT_REG ||
+			    found_type == BTRFS_FILE_EXTENT_PREALLOC) {
 				u64 ds = btrfs_file_extent_disk_bytenr(leaf,
 								       extent);
 				u64 dl = btrfs_file_extent_disk_num_bytes(leaf,
fs/btrfs/ordered-data.c +3 -2
diff -urp 4/fs/btrfs/ordered-data.c 5/fs/btrfs/ordered-data.c
@@ -182,7 +182,7 @@ int btrfs_add_ordered_extent(struct inod
 	entry->len = len;
 	entry->inode = inode;
 
-	if (type == BTRFS_ORDERED_NOCOW)
+	if (type == BTRFS_ORDERED_NOCOW || type == BTRFS_ORDERED_PREALLOC)
 		set_bit(type, &entry->flags);
 
 	/* one ref for the tree */
@@ -339,7 +339,8 @@ int btrfs_wait_ordered_extents(struct bt
 		ordered = list_entry(cur, struct btrfs_ordered_extent,
 				     root_extent_list);
 		if (nocow_only &&
-		    !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) {
+		    !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags) &&
+		    !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags)) {
 			list_move(&ordered->root_extent_list,
 				  &root->fs_info->ordered_extents);
 			cond_resched_lock(&root->fs_info->ordered_extent_lock);
fs/btrfs/ordered-data.h +2 -0
diff -urp 4/fs/btrfs/ordered-data.h 5/fs/btrfs/ordered-data.h
@@ -66,6 +66,8 @@ struct btrfs_ordered_sum {
 
 #define BTRFS_ORDERED_NOCOW 2 /* set when we want to write in place */
 
+#define BTRFS_ORDERED_PREALLOC 3 /* set when writing to prealloced extent */
+
 struct btrfs_ordered_extent {
 	/* logical offset in the file */
 	u64 file_offset;
fs/btrfs/transaction.c +4 -0
diff -urp 4/fs/btrfs/transaction.c 5/fs/btrfs/transaction.c
@@ -488,6 +488,10 @@ int btrfs_add_dead_root(struct btrfs_roo
 	dirty->root = root;
 	dirty->latest_root = latest;
 
+	spin_lock(&root->list_lock);
+	list_add(&dirty->root->dead_list, &latest->dead_list);
+	spin_unlock(&root->list_lock);
+
 	mutex_lock(&root->fs_info->trans_mutex);
 	list_add(&dirty->list, &latest->fs_info->dead_roots);
 	mutex_unlock(&root->fs_info->trans_mutex);
fs/btrfs/tree-log.c +9 -4
diff -urp 4/fs/btrfs/tree-log.c 5/fs/btrfs/tree-log.c
@@ -442,7 +442,8 @@ insert:
 
 		fi = (struct btrfs_file_extent_item *)dst_ptr;
 		extent_type = btrfs_file_extent_type(path->nodes[0], fi);
-		if (extent_type == BTRFS_FILE_EXTENT_REG) {
+		if (extent_type == BTRFS_FILE_EXTENT_REG ||
+		    extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
 			struct btrfs_key ins;
 			ins.objectid = btrfs_file_extent_disk_bytenr(
 							path->nodes[0], fi);
@@ -538,7 +539,8 @@ static noinline int replay_one_extent(st
 	item = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
 	found_type = btrfs_file_extent_type(eb, item);
 
-	if (found_type == BTRFS_FILE_EXTENT_REG)
+	if (found_type == BTRFS_FILE_EXTENT_REG ||
+	    found_type == BTRFS_FILE_EXTENT_PREALLOC)
 		extent_end = start + btrfs_file_extent_num_bytes(eb, item);
 	else if (found_type == BTRFS_FILE_EXTENT_INLINE) {
 		size = btrfs_file_extent_inline_len(eb,
@@ -563,7 +565,9 @@ static noinline int replay_one_extent(st
 	ret = btrfs_lookup_file_extent(trans, root, path, inode->i_ino,
 				       start, 0);
 
-	if (ret == 0 && found_type == BTRFS_FILE_EXTENT_REG) {
+	if (ret == 0 &&
+	    (found_type == BTRFS_FILE_EXTENT_REG ||
+	     found_type == BTRFS_FILE_EXTENT_PREALLOC)) {
 		struct btrfs_file_extent_item cmp1;
 		struct btrfs_file_extent_item cmp2;
 		struct btrfs_file_extent_item *existing;
@@ -2523,7 +2527,8 @@ static noinline int copy_items(struct bt
 						struct btrfs_file_extent_item);
 
 			found_type = btrfs_file_extent_type(src, extent);
-			if (found_type == BTRFS_FILE_EXTENT_REG) {
+			if (found_type == BTRFS_FILE_EXTENT_REG ||
+			    found_type == BTRFS_FILE_EXTENT_PREALLOC) {
 				u64 ds = btrfs_file_extent_disk_bytenr(src,
 								   extent);
 				u64 dl = btrfs_file_extent_disk_num_bytes(src,
#1 lore raw
Quoted 4 lines · Yan Zheng

Hello,

This patch adds fallocate support.

I'm sorry, but could you please rebase this against the compression code?

-chris