2019-05-27 09:55:05 +03:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
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
|
|
|
*/
|
|
|
|
#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;
|
2017-07-05 22:26:49 +03:00
|
|
|
struct super_block *sb;
|
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_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);
|
mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.
This promise never materialized. And unlikely will.
We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE. And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.
Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.
Let's stop pretending that pages in page cache are special. They are
not.
The changes are pretty straight-forward:
- <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
- page_cache_get() -> get_page();
- page_cache_release() -> put_page();
This patch contains automated changes generated with coccinelle using
script below. For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.
The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.
There are few places in the code where coccinelle didn't reach. I'll
fix them manually in a separate patch. Comments and documentation also
will be addressed with the separate patch.
virtual patch
@@
expression E;
@@
- E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
expression E;
@@
- E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT
@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE
@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK
@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)
@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)
@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-04-01 15:29:47 +03:00
|
|
|
get_page(page);
|
2005-05-02 22:25:02 +04:00
|
|
|
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)
|
mm, fs: get rid of PAGE_CACHE_* and page_cache_{get,release} macros
PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} macros were introduced *long* time
ago with promise that one day it will be possible to implement page
cache with bigger chunks than PAGE_SIZE.
This promise never materialized. And unlikely will.
We have many places where PAGE_CACHE_SIZE assumed to be equal to
PAGE_SIZE. And it's constant source of confusion on whether
PAGE_CACHE_* or PAGE_* constant should be used in a particular case,
especially on the border between fs and mm.
Global switching to PAGE_CACHE_SIZE != PAGE_SIZE would cause to much
breakage to be doable.
Let's stop pretending that pages in page cache are special. They are
not.
The changes are pretty straight-forward:
- <foo> << (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- <foo> >> (PAGE_CACHE_SHIFT - PAGE_SHIFT) -> <foo>;
- PAGE_CACHE_{SIZE,SHIFT,MASK,ALIGN} -> PAGE_{SIZE,SHIFT,MASK,ALIGN};
- page_cache_get() -> get_page();
- page_cache_release() -> put_page();
This patch contains automated changes generated with coccinelle using
script below. For some reason, coccinelle doesn't patch header files.
I've called spatch for them manually.
The only adjustment after coccinelle is revert of changes to
PAGE_CAHCE_ALIGN definition: we are going to drop it later.
There are few places in the code where coccinelle didn't reach. I'll
fix them manually in a separate patch. Comments and documentation also
will be addressed with the separate patch.
virtual patch
@@
expression E;
@@
- E << (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
expression E;
@@
- E >> (PAGE_CACHE_SHIFT - PAGE_SHIFT)
+ E
@@
@@
- PAGE_CACHE_SHIFT
+ PAGE_SHIFT
@@
@@
- PAGE_CACHE_SIZE
+ PAGE_SIZE
@@
@@
- PAGE_CACHE_MASK
+ PAGE_MASK
@@
expression E;
@@
- PAGE_CACHE_ALIGN(E)
+ PAGE_ALIGN(E)
@@
expression E;
@@
- page_cache_get(E)
+ get_page(E)
@@
expression E;
@@
- page_cache_release(E)
+ put_page(E)
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-04-01 15:29:47 +03:00
|
|
|
put_page(mp->page);
|
2005-05-02 22:25:02 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
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 */
|