#include <linux/blkdev.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/bio.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/buffer_head.h>
#include <linux/mempool.h>
#include <linux/seq_file.h>
#include <linux/writeback.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_filsys.h"
#include "jfs_metapage.h"
#include "jfs_txnmgr.h"
#include "jfs_debug.h"
#ifdef CONFIG_JFS_STATISTICS
static struct { … } mpStat;
#endif
#define metapage_locked(mp) …
#define trylock_metapage(mp) …
static inline void unlock_metapage(struct metapage *mp)
{ … }
static inline void __lock_metapage(struct metapage *mp)
{ … }
static inline void lock_metapage(struct metapage *mp)
{ … }
#define METAPOOL_MIN_PAGES …
static struct kmem_cache *metapage_cache;
static mempool_t *metapage_mempool;
#define MPS_PER_PAGE …
#if MPS_PER_PAGE > 1
struct meta_anchor {
int mp_count;
atomic_t io_count;
blk_status_t status;
struct metapage *mp[MPS_PER_PAGE];
};
static inline struct metapage *folio_to_mp(struct folio *folio, int offset)
{
struct meta_anchor *anchor = folio->private;
if (!anchor)
return NULL;
return anchor->mp[offset >> L2PSIZE];
}
static inline int insert_metapage(struct folio *folio, struct metapage *mp)
{
struct meta_anchor *a;
int index;
int l2mp_blocks;
a = folio->private;
if (!a) {
a = kzalloc(sizeof(struct meta_anchor), GFP_NOFS);
if (!a)
return -ENOMEM;
folio_attach_private(folio, a);
kmap(&folio->page);
}
if (mp) {
l2mp_blocks = L2PSIZE - folio->mapping->host->i_blkbits;
index = (mp->index >> l2mp_blocks) & (MPS_PER_PAGE - 1);
a->mp_count++;
a->mp[index] = mp;
}
return 0;
}
static inline void remove_metapage(struct folio *folio, struct metapage *mp)
{
struct meta_anchor *a = folio->private;
int l2mp_blocks = L2PSIZE - folio->mapping->host->i_blkbits;
int index;
index = (mp->index >> l2mp_blocks) & (MPS_PER_PAGE - 1);
BUG_ON(a->mp[index] != mp);
a->mp[index] = NULL;
if (--a->mp_count == 0) {
kfree(a);
folio_detach_private(folio);
kunmap(&folio->page);
}
}
static inline void inc_io(struct folio *folio)
{
struct meta_anchor *anchor = folio->private;
atomic_inc(&anchor->io_count);
}
static inline void dec_io(struct folio *folio, blk_status_t status,
void (*handler)(struct folio *, blk_status_t))
{
struct meta_anchor *anchor = folio->private;
if (anchor->status == BLK_STS_OK)
anchor->status = status;
if (atomic_dec_and_test(&anchor->io_count))
handler(folio, anchor->status);
}
#else
static inline struct metapage *folio_to_mp(struct folio *folio, int offset)
{ … }
static inline int insert_metapage(struct folio *folio, struct metapage *mp)
{ … }
static inline void remove_metapage(struct folio *folio, struct metapage *mp)
{ … }
#define inc_io(folio) …
#define dec_io(folio, status, handler) …
#endif
static inline struct metapage *alloc_metapage(gfp_t gfp_mask)
{ … }
static inline void free_metapage(struct metapage *mp)
{ … }
int __init metapage_init(void)
{ … }
void metapage_exit(void)
{ … }
static inline void drop_metapage(struct folio *folio, struct metapage *mp)
{ … }
static sector_t metapage_get_blocks(struct inode *inode, sector_t lblock,
int *len)
{ … }
static void last_read_complete(struct folio *folio, blk_status_t status)
{ … }
static void metapage_read_end_io(struct bio *bio)
{ … }
static void remove_from_logsync(struct metapage *mp)
{ … }
static void last_write_complete(struct folio *folio, blk_status_t status)
{ … }
static void metapage_write_end_io(struct bio *bio)
{ … }
static int metapage_write_folio(struct folio *folio,
struct writeback_control *wbc, void *unused)
{ … }
static int metapage_writepages(struct address_space *mapping,
struct writeback_control *wbc)
{ … }
static int metapage_read_folio(struct file *fp, struct folio *folio)
{ … }
static bool metapage_release_folio(struct folio *folio, gfp_t gfp_mask)
{ … }
static void metapage_invalidate_folio(struct folio *folio, size_t offset,
size_t length)
{ … }
const struct address_space_operations jfs_metapage_aops = …;
struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
unsigned int size, int absolute,
unsigned long new)
{ … }
void grab_metapage(struct metapage * mp)
{ … }
static int metapage_write_one(struct folio *folio)
{ … }
void force_metapage(struct metapage *mp)
{ … }
void hold_metapage(struct metapage *mp)
{ … }
void put_metapage(struct metapage *mp)
{ … }
void release_metapage(struct metapage * mp)
{ … }
void __invalidate_metapages(struct inode *ip, s64 addr, int len)
{ … }
#ifdef CONFIG_JFS_STATISTICS
int jfs_mpstat_proc_show(struct seq_file *m, void *v)
{ … }
#endif