2005-04-17 02:20:36 +04:00
/*
2005-05-05 00:29:35 +04:00
* Copyright ( C ) International Business Machines Corp . , 2000 - 2002
* Portions Copyright ( C ) Christoph Hellwig , 2001 - 2002
2005-04-17 02:20:36 +04:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2006-10-02 18:55:27 +04:00
* the Free Software Foundation ; either version 2 of the License , or
2005-04-17 02:20:36 +04:00
* ( at your option ) any later version .
2006-10-02 18:55:27 +04:00
*
2005-04-17 02:20:36 +04:00
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See
* the GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2006-10-02 18:55:27 +04:00
* along with this program ; if not , write to the Free Software
2005-04-17 02:20:36 +04:00
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# ifndef _H_JFS_METAPAGE
# define _H_JFS_METAPAGE
# include <linux/pagemap.h>
struct metapage {
/* Common logsyncblk prefix (see jfs_logmgr.h) */
u16 xflag ;
u16 unused ;
lid_t lid ;
int lsn ;
struct list_head synclist ;
/* End of logsyncblk prefix */
unsigned long flag ; /* See Below */
unsigned long count ; /* Reference count */
void * data ; /* Data pointer */
2006-10-02 18:55:27 +04:00
sector_t index ; /* block address of page */
2005-04-17 02:20:36 +04:00
wait_queue_head_t wait ;
/* implementation */
struct page * page ;
2005-05-02 22:25:02 +04:00
unsigned int logical_size ;
2005-04-17 02:20:36 +04:00
/* Journal management */
int clsn ;
2005-05-02 22:25:02 +04:00
int nohomeok ;
2005-04-17 02:20:36 +04:00
struct jfs_log * log ;
} ;
/* metapage flag */
# define META_locked 0
2005-05-02 22:25:02 +04:00
# define META_free 1
# define META_dirty 2
# define META_sync 3
# define META_discard 4
# define META_forcewrite 5
# define META_io 6
2005-04-17 02:20:36 +04:00
# define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag)
/* function prototypes */
2005-05-05 00:29:35 +04:00
extern int metapage_init ( void ) ;
extern void metapage_exit ( void ) ;
2005-04-17 02:20:36 +04:00
extern struct metapage * __get_metapage ( struct inode * inode ,
unsigned long lblock , unsigned int size ,
int absolute , unsigned long new ) ;
# define read_metapage(inode, lblock, size, absolute)\
2006-10-01 10:27:14 +04:00
__get_metapage ( inode , lblock , size , absolute , false )
2005-04-17 02:20:36 +04:00
# define get_metapage(inode, lblock, size, absolute)\
2006-10-01 10:27:14 +04:00
__get_metapage ( inode , lblock , size , absolute , true )
2005-04-17 02:20:36 +04:00
extern void release_metapage ( struct metapage * ) ;
2005-05-02 22:25:02 +04:00
extern void grab_metapage ( struct metapage * ) ;
extern void force_metapage ( struct metapage * ) ;
/*
2011-03-31 05:57:33 +04:00
* hold_metapage and put_metapage are used in conjunction . The page lock
2005-05-02 22:25:02 +04:00
* is not dropped between the two , so no other threads can get or release
* the metapage
*/
extern void hold_metapage ( struct metapage * ) ;
extern void put_metapage ( struct metapage * ) ;
2005-04-17 02:20:36 +04:00
static inline void write_metapage ( struct metapage * mp )
{
set_bit ( META_dirty , & mp - > flag ) ;
release_metapage ( mp ) ;
}
static inline void flush_metapage ( struct metapage * mp )
{
set_bit ( META_sync , & mp - > flag ) ;
write_metapage ( mp ) ;
}
static inline void discard_metapage ( struct metapage * mp )
{
clear_bit ( META_dirty , & mp - > flag ) ;
set_bit ( META_discard , & mp - > flag ) ;
release_metapage ( mp ) ;
}
2005-05-02 22:25:02 +04:00
static inline void metapage_nohomeok ( struct metapage * mp )
{
struct page * page = mp - > page ;
lock_page ( page ) ;
if ( ! mp - > nohomeok + + ) {
mark_metapage_dirty ( mp ) ;
page_cache_get ( page ) ;
wait_on_page_writeback ( page ) ;
}
unlock_page ( page ) ;
}
/*
* This serializes access to mp - > lsn when metapages are added to logsynclist
* without setting nohomeok . i . e . updating imap & dmap
*/
static inline void metapage_wait_for_io ( struct metapage * mp )
{
if ( test_bit ( META_io , & mp - > flag ) )
wait_on_page_writeback ( mp - > page ) ;
}
/*
* This is called when already holding the metapage
*/
static inline void _metapage_homeok ( struct metapage * mp )
{
if ( ! - - mp - > nohomeok )
page_cache_release ( mp - > page ) ;
}
static inline void metapage_homeok ( struct metapage * mp )
{
hold_metapage ( mp ) ;
_metapage_homeok ( mp ) ;
put_metapage ( mp ) ;
}
2006-06-28 15:26:44 +04:00
extern const struct address_space_operations jfs_metapage_aops ;
2005-05-02 22:25:02 +04:00
2005-04-17 02:20:36 +04:00
/*
* This routines invalidate all pages for an extent .
*/
extern void __invalidate_metapages ( struct inode * , s64 , int ) ;
# define invalidate_pxd_metapages(ip, pxd) \
__invalidate_metapages ( ( ip ) , addressPXD ( & ( pxd ) ) , lengthPXD ( & ( pxd ) ) )
# define invalidate_dxd_metapages(ip, dxd) \
__invalidate_metapages ( ( ip ) , addressDXD ( & ( dxd ) ) , lengthDXD ( & ( dxd ) ) )
# define invalidate_xad_metapages(ip, xad) \
__invalidate_metapages ( ( ip ) , addressXAD ( & ( xad ) ) , lengthXAD ( & ( xad ) ) )
# endif /* _H_JFS_METAPAGE */