1174604Sscottl/* SPDX-License-Identifier: GPL-2.0-or-later */ 2174604Sscottl/* 3174604Sscottl * Copyright (C) International Business Machines Corp., 2000-2002 4174604Sscottl * Portions Copyright (C) Christoph Hellwig, 2001-2002 5174604Sscottl */ 6174604Sscottl#ifndef _H_JFS_METAPAGE 7174604Sscottl#define _H_JFS_METAPAGE 8174604Sscottl 9174604Sscottl#include <linux/pagemap.h> 10174604Sscottl 11174604Sscottlstruct metapage { 12174604Sscottl /* Common logsyncblk prefix (see jfs_logmgr.h) */ 13174604Sscottl u16 xflag; 14174604Sscottl u16 unused; 15174604Sscottl lid_t lid; 16174604Sscottl int lsn; 17174604Sscottl struct list_head synclist; 18174604Sscottl /* End of logsyncblk prefix */ 19174604Sscottl 20174604Sscottl unsigned long flag; /* See Below */ 21174604Sscottl unsigned long count; /* Reference count */ 22174604Sscottl void *data; /* Data pointer */ 23174604Sscottl sector_t index; /* block address of page */ 24174604Sscottl wait_queue_head_t wait; 25174604Sscottl 26174604Sscottl /* implementation */ 27174604Sscottl struct page *page; 28174604Sscottl struct super_block *sb; 29174604Sscottl unsigned int logical_size; 30174604Sscottl 31174604Sscottl /* Journal management */ 32174604Sscottl int clsn; 33174604Sscottl int nohomeok; 34174604Sscottl struct jfs_log *log; 35174604Sscottl}; 36174604Sscottl 37174604Sscottl/* metapage flag */ 38174604Sscottl#define META_locked 0 39174604Sscottl#define META_dirty 2 40174604Sscottl#define META_sync 3 41174604Sscottl#define META_discard 4 42174604Sscottl#define META_forcewrite 5 43174604Sscottl#define META_io 6 44174604Sscottl 45174604Sscottl#define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag) 46174604Sscottl 47174604Sscottl/* function prototypes */ 48174604Sscottlextern int metapage_init(void); 49174604Sscottlextern void metapage_exit(void); 50174604Sscottlextern struct metapage *__get_metapage(struct inode *inode, 51174604Sscottl unsigned long lblock, unsigned int size, 52174604Sscottl int absolute, unsigned long new); 53174604Sscottl 54174604Sscottl#define read_metapage(inode, lblock, size, absolute)\ 55174604Sscottl __get_metapage(inode, lblock, size, absolute, false) 56174604Sscottl 57174604Sscottl#define get_metapage(inode, lblock, size, absolute)\ 58174604Sscottl __get_metapage(inode, lblock, size, absolute, true) 59174604Sscottl 60174604Sscottlextern void release_metapage(struct metapage *); 61174604Sscottlextern void grab_metapage(struct metapage *); 62174604Sscottlextern void force_metapage(struct metapage *); 63174604Sscottl 64174604Sscottl/* 65174604Sscottl * hold_metapage and put_metapage are used in conjunction. The page lock 66174604Sscottl * is not dropped between the two, so no other threads can get or release 67174604Sscottl * the metapage 68174604Sscottl */ 69174604Sscottlextern void hold_metapage(struct metapage *); 70174604Sscottlextern void put_metapage(struct metapage *); 71174604Sscottl 72174604Sscottlstatic inline void write_metapage(struct metapage *mp) 73174604Sscottl{ 74174604Sscottl set_bit(META_dirty, &mp->flag); 75174604Sscottl release_metapage(mp); 76174604Sscottl} 77174604Sscottl 78174604Sscottlstatic inline void flush_metapage(struct metapage *mp) 79174604Sscottl{ 80174604Sscottl set_bit(META_sync, &mp->flag); 81174604Sscottl write_metapage(mp); 82174604Sscottl} 83174604Sscottl 84174604Sscottlstatic inline void discard_metapage(struct metapage *mp) 85174604Sscottl{ 86174604Sscottl clear_bit(META_dirty, &mp->flag); 87174604Sscottl set_bit(META_discard, &mp->flag); 88174604Sscottl release_metapage(mp); 89174604Sscottl} 90174604Sscottl 91174604Sscottlstatic inline void metapage_nohomeok(struct metapage *mp) 92174604Sscottl{ 93174604Sscottl struct page *page = mp->page; 94174604Sscottl lock_page(page); 95174604Sscottl if (!mp->nohomeok++) { 96174604Sscottl mark_metapage_dirty(mp); 97174604Sscottl get_page(page); 98174604Sscottl wait_on_page_writeback(page); 99174604Sscottl } 100174604Sscottl unlock_page(page); 101174604Sscottl} 102174604Sscottl 103174604Sscottl/* 104174604Sscottl * This serializes access to mp->lsn when metapages are added to logsynclist 105174604Sscottl * without setting nohomeok. i.e. updating imap & dmap 106174604Sscottl */ 107174604Sscottlstatic inline void metapage_wait_for_io(struct metapage *mp) 108174604Sscottl{ 109174604Sscottl if (test_bit(META_io, &mp->flag)) 110174604Sscottl wait_on_page_writeback(mp->page); 111174604Sscottl} 112174604Sscottl 113174604Sscottl/* 114174604Sscottl * This is called when already holding the metapage 115174604Sscottl */ 116174604Sscottlstatic inline void _metapage_homeok(struct metapage *mp) 117174604Sscottl{ 118174604Sscottl if (!--mp->nohomeok) 119174604Sscottl put_page(mp->page); 120174604Sscottl} 121174604Sscottl 122174604Sscottlstatic inline void metapage_homeok(struct metapage *mp) 123174604Sscottl{ 124174604Sscottl hold_metapage(mp); 125174604Sscottl _metapage_homeok(mp); 126174604Sscottl put_metapage(mp); 127174604Sscottl} 128174604Sscottl 129174604Sscottlextern const struct address_space_operations jfs_metapage_aops; 130174604Sscottl 131174604Sscottl/* 132174604Sscottl * This routines invalidate all pages for an extent. 133174604Sscottl */ 134174604Sscottlextern void __invalidate_metapages(struct inode *, s64, int); 135174604Sscottl#define invalidate_pxd_metapages(ip, pxd) \ 136174604Sscottl __invalidate_metapages((ip), addressPXD(&(pxd)), lengthPXD(&(pxd))) 137174604Sscottl#define invalidate_dxd_metapages(ip, dxd) \ 138174604Sscottl __invalidate_metapages((ip), addressDXD(&(dxd)), lengthDXD(&(dxd))) 139174604Sscottl#define invalidate_xad_metapages(ip, xad) \ 140174604Sscottl __invalidate_metapages((ip), addressXAD(&(xad)), lengthXAD(&(xad))) 141174604Sscottl 142174604Sscottl#endif /* _H_JFS_METAPAGE */ 143174604Sscottl