btrfs: introduce the skeleton of btrfs_subpage structure
authorQu Wenruo <wqu@suse.com>
Tue, 26 Jan 2021 08:33:47 +0000 (16:33 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 8 Feb 2021 21:59:01 +0000 (22:59 +0100)
For sectorsize < page size support, we need a structure to record extra
status info for each sector of a page.

Introduce the skeleton structure, all subpage related code would go to
subpage.[ch].

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/Makefile
fs/btrfs/subpage.c [new file with mode: 0644]
fs/btrfs/subpage.h [new file with mode: 0644]
fs/btrfs/super.c

index e4595731942493da449dc91a332ef99228001bd3..b634c42115ead9a256f7c261ef76b0fa4e1e7c59 100644 (file)
@@ -27,7 +27,8 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \
           compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \
           reada.o backref.o ulist.o qgroup.o send.o dev-replace.o raid56.o \
           uuid-tree.o props.o free-space-tree.o tree-checker.o space-info.o \
-          block-rsv.o delalloc-space.o block-group.o discard.o reflink.o
+          block-rsv.o delalloc-space.o block-group.o discard.o reflink.o \
+          subpage.o
 
 btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o
 btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o
diff --git a/fs/btrfs/subpage.c b/fs/btrfs/subpage.c
new file mode 100644 (file)
index 0000000..a3e5b6a
--- /dev/null
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/slab.h>
+#include "ctree.h"
+#include "subpage.h"
+
+int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info,
+                        struct page *page, enum btrfs_subpage_type type)
+{
+       struct btrfs_subpage *subpage;
+
+       /*
+        * We have cases like a dummy extent buffer page, which is not mappped
+        * and doesn't need to be locked.
+        */
+       if (page->mapping)
+               ASSERT(PageLocked(page));
+       /* Either not subpage, or the page already has private attached */
+       if (fs_info->sectorsize == PAGE_SIZE || PagePrivate(page))
+               return 0;
+
+       subpage = kzalloc(sizeof(struct btrfs_subpage), GFP_NOFS);
+       if (!subpage)
+               return -ENOMEM;
+
+       spin_lock_init(&subpage->lock);
+       attach_page_private(page, subpage);
+       return 0;
+}
+
+void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info,
+                         struct page *page)
+{
+       struct btrfs_subpage *subpage;
+
+       /* Either not subpage, or already detached */
+       if (fs_info->sectorsize == PAGE_SIZE || !PagePrivate(page))
+               return;
+
+       subpage = (struct btrfs_subpage *)detach_page_private(page);
+       ASSERT(subpage);
+       kfree(subpage);
+}
diff --git a/fs/btrfs/subpage.h b/fs/btrfs/subpage.h
new file mode 100644 (file)
index 0000000..676280b
--- /dev/null
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef BTRFS_SUBPAGE_H
+#define BTRFS_SUBPAGE_H
+
+#include <linux/spinlock.h>
+
+/*
+ * Maximum page size we support is 64K, minimum sector size is 4K, u16 bitmap
+ * is sufficient. Regular bitmap_* is not used due to size reasons.
+ */
+#define BTRFS_SUBPAGE_BITMAP_SIZE      16
+
+/*
+ * Structure to trace status of each sector inside a page, attached to
+ * page::private for both data and metadata inodes.
+ */
+struct btrfs_subpage {
+       /* Common members for both data and metadata pages */
+       spinlock_t lock;
+};
+
+enum btrfs_subpage_type {
+       BTRFS_SUBPAGE_METADATA,
+       BTRFS_SUBPAGE_DATA,
+};
+
+int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info,
+                        struct page *page, enum btrfs_subpage_type type);
+void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info,
+                         struct page *page);
+
+#endif
index 12d7d3be7cd456993405ab86fd16d92aa2a5a306..919ed5c357e927bc03fc09d01c2d0bdce2b3a8c5 100644 (file)
@@ -48,7 +48,6 @@
 #include "tests/btrfs-tests.h"
 #include "block-group.h"
 #include "discard.h"
-
 #include "qgroup.h"
 #define CREATE_TRACE_POINTS
 #include <trace/events/btrfs.h>