linux/fs/nilfs2/ifile.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * ifile.c - 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_msg(sb, KERN_WARNING, "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}
 216