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

ifile.c (5334B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * NILFS inode file
      4 *
      5 * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
      6 *
      7 * Written by Amagai Yoshiji.
      8 * Revised by Ryusuke Konishi.
      9 *
     10 */
     11
     12#include <linux/types.h>
     13#include <linux/buffer_head.h>
     14#include "nilfs.h"
     15#include "mdt.h"
     16#include "alloc.h"
     17#include "ifile.h"
     18
     19/**
     20 * struct nilfs_ifile_info - on-memory private data of ifile
     21 * @mi: on-memory private data of metadata file
     22 * @palloc_cache: persistent object allocator cache of ifile
     23 */
     24struct nilfs_ifile_info {
     25	struct nilfs_mdt_info mi;
     26	struct nilfs_palloc_cache palloc_cache;
     27};
     28
     29static inline struct nilfs_ifile_info *NILFS_IFILE_I(struct inode *ifile)
     30{
     31	return (struct nilfs_ifile_info *)NILFS_MDT(ifile);
     32}
     33
     34/**
     35 * nilfs_ifile_create_inode - create a new disk inode
     36 * @ifile: ifile inode
     37 * @out_ino: pointer to a variable to store inode number
     38 * @out_bh: buffer_head contains newly allocated disk inode
     39 *
     40 * Return Value: On success, 0 is returned and the newly allocated inode
     41 * number is stored in the place pointed by @ino, and buffer_head pointer
     42 * that contains newly allocated disk inode structure is stored in the
     43 * place pointed by @out_bh
     44 * On error, one of the following negative error codes is returned.
     45 *
     46 * %-EIO - I/O error.
     47 *
     48 * %-ENOMEM - Insufficient amount of memory available.
     49 *
     50 * %-ENOSPC - No inode left.
     51 */
     52int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino,
     53			     struct buffer_head **out_bh)
     54{
     55	struct nilfs_palloc_req req;
     56	int ret;
     57
     58	req.pr_entry_nr = 0;  /*
     59			       * 0 says find free inode from beginning
     60			       * of a group. dull code!!
     61			       */
     62	req.pr_entry_bh = NULL;
     63
     64	ret = nilfs_palloc_prepare_alloc_entry(ifile, &req);
     65	if (!ret) {
     66		ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 1,
     67						   &req.pr_entry_bh);
     68		if (ret < 0)
     69			nilfs_palloc_abort_alloc_entry(ifile, &req);
     70	}
     71	if (ret < 0) {
     72		brelse(req.pr_entry_bh);
     73		return ret;
     74	}
     75	nilfs_palloc_commit_alloc_entry(ifile, &req);
     76	mark_buffer_dirty(req.pr_entry_bh);
     77	nilfs_mdt_mark_dirty(ifile);
     78	*out_ino = (ino_t)req.pr_entry_nr;
     79	*out_bh = req.pr_entry_bh;
     80	return 0;
     81}
     82
     83/**
     84 * nilfs_ifile_delete_inode - delete a disk inode
     85 * @ifile: ifile inode
     86 * @ino: inode number
     87 *
     88 * Return Value: On success, 0 is returned. On error, one of the following
     89 * negative error codes is returned.
     90 *
     91 * %-EIO - I/O error.
     92 *
     93 * %-ENOMEM - Insufficient amount of memory available.
     94 *
     95 * %-ENOENT - The inode number @ino have not been allocated.
     96 */
     97int nilfs_ifile_delete_inode(struct inode *ifile, ino_t ino)
     98{
     99	struct nilfs_palloc_req req = {
    100		.pr_entry_nr = ino, .pr_entry_bh = NULL
    101	};
    102	struct nilfs_inode *raw_inode;
    103	void *kaddr;
    104	int ret;
    105
    106	ret = nilfs_palloc_prepare_free_entry(ifile, &req);
    107	if (!ret) {
    108		ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 0,
    109						   &req.pr_entry_bh);
    110		if (ret < 0)
    111			nilfs_palloc_abort_free_entry(ifile, &req);
    112	}
    113	if (ret < 0) {
    114		brelse(req.pr_entry_bh);
    115		return ret;
    116	}
    117
    118	kaddr = kmap_atomic(req.pr_entry_bh->b_page);
    119	raw_inode = nilfs_palloc_block_get_entry(ifile, req.pr_entry_nr,
    120						 req.pr_entry_bh, kaddr);
    121	raw_inode->i_flags = 0;
    122	kunmap_atomic(kaddr);
    123
    124	mark_buffer_dirty(req.pr_entry_bh);
    125	brelse(req.pr_entry_bh);
    126
    127	nilfs_palloc_commit_free_entry(ifile, &req);
    128
    129	return 0;
    130}
    131
    132int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino,
    133				struct buffer_head **out_bh)
    134{
    135	struct super_block *sb = ifile->i_sb;
    136	int err;
    137
    138	if (unlikely(!NILFS_VALID_INODE(sb, ino))) {
    139		nilfs_error(sb, "bad inode number: %lu", (unsigned long)ino);
    140		return -EINVAL;
    141	}
    142
    143	err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh);
    144	if (unlikely(err))
    145		nilfs_warn(sb, "error %d reading inode: ino=%lu",
    146			   err, (unsigned long)ino);
    147	return err;
    148}
    149
    150/**
    151 * nilfs_ifile_count_free_inodes - calculate free inodes count
    152 * @ifile: ifile inode
    153 * @nmaxinodes: current maximum of available inodes count [out]
    154 * @nfreeinodes: free inodes count [out]
    155 */
    156int nilfs_ifile_count_free_inodes(struct inode *ifile,
    157				    u64 *nmaxinodes, u64 *nfreeinodes)
    158{
    159	u64 nused;
    160	int err;
    161
    162	*nmaxinodes = 0;
    163	*nfreeinodes = 0;
    164
    165	nused = atomic64_read(&NILFS_I(ifile)->i_root->inodes_count);
    166	err = nilfs_palloc_count_max_entries(ifile, nused, nmaxinodes);
    167	if (likely(!err))
    168		*nfreeinodes = *nmaxinodes - nused;
    169	return err;
    170}
    171
    172/**
    173 * nilfs_ifile_read - read or get ifile inode
    174 * @sb: super block instance
    175 * @root: root object
    176 * @inode_size: size of an inode
    177 * @raw_inode: on-disk ifile inode
    178 * @inodep: buffer to store the inode
    179 */
    180int nilfs_ifile_read(struct super_block *sb, struct nilfs_root *root,
    181		     size_t inode_size, struct nilfs_inode *raw_inode,
    182		     struct inode **inodep)
    183{
    184	struct inode *ifile;
    185	int err;
    186
    187	ifile = nilfs_iget_locked(sb, root, NILFS_IFILE_INO);
    188	if (unlikely(!ifile))
    189		return -ENOMEM;
    190	if (!(ifile->i_state & I_NEW))
    191		goto out;
    192
    193	err = nilfs_mdt_init(ifile, NILFS_MDT_GFP,
    194			     sizeof(struct nilfs_ifile_info));
    195	if (err)
    196		goto failed;
    197
    198	err = nilfs_palloc_init_blockgroup(ifile, inode_size);
    199	if (err)
    200		goto failed;
    201
    202	nilfs_palloc_setup_cache(ifile, &NILFS_IFILE_I(ifile)->palloc_cache);
    203
    204	err = nilfs_read_inode_common(ifile, raw_inode);
    205	if (err)
    206		goto failed;
    207
    208	unlock_new_inode(ifile);
    209 out:
    210	*inodep = ifile;
    211	return 0;
    212 failed:
    213	iget_failed(ifile);
    214	return err;
    215}