1ae98043fSRyusuke Konishi // SPDX-License-Identifier: GPL-2.0+
243bfb45eSRyusuke Konishi /*
394ee1d91SRyusuke Konishi * NILFS inode file
443bfb45eSRyusuke Konishi *
543bfb45eSRyusuke Konishi * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
643bfb45eSRyusuke Konishi *
74b420ab4SRyusuke Konishi * Written by Amagai Yoshiji.
84b420ab4SRyusuke Konishi * Revised by Ryusuke Konishi.
943bfb45eSRyusuke Konishi *
1043bfb45eSRyusuke Konishi */
1143bfb45eSRyusuke Konishi
1243bfb45eSRyusuke Konishi #include <linux/types.h>
1343bfb45eSRyusuke Konishi #include <linux/buffer_head.h>
1443bfb45eSRyusuke Konishi #include "nilfs.h"
1543bfb45eSRyusuke Konishi #include "mdt.h"
1643bfb45eSRyusuke Konishi #include "alloc.h"
1743bfb45eSRyusuke Konishi #include "ifile.h"
1843bfb45eSRyusuke Konishi
19f5974c8fSVyacheslav Dubeyko /**
20f5974c8fSVyacheslav Dubeyko * struct nilfs_ifile_info - on-memory private data of ifile
21f5974c8fSVyacheslav Dubeyko * @mi: on-memory private data of metadata file
22f5974c8fSVyacheslav Dubeyko * @palloc_cache: persistent object allocator cache of ifile
23f5974c8fSVyacheslav Dubeyko */
2449fa7a59SRyusuke Konishi struct nilfs_ifile_info {
2549fa7a59SRyusuke Konishi struct nilfs_mdt_info mi;
2649fa7a59SRyusuke Konishi struct nilfs_palloc_cache palloc_cache;
2749fa7a59SRyusuke Konishi };
2849fa7a59SRyusuke Konishi
NILFS_IFILE_I(struct inode * ifile)2949fa7a59SRyusuke Konishi static inline struct nilfs_ifile_info *NILFS_IFILE_I(struct inode *ifile)
3049fa7a59SRyusuke Konishi {
3149fa7a59SRyusuke Konishi return (struct nilfs_ifile_info *)NILFS_MDT(ifile);
3249fa7a59SRyusuke Konishi }
3349fa7a59SRyusuke Konishi
3443bfb45eSRyusuke Konishi /**
3543bfb45eSRyusuke Konishi * nilfs_ifile_create_inode - create a new disk inode
3643bfb45eSRyusuke Konishi * @ifile: ifile inode
3743bfb45eSRyusuke Konishi * @out_ino: pointer to a variable to store inode number
3843bfb45eSRyusuke Konishi * @out_bh: buffer_head contains newly allocated disk inode
3943bfb45eSRyusuke Konishi *
4043bfb45eSRyusuke Konishi * Return Value: On success, 0 is returned and the newly allocated inode
4143bfb45eSRyusuke Konishi * number is stored in the place pointed by @ino, and buffer_head pointer
4243bfb45eSRyusuke Konishi * that contains newly allocated disk inode structure is stored in the
4343bfb45eSRyusuke Konishi * place pointed by @out_bh
4443bfb45eSRyusuke Konishi * On error, one of the following negative error codes is returned.
4543bfb45eSRyusuke Konishi *
4643bfb45eSRyusuke Konishi * %-EIO - I/O error.
4743bfb45eSRyusuke Konishi *
4843bfb45eSRyusuke Konishi * %-ENOMEM - Insufficient amount of memory available.
4943bfb45eSRyusuke Konishi *
5043bfb45eSRyusuke Konishi * %-ENOSPC - No inode left.
5143bfb45eSRyusuke Konishi */
nilfs_ifile_create_inode(struct inode * ifile,ino_t * out_ino,struct buffer_head ** out_bh)5243bfb45eSRyusuke Konishi int nilfs_ifile_create_inode(struct inode *ifile, ino_t *out_ino,
5343bfb45eSRyusuke Konishi struct buffer_head **out_bh)
5443bfb45eSRyusuke Konishi {
5543bfb45eSRyusuke Konishi struct nilfs_palloc_req req;
5643bfb45eSRyusuke Konishi int ret;
5743bfb45eSRyusuke Konishi
58*95b13625SRyusuke Konishi req.pr_entry_nr = NILFS_FIRST_INO(ifile->i_sb);
5943bfb45eSRyusuke Konishi req.pr_entry_bh = NULL;
6043bfb45eSRyusuke Konishi
61*95b13625SRyusuke Konishi ret = nilfs_palloc_prepare_alloc_entry(ifile, &req, false);
6243bfb45eSRyusuke Konishi if (!ret) {
6343bfb45eSRyusuke Konishi ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 1,
6443bfb45eSRyusuke Konishi &req.pr_entry_bh);
6543bfb45eSRyusuke Konishi if (ret < 0)
6643bfb45eSRyusuke Konishi nilfs_palloc_abort_alloc_entry(ifile, &req);
6743bfb45eSRyusuke Konishi }
6843bfb45eSRyusuke Konishi if (ret < 0) {
6943bfb45eSRyusuke Konishi brelse(req.pr_entry_bh);
7043bfb45eSRyusuke Konishi return ret;
7143bfb45eSRyusuke Konishi }
7243bfb45eSRyusuke Konishi nilfs_palloc_commit_alloc_entry(ifile, &req);
735fc7b141SRyusuke Konishi mark_buffer_dirty(req.pr_entry_bh);
7443bfb45eSRyusuke Konishi nilfs_mdt_mark_dirty(ifile);
7543bfb45eSRyusuke Konishi *out_ino = (ino_t)req.pr_entry_nr;
7643bfb45eSRyusuke Konishi *out_bh = req.pr_entry_bh;
7743bfb45eSRyusuke Konishi return 0;
7843bfb45eSRyusuke Konishi }
7943bfb45eSRyusuke Konishi
8043bfb45eSRyusuke Konishi /**
8143bfb45eSRyusuke Konishi * nilfs_ifile_delete_inode - delete a disk inode
8243bfb45eSRyusuke Konishi * @ifile: ifile inode
8343bfb45eSRyusuke Konishi * @ino: inode number
8443bfb45eSRyusuke Konishi *
8543bfb45eSRyusuke Konishi * Return Value: On success, 0 is returned. On error, one of the following
8643bfb45eSRyusuke Konishi * negative error codes is returned.
8743bfb45eSRyusuke Konishi *
8843bfb45eSRyusuke Konishi * %-EIO - I/O error.
8943bfb45eSRyusuke Konishi *
9043bfb45eSRyusuke Konishi * %-ENOMEM - Insufficient amount of memory available.
9143bfb45eSRyusuke Konishi *
9243bfb45eSRyusuke Konishi * %-ENOENT - The inode number @ino have not been allocated.
9343bfb45eSRyusuke Konishi */
nilfs_ifile_delete_inode(struct inode * ifile,ino_t ino)9443bfb45eSRyusuke Konishi int nilfs_ifile_delete_inode(struct inode *ifile, ino_t ino)
9543bfb45eSRyusuke Konishi {
9643bfb45eSRyusuke Konishi struct nilfs_palloc_req req = {
9743bfb45eSRyusuke Konishi .pr_entry_nr = ino, .pr_entry_bh = NULL
9843bfb45eSRyusuke Konishi };
9943bfb45eSRyusuke Konishi struct nilfs_inode *raw_inode;
10043bfb45eSRyusuke Konishi void *kaddr;
10143bfb45eSRyusuke Konishi int ret;
10243bfb45eSRyusuke Konishi
10343bfb45eSRyusuke Konishi ret = nilfs_palloc_prepare_free_entry(ifile, &req);
10443bfb45eSRyusuke Konishi if (!ret) {
10543bfb45eSRyusuke Konishi ret = nilfs_palloc_get_entry_block(ifile, req.pr_entry_nr, 0,
10643bfb45eSRyusuke Konishi &req.pr_entry_bh);
10743bfb45eSRyusuke Konishi if (ret < 0)
10843bfb45eSRyusuke Konishi nilfs_palloc_abort_free_entry(ifile, &req);
10943bfb45eSRyusuke Konishi }
11043bfb45eSRyusuke Konishi if (ret < 0) {
11143bfb45eSRyusuke Konishi brelse(req.pr_entry_bh);
11243bfb45eSRyusuke Konishi return ret;
11343bfb45eSRyusuke Konishi }
11443bfb45eSRyusuke Konishi
1157b9c0976SCong Wang kaddr = kmap_atomic(req.pr_entry_bh->b_page);
11643bfb45eSRyusuke Konishi raw_inode = nilfs_palloc_block_get_entry(ifile, req.pr_entry_nr,
11743bfb45eSRyusuke Konishi req.pr_entry_bh, kaddr);
11843bfb45eSRyusuke Konishi raw_inode->i_flags = 0;
1197b9c0976SCong Wang kunmap_atomic(kaddr);
12043bfb45eSRyusuke Konishi
1215fc7b141SRyusuke Konishi mark_buffer_dirty(req.pr_entry_bh);
12243bfb45eSRyusuke Konishi brelse(req.pr_entry_bh);
12343bfb45eSRyusuke Konishi
12443bfb45eSRyusuke Konishi nilfs_palloc_commit_free_entry(ifile, &req);
12543bfb45eSRyusuke Konishi
12643bfb45eSRyusuke Konishi return 0;
12743bfb45eSRyusuke Konishi }
12843bfb45eSRyusuke Konishi
nilfs_ifile_get_inode_block(struct inode * ifile,ino_t ino,struct buffer_head ** out_bh)12943bfb45eSRyusuke Konishi int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino,
13043bfb45eSRyusuke Konishi struct buffer_head **out_bh)
13143bfb45eSRyusuke Konishi {
13243bfb45eSRyusuke Konishi struct super_block *sb = ifile->i_sb;
13343bfb45eSRyusuke Konishi int err;
13443bfb45eSRyusuke Konishi
13543bfb45eSRyusuke Konishi if (unlikely(!NILFS_VALID_INODE(sb, ino))) {
136cae3d4caSRyusuke Konishi nilfs_error(sb, "bad inode number: %lu", (unsigned long)ino);
13743bfb45eSRyusuke Konishi return -EINVAL;
13843bfb45eSRyusuke Konishi }
13943bfb45eSRyusuke Konishi
14043bfb45eSRyusuke Konishi err = nilfs_palloc_get_entry_block(ifile, ino, 0, out_bh);
141e828949eSRyusuke Konishi if (unlikely(err))
142a1d0747aSJoe Perches nilfs_warn(sb, "error %d reading inode: ino=%lu",
143d6517debSRyusuke Konishi err, (unsigned long)ino);
14443bfb45eSRyusuke Konishi return err;
14543bfb45eSRyusuke Konishi }
14679739565SRyusuke Konishi
14779739565SRyusuke Konishi /**
148c7ef972cSVyacheslav Dubeyko * nilfs_ifile_count_free_inodes - calculate free inodes count
149c7ef972cSVyacheslav Dubeyko * @ifile: ifile inode
150c7ef972cSVyacheslav Dubeyko * @nmaxinodes: current maximum of available inodes count [out]
151c7ef972cSVyacheslav Dubeyko * @nfreeinodes: free inodes count [out]
152c7ef972cSVyacheslav Dubeyko */
nilfs_ifile_count_free_inodes(struct inode * ifile,u64 * nmaxinodes,u64 * nfreeinodes)153c7ef972cSVyacheslav Dubeyko int nilfs_ifile_count_free_inodes(struct inode *ifile,
154c7ef972cSVyacheslav Dubeyko u64 *nmaxinodes, u64 *nfreeinodes)
155c7ef972cSVyacheslav Dubeyko {
156c7ef972cSVyacheslav Dubeyko u64 nused;
157c7ef972cSVyacheslav Dubeyko int err;
158c7ef972cSVyacheslav Dubeyko
159c7ef972cSVyacheslav Dubeyko *nmaxinodes = 0;
160c7ef972cSVyacheslav Dubeyko *nfreeinodes = 0;
161c7ef972cSVyacheslav Dubeyko
162e5f7f848SVyacheslav Dubeyko nused = atomic64_read(&NILFS_I(ifile)->i_root->inodes_count);
163c7ef972cSVyacheslav Dubeyko err = nilfs_palloc_count_max_entries(ifile, nused, nmaxinodes);
164c7ef972cSVyacheslav Dubeyko if (likely(!err))
165c7ef972cSVyacheslav Dubeyko *nfreeinodes = *nmaxinodes - nused;
166c7ef972cSVyacheslav Dubeyko return err;
167c7ef972cSVyacheslav Dubeyko }
168c7ef972cSVyacheslav Dubeyko
169c7ef972cSVyacheslav Dubeyko /**
170f1e89c86SRyusuke Konishi * nilfs_ifile_read - read or get ifile inode
171f1e89c86SRyusuke Konishi * @sb: super block instance
172f1e89c86SRyusuke Konishi * @root: root object
17379739565SRyusuke Konishi * @inode_size: size of an inode
174f1e89c86SRyusuke Konishi * @raw_inode: on-disk ifile inode
175f1e89c86SRyusuke Konishi * @inodep: buffer to store the inode
17679739565SRyusuke Konishi */
nilfs_ifile_read(struct super_block * sb,struct nilfs_root * root,size_t inode_size,struct nilfs_inode * raw_inode,struct inode ** inodep)177f1e89c86SRyusuke Konishi int nilfs_ifile_read(struct super_block *sb, struct nilfs_root *root,
178f1e89c86SRyusuke Konishi size_t inode_size, struct nilfs_inode *raw_inode,
179f1e89c86SRyusuke Konishi struct inode **inodep)
18079739565SRyusuke Konishi {
18179739565SRyusuke Konishi struct inode *ifile;
18279739565SRyusuke Konishi int err;
18379739565SRyusuke Konishi
184f1e89c86SRyusuke Konishi ifile = nilfs_iget_locked(sb, root, NILFS_IFILE_INO);
185f1e89c86SRyusuke Konishi if (unlikely(!ifile))
186f1e89c86SRyusuke Konishi return -ENOMEM;
187f1e89c86SRyusuke Konishi if (!(ifile->i_state & I_NEW))
188f1e89c86SRyusuke Konishi goto out;
189f1e89c86SRyusuke Konishi
190f1e89c86SRyusuke Konishi err = nilfs_mdt_init(ifile, NILFS_MDT_GFP,
19149fa7a59SRyusuke Konishi sizeof(struct nilfs_ifile_info));
192f1e89c86SRyusuke Konishi if (err)
193f1e89c86SRyusuke Konishi goto failed;
194f1e89c86SRyusuke Konishi
19579739565SRyusuke Konishi err = nilfs_palloc_init_blockgroup(ifile, inode_size);
196f1e89c86SRyusuke Konishi if (err)
197f1e89c86SRyusuke Konishi goto failed;
198f1e89c86SRyusuke Konishi
199f1e89c86SRyusuke Konishi nilfs_palloc_setup_cache(ifile, &NILFS_IFILE_I(ifile)->palloc_cache);
200f1e89c86SRyusuke Konishi
201f1e89c86SRyusuke Konishi err = nilfs_read_inode_common(ifile, raw_inode);
202f1e89c86SRyusuke Konishi if (err)
203f1e89c86SRyusuke Konishi goto failed;
204f1e89c86SRyusuke Konishi
205f1e89c86SRyusuke Konishi unlock_new_inode(ifile);
206f1e89c86SRyusuke Konishi out:
207f1e89c86SRyusuke Konishi *inodep = ifile;
208f1e89c86SRyusuke Konishi return 0;
209f1e89c86SRyusuke Konishi failed:
210f1e89c86SRyusuke Konishi iget_failed(ifile);
211f1e89c86SRyusuke Konishi return err;
21279739565SRyusuke Konishi }
213