1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) International Business Machines Corp., 2000-2002
4*4882a593Smuzhiyun * Portions Copyright (C) Christoph Hellwig, 2001-2002
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun #ifndef _H_JFS_METAPAGE
7*4882a593Smuzhiyun #define _H_JFS_METAPAGE
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <linux/pagemap.h>
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun struct metapage {
12*4882a593Smuzhiyun /* Common logsyncblk prefix (see jfs_logmgr.h) */
13*4882a593Smuzhiyun u16 xflag;
14*4882a593Smuzhiyun u16 unused;
15*4882a593Smuzhiyun lid_t lid;
16*4882a593Smuzhiyun int lsn;
17*4882a593Smuzhiyun struct list_head synclist;
18*4882a593Smuzhiyun /* End of logsyncblk prefix */
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun unsigned long flag; /* See Below */
21*4882a593Smuzhiyun unsigned long count; /* Reference count */
22*4882a593Smuzhiyun void *data; /* Data pointer */
23*4882a593Smuzhiyun sector_t index; /* block address of page */
24*4882a593Smuzhiyun wait_queue_head_t wait;
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun /* implementation */
27*4882a593Smuzhiyun struct page *page;
28*4882a593Smuzhiyun struct super_block *sb;
29*4882a593Smuzhiyun unsigned int logical_size;
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun /* Journal management */
32*4882a593Smuzhiyun int clsn;
33*4882a593Smuzhiyun int nohomeok;
34*4882a593Smuzhiyun struct jfs_log *log;
35*4882a593Smuzhiyun };
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /* metapage flag */
38*4882a593Smuzhiyun #define META_locked 0
39*4882a593Smuzhiyun #define META_dirty 2
40*4882a593Smuzhiyun #define META_sync 3
41*4882a593Smuzhiyun #define META_discard 4
42*4882a593Smuzhiyun #define META_forcewrite 5
43*4882a593Smuzhiyun #define META_io 6
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun #define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag)
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /* function prototypes */
48*4882a593Smuzhiyun extern int metapage_init(void);
49*4882a593Smuzhiyun extern void metapage_exit(void);
50*4882a593Smuzhiyun extern struct metapage *__get_metapage(struct inode *inode,
51*4882a593Smuzhiyun unsigned long lblock, unsigned int size,
52*4882a593Smuzhiyun int absolute, unsigned long new);
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun #define read_metapage(inode, lblock, size, absolute)\
55*4882a593Smuzhiyun __get_metapage(inode, lblock, size, absolute, false)
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun #define get_metapage(inode, lblock, size, absolute)\
58*4882a593Smuzhiyun __get_metapage(inode, lblock, size, absolute, true)
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun extern void release_metapage(struct metapage *);
61*4882a593Smuzhiyun extern void grab_metapage(struct metapage *);
62*4882a593Smuzhiyun extern void force_metapage(struct metapage *);
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun /*
65*4882a593Smuzhiyun * hold_metapage and put_metapage are used in conjunction. The page lock
66*4882a593Smuzhiyun * is not dropped between the two, so no other threads can get or release
67*4882a593Smuzhiyun * the metapage
68*4882a593Smuzhiyun */
69*4882a593Smuzhiyun extern void hold_metapage(struct metapage *);
70*4882a593Smuzhiyun extern void put_metapage(struct metapage *);
71*4882a593Smuzhiyun
write_metapage(struct metapage * mp)72*4882a593Smuzhiyun static inline void write_metapage(struct metapage *mp)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun set_bit(META_dirty, &mp->flag);
75*4882a593Smuzhiyun release_metapage(mp);
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun
flush_metapage(struct metapage * mp)78*4882a593Smuzhiyun static inline void flush_metapage(struct metapage *mp)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun set_bit(META_sync, &mp->flag);
81*4882a593Smuzhiyun write_metapage(mp);
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun
discard_metapage(struct metapage * mp)84*4882a593Smuzhiyun static inline void discard_metapage(struct metapage *mp)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun clear_bit(META_dirty, &mp->flag);
87*4882a593Smuzhiyun set_bit(META_discard, &mp->flag);
88*4882a593Smuzhiyun release_metapage(mp);
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
metapage_nohomeok(struct metapage * mp)91*4882a593Smuzhiyun static inline void metapage_nohomeok(struct metapage *mp)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun struct page *page = mp->page;
94*4882a593Smuzhiyun lock_page(page);
95*4882a593Smuzhiyun if (!mp->nohomeok++) {
96*4882a593Smuzhiyun mark_metapage_dirty(mp);
97*4882a593Smuzhiyun get_page(page);
98*4882a593Smuzhiyun wait_on_page_writeback(page);
99*4882a593Smuzhiyun }
100*4882a593Smuzhiyun unlock_page(page);
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun /*
104*4882a593Smuzhiyun * This serializes access to mp->lsn when metapages are added to logsynclist
105*4882a593Smuzhiyun * without setting nohomeok. i.e. updating imap & dmap
106*4882a593Smuzhiyun */
metapage_wait_for_io(struct metapage * mp)107*4882a593Smuzhiyun static inline void metapage_wait_for_io(struct metapage *mp)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun if (test_bit(META_io, &mp->flag))
110*4882a593Smuzhiyun wait_on_page_writeback(mp->page);
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun /*
114*4882a593Smuzhiyun * This is called when already holding the metapage
115*4882a593Smuzhiyun */
_metapage_homeok(struct metapage * mp)116*4882a593Smuzhiyun static inline void _metapage_homeok(struct metapage *mp)
117*4882a593Smuzhiyun {
118*4882a593Smuzhiyun if (!--mp->nohomeok)
119*4882a593Smuzhiyun put_page(mp->page);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
metapage_homeok(struct metapage * mp)122*4882a593Smuzhiyun static inline void metapage_homeok(struct metapage *mp)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun hold_metapage(mp);
125*4882a593Smuzhiyun _metapage_homeok(mp);
126*4882a593Smuzhiyun put_metapage(mp);
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun extern const struct address_space_operations jfs_metapage_aops;
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun /*
132*4882a593Smuzhiyun * This routines invalidate all pages for an extent.
133*4882a593Smuzhiyun */
134*4882a593Smuzhiyun extern void __invalidate_metapages(struct inode *, s64, int);
135*4882a593Smuzhiyun #define invalidate_pxd_metapages(ip, pxd) \
136*4882a593Smuzhiyun __invalidate_metapages((ip), addressPXD(&(pxd)), lengthPXD(&(pxd)))
137*4882a593Smuzhiyun #define invalidate_dxd_metapages(ip, dxd) \
138*4882a593Smuzhiyun __invalidate_metapages((ip), addressDXD(&(dxd)), lengthDXD(&(dxd)))
139*4882a593Smuzhiyun #define invalidate_xad_metapages(ip, xad) \
140*4882a593Smuzhiyun __invalidate_metapages((ip), addressXAD(&(xad)), lengthXAD(&(xad)))
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun #endif /* _H_JFS_METAPAGE */
143