diff mbox series

[v4,03/18] btrfs: introduce the skeleton of btrfs_subpage structure

Message ID 20210116071533.105780-4-wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: add read-only support for subpage sector size | expand

Commit Message

Qu Wenruo Jan. 16, 2021, 7:15 a.m. UTC
For btrfs subpage support, we need a structure to record extra info for
the status of each sectors of a page.

This patch will introduce the skeleton structure for future btrfs
subpage support.
All subpage related code would go to subpage.[ch] to avoid populating
the existing code base.

Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 fs/btrfs/Makefile  |  3 ++-
 fs/btrfs/subpage.c | 39 +++++++++++++++++++++++++++++++++++++++
 fs/btrfs/subpage.h | 31 +++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 fs/btrfs/subpage.c
 create mode 100644 fs/btrfs/subpage.h

Comments

David Sterba Jan. 18, 2021, 10:46 p.m. UTC | #1
On Sat, Jan 16, 2021 at 03:15:18PM +0800, Qu Wenruo wrote:
> For btrfs subpage support, we need a structure to record extra info for
> the status of each sectors of a page.
> 
> This patch will introduce the skeleton structure for future btrfs
> subpage support.
> All subpage related code would go to subpage.[ch] to avoid populating
> the existing code base.
> 
> Reviewed-by: Josef Bacik <josef@toxicpanda.com>
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
>  fs/btrfs/Makefile  |  3 ++-
>  fs/btrfs/subpage.c | 39 +++++++++++++++++++++++++++++++++++++++
>  fs/btrfs/subpage.h | 31 +++++++++++++++++++++++++++++++
>  3 files changed, 72 insertions(+), 1 deletion(-)
>  create mode 100644 fs/btrfs/subpage.c
>  create mode 100644 fs/btrfs/subpage.h
> 
> diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile
> index 9f1b1a88e317..942562e11456 100644
> --- a/fs/btrfs/Makefile
> +++ b/fs/btrfs/Makefile
> @@ -11,7 +11,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
> index 000000000000..c6ab32db3995
> --- /dev/null
> +++ b/fs/btrfs/subpage.c
> @@ -0,0 +1,39 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include "subpage.h"
> +
> +int btrfs_attach_subpage(struct btrfs_fs_info *fs_info, struct page *page)
> +{
> +	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(*subpage), GFP_NOFS);
> +	if (!subpage)
> +		return -ENOMEM;
> +
> +	spin_lock_init(&subpage->lock);
> +	attach_page_private(page, subpage);
> +	return 0;
> +}
> +
> +void btrfs_detach_subpage(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
> index 000000000000..96f3b226913e
> --- /dev/null
> +++ b/fs/btrfs/subpage.h
> @@ -0,0 +1,31 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef BTRFS_SUBPAGE_H
> +#define BTRFS_SUBPAGE_H
> +
> +#include <linux/spinlock.h>
> +#include "ctree.h"

So subpage.h would pull the whole ctree.h, that's not very nice. If
anything, the .c could include ctree.h because there are lots of the
common structure and function definitions, but not the .h. This creates
unnecessary include dependencies.

Any pointer type you'd need in structures could be forward declared.

> +
> +/*
> + * Since the maximum page size btrfs is going to support is 64K while the
> + * minimum sectorsize is 4K, this means a u16 bitmap is enough.
> + *
> + * The regular bitmap requires 32 bits as minimal bitmap size, so we can't use
> + * existing bitmap_* helpers here.
> + */
> +#define BTRFS_SUBPAGE_BITMAP_SIZE	16
> +
> +/*
> + * Structure to trace status of each sector inside a page.
> + *
> + * Will be attached to page::private for both data and metadata inodes.
> + */
> +struct btrfs_subpage {
> +	/* Common members for both data and metadata pages */
> +	spinlock_t lock;
> +};
> +
> +int btrfs_attach_subpage(struct btrfs_fs_info *fs_info, struct page *page);
> +void btrfs_detach_subpage(struct btrfs_fs_info *fs_info, struct page *page);
> +
> +#endif /* BTRFS_SUBPAGE_H */
> -- 
> 2.30.0
Qu Wenruo Jan. 18, 2021, 10:54 p.m. UTC | #2
On 2021/1/19 上午6:46, David Sterba wrote:
> On Sat, Jan 16, 2021 at 03:15:18PM +0800, Qu Wenruo wrote:
>> For btrfs subpage support, we need a structure to record extra info for
>> the status of each sectors of a page.
>>
>> This patch will introduce the skeleton structure for future btrfs
>> subpage support.
>> All subpage related code would go to subpage.[ch] to avoid populating
>> the existing code base.
>>
>> Reviewed-by: Josef Bacik <josef@toxicpanda.com>
>> Signed-off-by: Qu Wenruo <wqu@suse.com>
>> ---
>>   fs/btrfs/Makefile  |  3 ++-
>>   fs/btrfs/subpage.c | 39 +++++++++++++++++++++++++++++++++++++++
>>   fs/btrfs/subpage.h | 31 +++++++++++++++++++++++++++++++
>>   3 files changed, 72 insertions(+), 1 deletion(-)
>>   create mode 100644 fs/btrfs/subpage.c
>>   create mode 100644 fs/btrfs/subpage.h
>>
>> diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile
>> index 9f1b1a88e317..942562e11456 100644
>> --- a/fs/btrfs/Makefile
>> +++ b/fs/btrfs/Makefile
>> @@ -11,7 +11,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
>> index 000000000000..c6ab32db3995
>> --- /dev/null
>> +++ b/fs/btrfs/subpage.c
>> @@ -0,0 +1,39 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +#include "subpage.h"
>> +
>> +int btrfs_attach_subpage(struct btrfs_fs_info *fs_info, struct page *page)
>> +{
>> +	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(*subpage), GFP_NOFS);
>> +	if (!subpage)
>> +		return -ENOMEM;
>> +
>> +	spin_lock_init(&subpage->lock);
>> +	attach_page_private(page, subpage);
>> +	return 0;
>> +}
>> +
>> +void btrfs_detach_subpage(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
>> index 000000000000..96f3b226913e
>> --- /dev/null
>> +++ b/fs/btrfs/subpage.h
>> @@ -0,0 +1,31 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +
>> +#ifndef BTRFS_SUBPAGE_H
>> +#define BTRFS_SUBPAGE_H
>> +
>> +#include <linux/spinlock.h>
>> +#include "ctree.h"
>
> So subpage.h would pull the whole ctree.h, that's not very nice. If
> anything, the .c could include ctree.h because there are lots of the
> common structure and function definitions, but not the .h. This creates
> unnecessary include dependencies.
>
> Any pointer type you'd need in structures could be forward declared.

Unfortunately, the main needed pointer is fs_info, and we're accessing
it pretty frequently (mostly for sector/node size).

I don't believe forward declaration would help in this case.

Thanks,
Qu
>
>> +
>> +/*
>> + * Since the maximum page size btrfs is going to support is 64K while the
>> + * minimum sectorsize is 4K, this means a u16 bitmap is enough.
>> + *
>> + * The regular bitmap requires 32 bits as minimal bitmap size, so we can't use
>> + * existing bitmap_* helpers here.
>> + */
>> +#define BTRFS_SUBPAGE_BITMAP_SIZE	16
>> +
>> +/*
>> + * Structure to trace status of each sector inside a page.
>> + *
>> + * Will be attached to page::private for both data and metadata inodes.
>> + */
>> +struct btrfs_subpage {
>> +	/* Common members for both data and metadata pages */
>> +	spinlock_t lock;
>> +};
>> +
>> +int btrfs_attach_subpage(struct btrfs_fs_info *fs_info, struct page *page);
>> +void btrfs_detach_subpage(struct btrfs_fs_info *fs_info, struct page *page);
>> +
>> +#endif /* BTRFS_SUBPAGE_H */
>> --
>> 2.30.0
David Sterba Jan. 18, 2021, 11:01 p.m. UTC | #3
On Sat, Jan 16, 2021 at 03:15:18PM +0800, Qu Wenruo wrote:
> For btrfs subpage support, we need a structure to record extra info for
> the status of each sectors of a page.
> 
> This patch will introduce the skeleton structure for future btrfs
> subpage support.
> All subpage related code would go to subpage.[ch] to avoid populating
> the existing code base.

Ok, and after reading more of the patchset it makes even more sense,
handling all the special cases is suitable for a separate file.
David Sterba Jan. 19, 2021, 3:51 p.m. UTC | #4
On Tue, Jan 19, 2021 at 06:54:28AM +0800, Qu Wenruo wrote:
> On 2021/1/19 上午6:46, David Sterba wrote:
> > On Sat, Jan 16, 2021 at 03:15:18PM +0800, Qu Wenruo wrote:
> >> +		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
> >> index 000000000000..96f3b226913e
> >> --- /dev/null
> >> +++ b/fs/btrfs/subpage.h
> >> @@ -0,0 +1,31 @@
> >> +/* SPDX-License-Identifier: GPL-2.0 */
> >> +
> >> +#ifndef BTRFS_SUBPAGE_H
> >> +#define BTRFS_SUBPAGE_H
> >> +
> >> +#include <linux/spinlock.h>
> >> +#include "ctree.h"
> >
> > So subpage.h would pull the whole ctree.h, that's not very nice. If
> > anything, the .c could include ctree.h because there are lots of the
> > common structure and function definitions, but not the .h. This creates
> > unnecessary include dependencies.
> >
> > Any pointer type you'd need in structures could be forward declared.
> 
> Unfortunately, the main needed pointer is fs_info, and we're accessing
> it pretty frequently (mostly for sector/node size).
> 
> I don't believe forward declaration would help in this case.

I've looked at the final subpage.h and you add way too many static
inlines that don't seem to be necessary for the reasons the static
inlines are supposed to be used.
David Sterba Jan. 19, 2021, 4:06 p.m. UTC | #5
On Tue, Jan 19, 2021 at 04:51:45PM +0100, David Sterba wrote:
> On Tue, Jan 19, 2021 at 06:54:28AM +0800, Qu Wenruo wrote:
> > On 2021/1/19 上午6:46, David Sterba wrote:
> > > On Sat, Jan 16, 2021 at 03:15:18PM +0800, Qu Wenruo wrote:
> > >> +		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
> > >> index 000000000000..96f3b226913e
> > >> --- /dev/null
> > >> +++ b/fs/btrfs/subpage.h
> > >> @@ -0,0 +1,31 @@
> > >> +/* SPDX-License-Identifier: GPL-2.0 */
> > >> +
> > >> +#ifndef BTRFS_SUBPAGE_H
> > >> +#define BTRFS_SUBPAGE_H
> > >> +
> > >> +#include <linux/spinlock.h>
> > >> +#include "ctree.h"
> > >
> > > So subpage.h would pull the whole ctree.h, that's not very nice. If
> > > anything, the .c could include ctree.h because there are lots of the
> > > common structure and function definitions, but not the .h. This creates
> > > unnecessary include dependencies.
> > >
> > > Any pointer type you'd need in structures could be forward declared.
> > 
> > Unfortunately, the main needed pointer is fs_info, and we're accessing
> > it pretty frequently (mostly for sector/node size).
> > 
> > I don't believe forward declaration would help in this case.
> 
> I've looked at the final subpage.h and you add way too many static
> inlines that don't seem to be necessary for the reasons the static
> inlines are supposed to be used.

The only file that includes subpage.h is extent_io.c, so as long as it
stays like that it's manageable. But untangling the include hell still
needs to hapen some day and new code that makes it harder worries me.
Qu Wenruo Jan. 20, 2021, 12:19 a.m. UTC | #6
On 2021/1/20 上午12:06, David Sterba wrote:
> On Tue, Jan 19, 2021 at 04:51:45PM +0100, David Sterba wrote:
>> On Tue, Jan 19, 2021 at 06:54:28AM +0800, Qu Wenruo wrote:
>>> On 2021/1/19 上午6:46, David Sterba wrote:
>>>> On Sat, Jan 16, 2021 at 03:15:18PM +0800, Qu Wenruo wrote:
>>>>> +		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
>>>>> index 000000000000..96f3b226913e
>>>>> --- /dev/null
>>>>> +++ b/fs/btrfs/subpage.h
>>>>> @@ -0,0 +1,31 @@
>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>> +
>>>>> +#ifndef BTRFS_SUBPAGE_H
>>>>> +#define BTRFS_SUBPAGE_H
>>>>> +
>>>>> +#include <linux/spinlock.h>
>>>>> +#include "ctree.h"
>>>>
>>>> So subpage.h would pull the whole ctree.h, that's not very nice. If
>>>> anything, the .c could include ctree.h because there are lots of the
>>>> common structure and function definitions, but not the .h. This creates
>>>> unnecessary include dependencies.
>>>>
>>>> Any pointer type you'd need in structures could be forward declared.
>>>
>>> Unfortunately, the main needed pointer is fs_info, and we're accessing
>>> it pretty frequently (mostly for sector/node size).
>>>
>>> I don't believe forward declaration would help in this case.
>>
>> I've looked at the final subpage.h and you add way too many static
>> inlines that don't seem to be necessary for the reasons the static
>> inlines are supposed to be used.
>
> The only file that includes subpage.h is extent_io.c, so as long as it
> stays like that it's manageable. But untangling the include hell still
> needs to hapen some day and new code that makes it harder worries me.
>
If going through the github branch, you will see there are more files
using subpage.h:
- extent_io.c
- disk-io.c
- file.c
- inode.c
- reflink.c
- relocation.c

And furthermore, about the static inline abuse, the part really need
that static inline is the check against regular sector size, and
unfortunately, most outside callers need such check.

I can put the pure subpage callers into subpage.c, but the generic
helpers handling both cases still need that.

Thanks,
Qu
David Sterba Jan. 23, 2021, 7:37 p.m. UTC | #7
On Wed, Jan 20, 2021 at 08:19:14AM +0800, Qu Wenruo wrote:
> 
> 
> On 2021/1/20 上午12:06, David Sterba wrote:
> > On Tue, Jan 19, 2021 at 04:51:45PM +0100, David Sterba wrote:
> >> On Tue, Jan 19, 2021 at 06:54:28AM +0800, Qu Wenruo wrote:
> >>> On 2021/1/19 上午6:46, David Sterba wrote:
> >>>> On Sat, Jan 16, 2021 at 03:15:18PM +0800, Qu Wenruo wrote:
> >>>>> +		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
> >>>>> index 000000000000..96f3b226913e
> >>>>> --- /dev/null
> >>>>> +++ b/fs/btrfs/subpage.h
> >>>>> @@ -0,0 +1,31 @@
> >>>>> +/* SPDX-License-Identifier: GPL-2.0 */
> >>>>> +
> >>>>> +#ifndef BTRFS_SUBPAGE_H
> >>>>> +#define BTRFS_SUBPAGE_H
> >>>>> +
> >>>>> +#include <linux/spinlock.h>
> >>>>> +#include "ctree.h"
> >>>>
> >>>> So subpage.h would pull the whole ctree.h, that's not very nice. If
> >>>> anything, the .c could include ctree.h because there are lots of the
> >>>> common structure and function definitions, but not the .h. This creates
> >>>> unnecessary include dependencies.
> >>>>
> >>>> Any pointer type you'd need in structures could be forward declared.
> >>>
> >>> Unfortunately, the main needed pointer is fs_info, and we're accessing
> >>> it pretty frequently (mostly for sector/node size).
> >>>
> >>> I don't believe forward declaration would help in this case.
> >>
> >> I've looked at the final subpage.h and you add way too many static
> >> inlines that don't seem to be necessary for the reasons the static
> >> inlines are supposed to be used.
> >
> > The only file that includes subpage.h is extent_io.c, so as long as it
> > stays like that it's manageable. But untangling the include hell still
> > needs to hapen some day and new code that makes it harder worries me.
> >
> If going through the github branch, you will see there are more files
> using subpage.h:
> - extent_io.c
> - disk-io.c
> - file.c
> - inode.c
> - reflink.c
> - relocation.c
> 
> And furthermore, about the static inline abuse, the part really need
> that static inline is the check against regular sector size, and
> unfortunately, most outside callers need such check.
> 
> I can put the pure subpage callers into subpage.c, but the generic
> helpers handling both cases still need that.

I had a look and this is too much. Just by counting 'static inline'
(wher it's also part of the btrfs_page_clamp_* helpers) it's 30 and not
all the functions are short enough for static inlines. Please make them
all regular functions and put them to subpage.c and don't include
ctree.h.
Qu Wenruo Jan. 24, 2021, 12:24 a.m. UTC | #8
On 2021/1/24 上午3:37, David Sterba wrote:
> On Wed, Jan 20, 2021 at 08:19:14AM +0800, Qu Wenruo wrote:
>>
>>
>> On 2021/1/20 上午12:06, David Sterba wrote:
>>> On Tue, Jan 19, 2021 at 04:51:45PM +0100, David Sterba wrote:
>>>> On Tue, Jan 19, 2021 at 06:54:28AM +0800, Qu Wenruo wrote:
>>>>> On 2021/1/19 上午6:46, David Sterba wrote:
>>>>>> On Sat, Jan 16, 2021 at 03:15:18PM +0800, Qu Wenruo wrote:
>>>>>>> +		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
>>>>>>> index 000000000000..96f3b226913e
>>>>>>> --- /dev/null
>>>>>>> +++ b/fs/btrfs/subpage.h
>>>>>>> @@ -0,0 +1,31 @@
>>>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>>>> +
>>>>>>> +#ifndef BTRFS_SUBPAGE_H
>>>>>>> +#define BTRFS_SUBPAGE_H
>>>>>>> +
>>>>>>> +#include <linux/spinlock.h>
>>>>>>> +#include "ctree.h"
>>>>>>
>>>>>> So subpage.h would pull the whole ctree.h, that's not very nice. If
>>>>>> anything, the .c could include ctree.h because there are lots of the
>>>>>> common structure and function definitions, but not the .h. This creates
>>>>>> unnecessary include dependencies.
>>>>>>
>>>>>> Any pointer type you'd need in structures could be forward declared.
>>>>>
>>>>> Unfortunately, the main needed pointer is fs_info, and we're accessing
>>>>> it pretty frequently (mostly for sector/node size).
>>>>>
>>>>> I don't believe forward declaration would help in this case.
>>>>
>>>> I've looked at the final subpage.h and you add way too many static
>>>> inlines that don't seem to be necessary for the reasons the static
>>>> inlines are supposed to be used.
>>>
>>> The only file that includes subpage.h is extent_io.c, so as long as it
>>> stays like that it's manageable. But untangling the include hell still
>>> needs to hapen some day and new code that makes it harder worries me.
>>>
>> If going through the github branch, you will see there are more files
>> using subpage.h:
>> - extent_io.c
>> - disk-io.c
>> - file.c
>> - inode.c
>> - reflink.c
>> - relocation.c
>>
>> And furthermore, about the static inline abuse, the part really need
>> that static inline is the check against regular sector size, and
>> unfortunately, most outside callers need such check.
>>
>> I can put the pure subpage callers into subpage.c, but the generic
>> helpers handling both cases still need that.
>
> I had a look and this is too much. Just by counting 'static inline'
> (wher it's also part of the btrfs_page_clamp_* helpers) it's 30 and not
> all the functions are short enough for static inlines. Please make them
> all regular functions and put them to subpage.c and don't include
> ctree.h.
>
OK, I'll go that direction for next update.

Thanks,
Qu
diff mbox series

Patch

diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile
index 9f1b1a88e317..942562e11456 100644
--- a/fs/btrfs/Makefile
+++ b/fs/btrfs/Makefile
@@ -11,7 +11,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
index 000000000000..c6ab32db3995
--- /dev/null
+++ b/fs/btrfs/subpage.c
@@ -0,0 +1,39 @@ 
+// SPDX-License-Identifier: GPL-2.0
+
+#include "subpage.h"
+
+int btrfs_attach_subpage(struct btrfs_fs_info *fs_info, struct page *page)
+{
+	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(*subpage), GFP_NOFS);
+	if (!subpage)
+		return -ENOMEM;
+
+	spin_lock_init(&subpage->lock);
+	attach_page_private(page, subpage);
+	return 0;
+}
+
+void btrfs_detach_subpage(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
index 000000000000..96f3b226913e
--- /dev/null
+++ b/fs/btrfs/subpage.h
@@ -0,0 +1,31 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef BTRFS_SUBPAGE_H
+#define BTRFS_SUBPAGE_H
+
+#include <linux/spinlock.h>
+#include "ctree.h"
+
+/*
+ * Since the maximum page size btrfs is going to support is 64K while the
+ * minimum sectorsize is 4K, this means a u16 bitmap is enough.
+ *
+ * The regular bitmap requires 32 bits as minimal bitmap size, so we can't use
+ * existing bitmap_* helpers here.
+ */
+#define BTRFS_SUBPAGE_BITMAP_SIZE	16
+
+/*
+ * Structure to trace status of each sector inside a page.
+ *
+ * Will be attached to page::private for both data and metadata inodes.
+ */
+struct btrfs_subpage {
+	/* Common members for both data and metadata pages */
+	spinlock_t lock;
+};
+
+int btrfs_attach_subpage(struct btrfs_fs_info *fs_info, struct page *page);
+void btrfs_detach_subpage(struct btrfs_fs_info *fs_info, struct page *page);
+
+#endif /* BTRFS_SUBPAGE_H */