xref: /OK3568_Linux_fs/kernel/fs/jfs/jfs_metapage.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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