cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

inode.c (12116B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *	fs/bfs/inode.c
      4 *	BFS superblock and inode operations.
      5 *	Copyright (C) 1999-2018 Tigran Aivazian <aivazian.tigran@gmail.com>
      6 *	From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds.
      7 *	Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005.
      8 */
      9
     10#include <linux/module.h>
     11#include <linux/mm.h>
     12#include <linux/slab.h>
     13#include <linux/init.h>
     14#include <linux/fs.h>
     15#include <linux/buffer_head.h>
     16#include <linux/vfs.h>
     17#include <linux/writeback.h>
     18#include <linux/uio.h>
     19#include <linux/uaccess.h>
     20#include "bfs.h"
     21
     22MODULE_AUTHOR("Tigran Aivazian <aivazian.tigran@gmail.com>");
     23MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux");
     24MODULE_LICENSE("GPL");
     25
     26#undef DEBUG
     27
     28#ifdef DEBUG
     29#define dprintf(x...)	printf(x)
     30#else
     31#define dprintf(x...)
     32#endif
     33
     34struct inode *bfs_iget(struct super_block *sb, unsigned long ino)
     35{
     36	struct bfs_inode *di;
     37	struct inode *inode;
     38	struct buffer_head *bh;
     39	int block, off;
     40
     41	inode = iget_locked(sb, ino);
     42	if (!inode)
     43		return ERR_PTR(-ENOMEM);
     44	if (!(inode->i_state & I_NEW))
     45		return inode;
     46
     47	if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(inode->i_sb)->si_lasti)) {
     48		printf("Bad inode number %s:%08lx\n", inode->i_sb->s_id, ino);
     49		goto error;
     50	}
     51
     52	block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
     53	bh = sb_bread(inode->i_sb, block);
     54	if (!bh) {
     55		printf("Unable to read inode %s:%08lx\n", inode->i_sb->s_id,
     56									ino);
     57		goto error;
     58	}
     59
     60	off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
     61	di = (struct bfs_inode *)bh->b_data + off;
     62
     63	inode->i_mode = 0x0000FFFF & le32_to_cpu(di->i_mode);
     64	if (le32_to_cpu(di->i_vtype) == BFS_VDIR) {
     65		inode->i_mode |= S_IFDIR;
     66		inode->i_op = &bfs_dir_inops;
     67		inode->i_fop = &bfs_dir_operations;
     68	} else if (le32_to_cpu(di->i_vtype) == BFS_VREG) {
     69		inode->i_mode |= S_IFREG;
     70		inode->i_op = &bfs_file_inops;
     71		inode->i_fop = &bfs_file_operations;
     72		inode->i_mapping->a_ops = &bfs_aops;
     73	}
     74
     75	BFS_I(inode)->i_sblock =  le32_to_cpu(di->i_sblock);
     76	BFS_I(inode)->i_eblock =  le32_to_cpu(di->i_eblock);
     77	BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino);
     78	i_uid_write(inode, le32_to_cpu(di->i_uid));
     79	i_gid_write(inode,  le32_to_cpu(di->i_gid));
     80	set_nlink(inode, le32_to_cpu(di->i_nlink));
     81	inode->i_size = BFS_FILESIZE(di);
     82	inode->i_blocks = BFS_FILEBLOCKS(di);
     83	inode->i_atime.tv_sec =  le32_to_cpu(di->i_atime);
     84	inode->i_mtime.tv_sec =  le32_to_cpu(di->i_mtime);
     85	inode->i_ctime.tv_sec =  le32_to_cpu(di->i_ctime);
     86	inode->i_atime.tv_nsec = 0;
     87	inode->i_mtime.tv_nsec = 0;
     88	inode->i_ctime.tv_nsec = 0;
     89
     90	brelse(bh);
     91	unlock_new_inode(inode);
     92	return inode;
     93
     94error:
     95	iget_failed(inode);
     96	return ERR_PTR(-EIO);
     97}
     98
     99static struct bfs_inode *find_inode(struct super_block *sb, u16 ino, struct buffer_head **p)
    100{
    101	if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(sb)->si_lasti)) {
    102		printf("Bad inode number %s:%08x\n", sb->s_id, ino);
    103		return ERR_PTR(-EIO);
    104	}
    105
    106	ino -= BFS_ROOT_INO;
    107
    108	*p = sb_bread(sb, 1 + ino / BFS_INODES_PER_BLOCK);
    109	if (!*p) {
    110		printf("Unable to read inode %s:%08x\n", sb->s_id, ino);
    111		return ERR_PTR(-EIO);
    112	}
    113
    114	return (struct bfs_inode *)(*p)->b_data +  ino % BFS_INODES_PER_BLOCK;
    115}
    116
    117static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc)
    118{
    119	struct bfs_sb_info *info = BFS_SB(inode->i_sb);
    120	unsigned int ino = (u16)inode->i_ino;
    121	unsigned long i_sblock;
    122	struct bfs_inode *di;
    123	struct buffer_head *bh;
    124	int err = 0;
    125
    126	dprintf("ino=%08x\n", ino);
    127
    128	di = find_inode(inode->i_sb, ino, &bh);
    129	if (IS_ERR(di))
    130		return PTR_ERR(di);
    131
    132	mutex_lock(&info->bfs_lock);
    133
    134	if (ino == BFS_ROOT_INO)
    135		di->i_vtype = cpu_to_le32(BFS_VDIR);
    136	else
    137		di->i_vtype = cpu_to_le32(BFS_VREG);
    138
    139	di->i_ino = cpu_to_le16(ino);
    140	di->i_mode = cpu_to_le32(inode->i_mode);
    141	di->i_uid = cpu_to_le32(i_uid_read(inode));
    142	di->i_gid = cpu_to_le32(i_gid_read(inode));
    143	di->i_nlink = cpu_to_le32(inode->i_nlink);
    144	di->i_atime = cpu_to_le32(inode->i_atime.tv_sec);
    145	di->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec);
    146	di->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);
    147	i_sblock = BFS_I(inode)->i_sblock;
    148	di->i_sblock = cpu_to_le32(i_sblock);
    149	di->i_eblock = cpu_to_le32(BFS_I(inode)->i_eblock);
    150	di->i_eoffset = cpu_to_le32(i_sblock * BFS_BSIZE + inode->i_size - 1);
    151
    152	mark_buffer_dirty(bh);
    153	if (wbc->sync_mode == WB_SYNC_ALL) {
    154		sync_dirty_buffer(bh);
    155		if (buffer_req(bh) && !buffer_uptodate(bh))
    156			err = -EIO;
    157	}
    158	brelse(bh);
    159	mutex_unlock(&info->bfs_lock);
    160	return err;
    161}
    162
    163static void bfs_evict_inode(struct inode *inode)
    164{
    165	unsigned long ino = inode->i_ino;
    166	struct bfs_inode *di;
    167	struct buffer_head *bh;
    168	struct super_block *s = inode->i_sb;
    169	struct bfs_sb_info *info = BFS_SB(s);
    170	struct bfs_inode_info *bi = BFS_I(inode);
    171
    172	dprintf("ino=%08lx\n", ino);
    173
    174	truncate_inode_pages_final(&inode->i_data);
    175	invalidate_inode_buffers(inode);
    176	clear_inode(inode);
    177
    178	if (inode->i_nlink)
    179		return;
    180
    181	di = find_inode(s, inode->i_ino, &bh);
    182	if (IS_ERR(di))
    183		return;
    184
    185	mutex_lock(&info->bfs_lock);
    186	/* clear on-disk inode */
    187	memset(di, 0, sizeof(struct bfs_inode));
    188	mark_buffer_dirty(bh);
    189	brelse(bh);
    190
    191	if (bi->i_dsk_ino) {
    192		if (bi->i_sblock)
    193			info->si_freeb += bi->i_eblock + 1 - bi->i_sblock;
    194		info->si_freei++;
    195		clear_bit(ino, info->si_imap);
    196		bfs_dump_imap("evict_inode", s);
    197	}
    198
    199	/*
    200	 * If this was the last file, make the previous block
    201	 * "last block of the last file" even if there is no
    202	 * real file there, saves us 1 gap.
    203	 */
    204	if (info->si_lf_eblk == bi->i_eblock)
    205		info->si_lf_eblk = bi->i_sblock - 1;
    206	mutex_unlock(&info->bfs_lock);
    207}
    208
    209static void bfs_put_super(struct super_block *s)
    210{
    211	struct bfs_sb_info *info = BFS_SB(s);
    212
    213	if (!info)
    214		return;
    215
    216	mutex_destroy(&info->bfs_lock);
    217	kfree(info);
    218	s->s_fs_info = NULL;
    219}
    220
    221static int bfs_statfs(struct dentry *dentry, struct kstatfs *buf)
    222{
    223	struct super_block *s = dentry->d_sb;
    224	struct bfs_sb_info *info = BFS_SB(s);
    225	u64 id = huge_encode_dev(s->s_bdev->bd_dev);
    226	buf->f_type = BFS_MAGIC;
    227	buf->f_bsize = s->s_blocksize;
    228	buf->f_blocks = info->si_blocks;
    229	buf->f_bfree = buf->f_bavail = info->si_freeb;
    230	buf->f_files = info->si_lasti + 1 - BFS_ROOT_INO;
    231	buf->f_ffree = info->si_freei;
    232	buf->f_fsid = u64_to_fsid(id);
    233	buf->f_namelen = BFS_NAMELEN;
    234	return 0;
    235}
    236
    237static struct kmem_cache *bfs_inode_cachep;
    238
    239static struct inode *bfs_alloc_inode(struct super_block *sb)
    240{
    241	struct bfs_inode_info *bi;
    242	bi = alloc_inode_sb(sb, bfs_inode_cachep, GFP_KERNEL);
    243	if (!bi)
    244		return NULL;
    245	return &bi->vfs_inode;
    246}
    247
    248static void bfs_free_inode(struct inode *inode)
    249{
    250	kmem_cache_free(bfs_inode_cachep, BFS_I(inode));
    251}
    252
    253static void init_once(void *foo)
    254{
    255	struct bfs_inode_info *bi = foo;
    256
    257	inode_init_once(&bi->vfs_inode);
    258}
    259
    260static int __init init_inodecache(void)
    261{
    262	bfs_inode_cachep = kmem_cache_create("bfs_inode_cache",
    263					     sizeof(struct bfs_inode_info),
    264					     0, (SLAB_RECLAIM_ACCOUNT|
    265						SLAB_MEM_SPREAD|SLAB_ACCOUNT),
    266					     init_once);
    267	if (bfs_inode_cachep == NULL)
    268		return -ENOMEM;
    269	return 0;
    270}
    271
    272static void destroy_inodecache(void)
    273{
    274	/*
    275	 * Make sure all delayed rcu free inodes are flushed before we
    276	 * destroy cache.
    277	 */
    278	rcu_barrier();
    279	kmem_cache_destroy(bfs_inode_cachep);
    280}
    281
    282static const struct super_operations bfs_sops = {
    283	.alloc_inode	= bfs_alloc_inode,
    284	.free_inode	= bfs_free_inode,
    285	.write_inode	= bfs_write_inode,
    286	.evict_inode	= bfs_evict_inode,
    287	.put_super	= bfs_put_super,
    288	.statfs		= bfs_statfs,
    289};
    290
    291void bfs_dump_imap(const char *prefix, struct super_block *s)
    292{
    293#ifdef DEBUG
    294	int i;
    295	char *tmpbuf = (char *)get_zeroed_page(GFP_KERNEL);
    296
    297	if (!tmpbuf)
    298		return;
    299	for (i = BFS_SB(s)->si_lasti; i >= 0; i--) {
    300		if (i > PAGE_SIZE - 100) break;
    301		if (test_bit(i, BFS_SB(s)->si_imap))
    302			strcat(tmpbuf, "1");
    303		else
    304			strcat(tmpbuf, "0");
    305	}
    306	printf("%s: lasti=%08lx <%s>\n", prefix, BFS_SB(s)->si_lasti, tmpbuf);
    307	free_page((unsigned long)tmpbuf);
    308#endif
    309}
    310
    311static int bfs_fill_super(struct super_block *s, void *data, int silent)
    312{
    313	struct buffer_head *bh, *sbh;
    314	struct bfs_super_block *bfs_sb;
    315	struct inode *inode;
    316	unsigned i;
    317	struct bfs_sb_info *info;
    318	int ret = -EINVAL;
    319	unsigned long i_sblock, i_eblock, i_eoff, s_size;
    320
    321	info = kzalloc(sizeof(*info), GFP_KERNEL);
    322	if (!info)
    323		return -ENOMEM;
    324	mutex_init(&info->bfs_lock);
    325	s->s_fs_info = info;
    326	s->s_time_min = 0;
    327	s->s_time_max = U32_MAX;
    328
    329	sb_set_blocksize(s, BFS_BSIZE);
    330
    331	sbh = sb_bread(s, 0);
    332	if (!sbh)
    333		goto out;
    334	bfs_sb = (struct bfs_super_block *)sbh->b_data;
    335	if (le32_to_cpu(bfs_sb->s_magic) != BFS_MAGIC) {
    336		if (!silent)
    337			printf("No BFS filesystem on %s (magic=%08x)\n", s->s_id,  le32_to_cpu(bfs_sb->s_magic));
    338		goto out1;
    339	}
    340	if (BFS_UNCLEAN(bfs_sb, s) && !silent)
    341		printf("%s is unclean, continuing\n", s->s_id);
    342
    343	s->s_magic = BFS_MAGIC;
    344
    345	if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end) ||
    346	    le32_to_cpu(bfs_sb->s_start) < sizeof(struct bfs_super_block) + sizeof(struct bfs_dirent)) {
    347		printf("Superblock is corrupted on %s\n", s->s_id);
    348		goto out1;
    349	}
    350
    351	info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) / sizeof(struct bfs_inode) + BFS_ROOT_INO - 1;
    352	if (info->si_lasti == BFS_MAX_LASTI)
    353		printf("NOTE: filesystem %s was created with 512 inodes, the real maximum is 511, mounting anyway\n", s->s_id);
    354	else if (info->si_lasti > BFS_MAX_LASTI) {
    355		printf("Impossible last inode number %lu > %d on %s\n", info->si_lasti, BFS_MAX_LASTI, s->s_id);
    356		goto out1;
    357	}
    358	for (i = 0; i < BFS_ROOT_INO; i++)
    359		set_bit(i, info->si_imap);
    360
    361	s->s_op = &bfs_sops;
    362	inode = bfs_iget(s, BFS_ROOT_INO);
    363	if (IS_ERR(inode)) {
    364		ret = PTR_ERR(inode);
    365		goto out1;
    366	}
    367	s->s_root = d_make_root(inode);
    368	if (!s->s_root) {
    369		ret = -ENOMEM;
    370		goto out1;
    371	}
    372
    373	info->si_blocks = (le32_to_cpu(bfs_sb->s_end) + 1) >> BFS_BSIZE_BITS;
    374	info->si_freeb = (le32_to_cpu(bfs_sb->s_end) + 1 - le32_to_cpu(bfs_sb->s_start)) >> BFS_BSIZE_BITS;
    375	info->si_freei = 0;
    376	info->si_lf_eblk = 0;
    377
    378	/* can we read the last block? */
    379	bh = sb_bread(s, info->si_blocks - 1);
    380	if (!bh) {
    381		printf("Last block not available on %s: %lu\n", s->s_id, info->si_blocks - 1);
    382		ret = -EIO;
    383		goto out2;
    384	}
    385	brelse(bh);
    386
    387	bh = NULL;
    388	for (i = BFS_ROOT_INO; i <= info->si_lasti; i++) {
    389		struct bfs_inode *di;
    390		int block = (i - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
    391		int off = (i - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
    392		unsigned long eblock;
    393
    394		if (!off) {
    395			brelse(bh);
    396			bh = sb_bread(s, block);
    397		}
    398
    399		if (!bh)
    400			continue;
    401
    402		di = (struct bfs_inode *)bh->b_data + off;
    403
    404		/* test if filesystem is not corrupted */
    405
    406		i_eoff = le32_to_cpu(di->i_eoffset);
    407		i_sblock = le32_to_cpu(di->i_sblock);
    408		i_eblock = le32_to_cpu(di->i_eblock);
    409		s_size = le32_to_cpu(bfs_sb->s_end);
    410
    411		if (i_sblock > info->si_blocks ||
    412			i_eblock > info->si_blocks ||
    413			i_sblock > i_eblock ||
    414			(i_eoff != le32_to_cpu(-1) && i_eoff > s_size) ||
    415			i_sblock * BFS_BSIZE > i_eoff) {
    416
    417			printf("Inode 0x%08x corrupted on %s\n", i, s->s_id);
    418
    419			brelse(bh);
    420			ret = -EIO;
    421			goto out2;
    422		}
    423
    424		if (!di->i_ino) {
    425			info->si_freei++;
    426			continue;
    427		}
    428		set_bit(i, info->si_imap);
    429		info->si_freeb -= BFS_FILEBLOCKS(di);
    430
    431		eblock =  le32_to_cpu(di->i_eblock);
    432		if (eblock > info->si_lf_eblk)
    433			info->si_lf_eblk = eblock;
    434	}
    435	brelse(bh);
    436	brelse(sbh);
    437	bfs_dump_imap("fill_super", s);
    438	return 0;
    439
    440out2:
    441	dput(s->s_root);
    442	s->s_root = NULL;
    443out1:
    444	brelse(sbh);
    445out:
    446	mutex_destroy(&info->bfs_lock);
    447	kfree(info);
    448	s->s_fs_info = NULL;
    449	return ret;
    450}
    451
    452static struct dentry *bfs_mount(struct file_system_type *fs_type,
    453	int flags, const char *dev_name, void *data)
    454{
    455	return mount_bdev(fs_type, flags, dev_name, data, bfs_fill_super);
    456}
    457
    458static struct file_system_type bfs_fs_type = {
    459	.owner		= THIS_MODULE,
    460	.name		= "bfs",
    461	.mount		= bfs_mount,
    462	.kill_sb	= kill_block_super,
    463	.fs_flags	= FS_REQUIRES_DEV,
    464};
    465MODULE_ALIAS_FS("bfs");
    466
    467static int __init init_bfs_fs(void)
    468{
    469	int err = init_inodecache();
    470	if (err)
    471		goto out1;
    472	err = register_filesystem(&bfs_fs_type);
    473	if (err)
    474		goto out;
    475	return 0;
    476out:
    477	destroy_inodecache();
    478out1:
    479	return err;
    480}
    481
    482static void __exit exit_bfs_fs(void)
    483{
    484	unregister_filesystem(&bfs_fs_type);
    485	destroy_inodecache();
    486}
    487
    488module_init(init_bfs_fs)
    489module_exit(exit_bfs_fs)