blob: 727f1c4cf18185709f24ec0ec9a1879413588f92 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2021. Huawei Technologies Co., Ltd. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* 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.
*/
#ifndef EUFS_DEF_H
#define EUFS_DEF_H
#ifndef EUFS_H
#error "Do not include euler_def.h directly. Include euler.h instead."
#endif
#include <linux/cpufeature.h>
#include <linux/processor.h>
#include <linux/types.h>
#include <linux/magic.h>
#include <linux/delay.h>
struct alloc_batch {
/* both in slots */
long size;
long n_used;
void **batch;
long n_pending;
struct list_head list;
};
struct v_dict;
enum { I_TRANS_NONE = 0, I_TRANS_AVAIL, I_TRANS_LOCKED };
struct eufs_inode_info {
struct list_head i_dep_list; /* A list of struct op_node to persist */
/* protect operations on i_dep_list */
struct mutex i_dep_lock;
struct llist_node i_persistee_node;
u32 i_next_dep_seq;
u32 i_persisted_dep_seq;
spinlock_t i_owner_lock;
struct list_head i_owner_list;
/* regular file: pmem pointer */
void __pmem *i_volatile_root;
struct v_dict *i_volatile_dict;
/*
* serialize the insertion of dependency nodes into the same
* directory by different processes or CPUs
*/
struct mutex i_header_lock;
struct mutex i_urgent_mutex;
int i_volatile_height;
u64 i_volatile_tree_blocks;
u64 i_dotdot;
/*
* a inode can only be added into a persistence list once,
* so use i_is_persisting & inode_lock to ensure that.
*/
bool i_is_persisting;
/* whether or not the inode need persistence */
bool i_is_dirty;
int i_lock_transferred;
bool hole_at_sta; /* the 0th data block is a hole */
u64 i_ext;
u16 i_version;
struct alloc_batch page_batch;
/* serialize mmap with truncate/fallocate/write/unlink */
struct rw_semaphore mmap_rwsem;
/* Protect pointers to leaf nodes (data pages) */
struct mutex i_leaf_lock;
spinlock_t i_dentry_persist_lock;
struct inode vfs_inode;
};
typedef u8 page_info_t;
struct page_wear;
/*
* EulerFS super-block data in memory
*/
struct eufs_sb_info {
struct block_device *s_bdev;
struct dax_device *s_dax_dev;
phys_addr_t phys_addr;
void __pmem *virt_addr;
struct vm_struct *vm;
unsigned long block_start;
unsigned long block_end;
void __pmem *renamej;
u64 s_crash_ver;
/* protects the SB's buffer-head */
struct mutex s_lock;
unsigned long blocksize;
unsigned long initsize;
unsigned long s_mount_opt;
atomic_t next_generation;
/* Begin of Allocator */
/* DRAM pools:
* - a single global pool
* - potected by page_lock and line_lock
* - a local pool per cpu
* - allocate/free from global pool in batch
* - no locks needed
* - a single (global) rest pool
* - when a page is used too many times, it is put into rest pool
* - cache lines are never put in rest pool
*/
spinlock_t large_lock;
spinlock_t page_lock;
spinlock_t line_lock;
struct mem_pool *gpool;
struct mem_pool *ppool; /* percpu variable */
spinlock_t rest_lock;
struct mem_pool *rest_pool;
page_info_t __pmem *page_map;
void __pmem *data_start;
u64 npages;
/* Other DRAM structures for the allcoator:
*
* - struct ptr_list_node: an unit for allocation (i.e., a page
* or a cacheline).
*
* - cached nodes: preallocated ptr_list_node for all pages, indexed by
* the page number. If the page is free, its ptr_list_node should
* be in some mem_pool.
*
* - line_node_ptrs: preallocated pointers for all pages. For each
* page, the pointer may point to an array of
* (PAGE_SIZE/CACHELINE_SIZE) ptr_list_nodes, each of which presents
* the allocation status of the corresponding cache line in the page.
* The array is dynamically allocated for memory conservation.
*
* - line_indicators: preallocated u8s for all pages. Each of the u8s
* records the number of cache lines available in global pool. This
* is used for cacheline coalescence.
*
* - page_wears: preallocated ints for all pages. Each of the ints
* records the number of writes to the page. This is used to
* coarse-grainedly show the degree of wear.
*
*/
struct ptr_list_node *cached_nodes;
struct ptr_list_node **line_node_ptrs;
u8 *line_indicators; /* Number of lines used per page! */
struct page_wear *page_wears;
/* End of Allocator */
/* Begin of Persister */
/* kmem cache for dep_node is universal defined in super.c */
struct llist_head *persistee_list; /* percpu variable */
struct task_struct **persisters;
bool *need_sync; /* for fssync */
wait_queue_head_t sync_wq; /* for fssync's thread */
struct mutex sync_mutex; /* serialize fssync request */
/* End of Persister */
/* The word `draining` is reserved for volatility quota limitation */
bool s_draining;
wait_queue_head_t s_draining_wq;
atomic_t s_nr_dirty_inodes;
atomic_t s_nr_dep_nodes;
struct mutex gather_mutex;
};
struct dir_scan_data {
struct super_block *sb;
struct dir_context *ctx;
};
typedef u64 hashlen_t;
#endif /* EUFS_DEF_H */