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