Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * NILFS inode file
0004  *
0005  * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
0006  *
0007  * Written by Amagai Yoshiji.
0008  * Revised by Ryusuke Konishi.
0009  *
0010  */
0011 
0012 #include <linux/types.h>
0013 #include <linux/buffer_head.h>
0014 #include "nilfs.h"
0015 #include "mdt.h"
0016 #include "alloc.h"
0017 #include "ifile.h"
0018 
0019 /**
0020  * struct nilfs_ifile_info - on-memory private data of ifile
0021  * @mi: on-memory private data of metadata file
0022  * @palloc_cache: persistent object allocator cache of ifile
0023  */
0024 struct nilfs_ifile_info {
0025     struct nilfs_mdt_info mi;
0026     struct nilfs_palloc_cache palloc_cache;
0027 };
0028 
0029 static inline struct nilfs_ifile_info *NILFS_IFILE_I(struct inode *ifile)
0030 {
0031     return (struct nilfs_ifile_info *)NILFS_MDT(ifile);
0032 }
0033 
0034 /**
0035  * nilfs_ifile_create_inode - create a new disk inode
0036  * @ifile: ifile inode
0037  * @out_ino: pointer to a variable to store inode number
0038  * @out_bh: buffer_head contains newly allocated disk inode
0039  *
0040  * Return Value: On success, 0 is returned and the newly allocated inode
0041  * number is stored in the place pointed by @ino, and buffer_head pointer
0042  * that contains newly allocated disk inode structure is stored in the
0043  * place pointed by @out_bh
0044  * On error, one of the following negative error codes is returned.
0045  *
0046  * %-EIO - I/O error.
0047  *
0048  * %-ENOMEM - Insufficient amount of memory available.
0049  *
0050  * %-ENOSPC - No inode left.
0051  */
0052 int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino,
0053                  struct buffer_head **out_bh)
0054 {
0055     struct nilfs_palloc_req req;
0056     int ret;
0057 
0058     req.pr_entry_nr = 0;  /*
0059                    * 0 says find free inode from beginning
0060                    * of a group. dull code!!
0061                    */
0062     req.pr_entry_bh = NULL;
0063 
0064     ret = nilfs_palloc_prepare_alloc_entry(ifile, &req);
0065     if (!ret) {
0066         ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 1,
0067                            &req.pr_entry_bh);
0068         if (ret < 0)
0069             nilfs_palloc_abort_alloc_entry(ifile, &req);
0070     }
0071     if (ret < 0) {
0072         brelse(req.pr_entry_bh);
0073         return ret;
0074     }
0075     nilfs_palloc_commit_alloc_entry(ifile, &req);
0076     mark_buffer_dirty(req.pr_entry_bh);
0077     nilfs_mdt_mark_dirty(ifile);
0078     *out_ino = (ino_t)req.pr_entry_nr;
0079     *out_bh = req.pr_entry_bh;
0080     return 0;
0081 }
0082 
0083 /**
0084  * nilfs_ifile_delete_inode - delete a disk inode
0085  * @ifile: ifile inode
0086  * @ino: inode number
0087  *
0088  * Return Value: On success, 0 is returned. On error, one of the following
0089  * negative error codes is returned.
0090  *
0091  * %-EIO - I/O error.
0092  *
0093  * %-ENOMEM - Insufficient amount of memory available.
0094  *
0095  * %-ENOENT - The inode number @ino have not been allocated.
0096  */
0097 int nilfs_ifile_delete_inode(struct inode *ifile, ino_t ino)
0098 {
0099     struct nilfs_palloc_req req = {
0100         .pr_entry_nr = ino, .pr_entry_bh = NULL
0101     };
0102     struct nilfs_inode *raw_inode;
0103     void *kaddr;
0104     int ret;
0105 
0106     ret = nilfs_palloc_prepare_free_entry(ifile, &req);
0107     if (!ret) {
0108         ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 0,
0109                            &req.pr_entry_bh);
0110         if (ret < 0)
0111             nilfs_palloc_abort_free_entry(ifile, &req);
0112     }
0113     if (ret < 0) {
0114         brelse(req.pr_entry_bh);
0115         return ret;
0116     }
0117 
0118     kaddr = kmap_atomic(req.pr_entry_bh->b_page);
0119     raw_inode = nilfs_palloc_block_get_entry(ifile, req.pr_entry_nr,
0120                          req.pr_entry_bh, kaddr);
0121     raw_inode->i_flags = 0;
0122     kunmap_atomic(kaddr);
0123 
0124     mark_buffer_dirty(req.pr_entry_bh);
0125     brelse(req.pr_entry_bh);
0126 
0127     nilfs_palloc_commit_free_entry(ifile, &req);
0128 
0129     return 0;
0130 }
0131 
0132 int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino,
0133                 struct buffer_head **out_bh)
0134 {
0135     struct super_block *sb = ifile->i_sb;
0136     int err;
0137 
0138     if (unlikely(!NILFS_VALID_INODE(sb, ino))) {
0139         nilfs_error(sb, "bad inode number: %lu", (unsigned long)ino);
0140         return -EINVAL;
0141     }
0142 
0143     err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh);
0144     if (unlikely(err))
0145         nilfs_warn(sb, "error %d reading inode: ino=%lu",
0146                err, (unsigned long)ino);
0147     return err;
0148 }
0149 
0150 /**
0151  * nilfs_ifile_count_free_inodes - calculate free inodes count
0152  * @ifile: ifile inode
0153  * @nmaxinodes: current maximum of available inodes count [out]
0154  * @nfreeinodes: free inodes count [out]
0155  */
0156 int nilfs_ifile_count_free_inodes(struct inode *ifile,
0157                     u64 *nmaxinodes, u64 *nfreeinodes)
0158 {
0159     u64 nused;
0160     int err;
0161 
0162     *nmaxinodes = 0;
0163     *nfreeinodes = 0;
0164 
0165     nused = atomic64_read(&NILFS_I(ifile)->i_root->inodes_count);
0166     err = nilfs_palloc_count_max_entries(ifile, nused, nmaxinodes);
0167     if (likely(!err))
0168         *nfreeinodes = *nmaxinodes - nused;
0169     return err;
0170 }
0171 
0172 /**
0173  * nilfs_ifile_read - read or get ifile inode
0174  * @sb: super block instance
0175  * @root: root object
0176  * @inode_size: size of an inode
0177  * @raw_inode: on-disk ifile inode
0178  * @inodep: buffer to store the inode
0179  */
0180 int nilfs_ifile_read(struct super_block *sb, struct nilfs_root *root,
0181              size_t inode_size, struct nilfs_inode *raw_inode,
0182              struct inode **inodep)
0183 {
0184     struct inode *ifile;
0185     int err;
0186 
0187     ifile = nilfs_iget_locked(sb, root, NILFS_IFILE_INO);
0188     if (unlikely(!ifile))
0189         return -ENOMEM;
0190     if (!(ifile->i_state & I_NEW))
0191         goto out;
0192 
0193     err = nilfs_mdt_init(ifile, NILFS_MDT_GFP,
0194                  sizeof(struct nilfs_ifile_info));
0195     if (err)
0196         goto failed;
0197 
0198     err = nilfs_palloc_init_blockgroup(ifile, inode_size);
0199     if (err)
0200         goto failed;
0201 
0202     nilfs_palloc_setup_cache(ifile, &NILFS_IFILE_I(ifile)->palloc_cache);
0203 
0204     err = nilfs_read_inode_common(ifile, raw_inode);
0205     if (err)
0206         goto failed;
0207 
0208     unlock_new_inode(ifile);
0209  out:
0210     *inodep = ifile;
0211     return 0;
0212  failed:
0213     iget_failed(ifile);
0214     return err;
0215 }