xref: /openbmc/linux/fs/nilfs2/ifile.c (revision ee1cd5048959de496cd005c50b137212a5b62062)
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