1*cac06d84SQu Wenruo // SPDX-License-Identifier: GPL-2.0 2*cac06d84SQu Wenruo 3*cac06d84SQu Wenruo #include <linux/slab.h> 4*cac06d84SQu Wenruo #include "ctree.h" 5*cac06d84SQu Wenruo #include "subpage.h" 6*cac06d84SQu Wenruo 7*cac06d84SQu Wenruo int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info, 8*cac06d84SQu Wenruo struct page *page, enum btrfs_subpage_type type) 9*cac06d84SQu Wenruo { 10*cac06d84SQu Wenruo struct btrfs_subpage *subpage; 11*cac06d84SQu Wenruo 12*cac06d84SQu Wenruo /* 13*cac06d84SQu Wenruo * We have cases like a dummy extent buffer page, which is not mappped 14*cac06d84SQu Wenruo * and doesn't need to be locked. 15*cac06d84SQu Wenruo */ 16*cac06d84SQu Wenruo if (page->mapping) 17*cac06d84SQu Wenruo ASSERT(PageLocked(page)); 18*cac06d84SQu Wenruo /* Either not subpage, or the page already has private attached */ 19*cac06d84SQu Wenruo if (fs_info->sectorsize == PAGE_SIZE || PagePrivate(page)) 20*cac06d84SQu Wenruo return 0; 21*cac06d84SQu Wenruo 22*cac06d84SQu Wenruo subpage = kzalloc(sizeof(struct btrfs_subpage), GFP_NOFS); 23*cac06d84SQu Wenruo if (!subpage) 24*cac06d84SQu Wenruo return -ENOMEM; 25*cac06d84SQu Wenruo 26*cac06d84SQu Wenruo spin_lock_init(&subpage->lock); 27*cac06d84SQu Wenruo attach_page_private(page, subpage); 28*cac06d84SQu Wenruo return 0; 29*cac06d84SQu Wenruo } 30*cac06d84SQu Wenruo 31*cac06d84SQu Wenruo void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info, 32*cac06d84SQu Wenruo struct page *page) 33*cac06d84SQu Wenruo { 34*cac06d84SQu Wenruo struct btrfs_subpage *subpage; 35*cac06d84SQu Wenruo 36*cac06d84SQu Wenruo /* Either not subpage, or already detached */ 37*cac06d84SQu Wenruo if (fs_info->sectorsize == PAGE_SIZE || !PagePrivate(page)) 38*cac06d84SQu Wenruo return; 39*cac06d84SQu Wenruo 40*cac06d84SQu Wenruo subpage = (struct btrfs_subpage *)detach_page_private(page); 41*cac06d84SQu Wenruo ASSERT(subpage); 42*cac06d84SQu Wenruo kfree(subpage); 43*cac06d84SQu Wenruo } 44