• Chao Yu's avatar
    f2fs: restructure f2fs page.private layout · b763f3be
    Chao Yu authored
    Restruct f2fs page private layout for below reasons:
    
    There are some cases that f2fs wants to set a flag in a page to
    indicate a specified status of page:
    a) page is in transaction list for atomic write
    b) page contains dummy data for aligned write
    c) page is migrating for GC
    d) page contains inline data for inline inode flush
    e) page belongs to merkle tree, and is verified for fsverity
    f) page is dirty and has filesystem/inode reference count for writeback
    g) page is temporary and has decompress io context reference for compression
    
    There are existed places in page structure we can use to store
    f2fs private status/data:
    - page.flags: PG_checked, PG_private
    - page.private
    
    However it was a mess when we using them, which may cause potential
    confliction:
    		page.private	PG_private	PG_checked	page._refcount (+1 at most)
    a)		-1		set				+1
    b)		-2		set
    c), d), e)					set
    f)		0		set				+1
    g)		pointer		set
    
    The other problem is page.flags has no free slot, if we can avoid set
    zero to page.private and set PG_private flag, then we use non-zero value
    to indicate PG_private status, so that we may have chance to reclaim
    PG_private slot for other usage. [1]
    
    The other concern is f2fs has bad scalability in aspect of indicating
    more page status.
    
    So in this patch, let's restructure f2fs' page.private as below to
    solve above issues:
    
    Layout A: lowest bit should be 1
    | bit0 = 1 | bit1 | bit2 | ... | bit MAX | private data .... |
     bit 0	PAGE_PRIVATE_NOT_POINTER
     bit 1	PAGE_PRIVATE_ATOMIC_WRITE
     bit 2	PAGE_PRIVATE_DUMMY_WRITE
     bit 3	PAGE_PRIVATE_ONGOING_MIGRATION
     bit 4	PAGE_PRIVATE_INLINE_INODE
     bit 5	PAGE_PRIVATE_REF_RESOURCE
     bit 6-	f2fs private data
    
    Layout B: lowest bit should be 0
     page.private is a wrapped pointer.
    
    After the change:
    		page.private	PG_private	PG_checked	page._refcount (+1 at most)
    a)		11		set				+1
    b)		101		set				+1
    c)		1001		set				+1
    d)		10001		set				+1
    e)						set
    f)		100001		set				+1
    g)		pointer		set				+1
    
    [1] https://lore.kernel.org/linux-f2fs-devel/20210422154705.GO3596236@casper.infradead.org/T/#u
    
    Cc: Matthew Wilcox <willy@infradead.org>
    Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
    Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
    b763f3be
node.h 11.9 KB