-
Little Leaf authored
- mkfs.ycrfs.c:文件系统格式化工具 - ycrfs.c、ycrfs.h:文件系统的内核模块实现 - Makefile:简化内核模块构建流程 - .clang-format:统一代码风格为[Linux kernel coding style]:(https://www.kernel.org/doc/html/latest/process/coding-style.html)
2c7c6f34
#include <linux/buffer_head.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mpage.h>
#include <linux/slab.h>
#include <linux/statfs.h>
#include <linux/version.h>
#include "ycrfs.h"
struct ycrfs_inode_info {
uint32_t iblock;
char i_data[32];
struct inode vfs_inode;
};
static const struct inode_operations ycrfs_inode_ops;
static const struct inode_operations ycrfs_symlink_inode_ops;
static const struct file_operations ycrfs_dir_ops;
static const struct file_operations ycrfs_file_ops;
static const struct address_space_operations ycrfs_aops;
static inline uint32_t idiv_ceil(uint32_t a, uint32_t b)
{
uint32_t ret = a / b;
if (a % b) {
return ret + 1;
}
return ret;
}
static inline uint32_t get_first_free_bits(unsigned long *freemap,
unsigned long size, uint32_t len)
{
uint32_t bit, prev = 0, count = 0;
for_each_set_bit(bit, freemap, size) {
if (prev != bit - 1) {
count = 0;
}
prev = bit;
if (++count == len) {
bitmap_clear(freemap, bit - len + 1, len);
return bit - len + 1;
}
}
return 0;
}
static inline uint32_t get_free_inode(struct ycrfs_sb_info *sbi)
{
uint32_t ret =
get_first_free_bits(sbi->bfree_bitmap, sbi->nr_blocks, 1);
if (ret) {
sbi->nr_free_inodes--;
}
return ret;
}
static inline uint32_t get_free_blocks(struct ycrfs_sb_info *sbi, uint32_t len)
{
uint32_t ret =
get_first_free_bits(sbi->bfree_bitmap, sbi->nr_blocks, len);
if (ret) {
sbi->nr_free_blocks -= len;
}
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
return ret;
}
static inline uint32_t put_free_bits(unsigned long *freemap, unsigned long size,
uint32_t i, uint32_t len)
{
if (i + len - 1 > size) {
return -1;
}
bitmap_set(freemap, i, len);
return 0;
}
static inline void put_inode(struct ycrfs_sb_info *sbi, uint32_t ino)
{
if (put_free_bits(sbi->ifree_bitmap, sbi->nr_inodes, ino, 1)) {
return;
}
sbi->nr_free_inodes++;
}
static inline void put_blocks(struct ycrfs_sb_info *sbi, uint32_t bno,
uint32_t len)
{
if (put_free_bits(sbi->ifree_bitmap, sbi->nr_blocks, bno, len)) {
return;
}
sbi->nr_free_blocks += len;
}
static struct kmem_cache *ycrfs_inode_cache;
int ycrfs_init_inode_cache(void)
{
ycrfs_inode_cache = kmem_cache_create(
"ycrfs_cache", sizeof(struct ycrfs_inode_info), 0, 0, NULL);
if (!ycrfs_inode_cache) {
return -ENOMEM;
}
return 0;
}
void ycrfs_destroy_inode_cache(void)
{
kmem_cache_destroy(ycrfs_inode_cache);
}
struct inode *ycrfs_alloc_inode(struct super_block *sb)
{
struct ycrfs_inode_info *zi =
kmem_cache_alloc(ycrfs_inode_cache, GFP_KERNEL);
if (!zi)
return NULL;
inode_init_once(&zi->vfs_inode);
return &zi->vfs_inode;
}
void ycrfs_destroy_inode(struct inode *inode)
{
struct ycrfs_inode_info *zi =
container_of(inode, struct ycrfs_inode_info, vfs_inode);
kmem_cache_free(ycrfs_inode_cache, zi);
}
static int ycrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct ycrfs_inode *disk_inode;
struct super_block *sb = inode->i_sb;