xref: /openbmc/linux/fs/sysv/ialloc.c (revision 0545810f)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  linux/fs/sysv/ialloc.c
4  *
5  *  minix/bitmap.c
6  *  Copyright (C) 1991, 1992  Linus Torvalds
7  *
8  *  ext/freelists.c
9  *  Copyright (C) 1992  Remy Card (card@masi.ibp.fr)
10  *
11  *  xenix/alloc.c
12  *  Copyright (C) 1992  Doug Evans
13  *
14  *  coh/alloc.c
15  *  Copyright (C) 1993  Pascal Haible, Bruno Haible
16  *
17  *  sysv/ialloc.c
18  *  Copyright (C) 1993  Bruno Haible
19  *
20  *  This file contains code for allocating/freeing inodes.
21  */
22 
23 #include <linux/kernel.h>
24 #include <linux/stddef.h>
25 #include <linux/sched.h>
26 #include <linux/stat.h>
27 #include <linux/string.h>
28 #include <linux/buffer_head.h>
29 #include <linux/writeback.h>
30 #include "sysv.h"
31 
32 /* We don't trust the value of
33    sb->sv_sbd2->s_tinode = *sb->sv_sb_total_free_inodes
34    but we nevertheless keep it up to date. */
35 
36 /* An inode on disk is considered free if both i_mode == 0 and i_nlink == 0. */
37 
38 /* return &sb->sv_sb_fic_inodes[i] = &sbd->s_inode[i]; */
39 static inline sysv_ino_t *
40 sv_sb_fic_inode(struct super_block * sb, unsigned int i)
41 {
42 	struct sysv_sb_info *sbi = SYSV_SB(sb);
43 
44 	if (sbi->s_bh1 == sbi->s_bh2)
45 		return &sbi->s_sb_fic_inodes[i];
46 	else {
47 		/* 512 byte Xenix FS */
48 		unsigned int offset = offsetof(struct xenix_super_block, s_inode[i]);
49 		if (offset < 512)
50 			return (sysv_ino_t*)(sbi->s_sbd1 + offset);
51 		else
52 			return (sysv_ino_t*)(sbi->s_sbd2 + offset);
53 	}
54 }
55 
56 struct sysv_inode *
57 sysv_raw_inode(struct super_block *sb, unsigned ino, struct buffer_head **bh)
58 {
59 	struct sysv_sb_info *sbi = SYSV_SB(sb);
60 	struct sysv_inode *res;
61 	int block = sbi->s_firstinodezone + sbi->s_block_base;
62 
63 	block += (ino-1) >> sbi->s_inodes_per_block_bits;
64 	*bh = sb_bread(sb, block);
65 	if (!*bh)
66 		return NULL;
67 	res = (struct sysv_inode *)(*bh)->b_data;
68 	return res + ((ino-1) & sbi->s_inodes_per_block_1);
69 }
70 
71 static int refill_free_cache(struct super_block *sb)
72 {
73 	struct sysv_sb_info *sbi = SYSV_SB(sb);
74 	struct buffer_head * bh;
75 	struct sysv_inode * raw_inode;
76 	int i = 0, ino;
77 
78 	ino = SYSV_ROOT_INO+1;
79 	raw_inode = sysv_raw_inode(sb, ino, &bh);
80 	if (!raw_inode)
81 		goto out;
82 	while (ino <= sbi->s_ninodes) {
83 		if (raw_inode->i_mode == 0 && raw_inode->i_nlink == 0) {
84 			*sv_sb_fic_inode(sb,i++) = cpu_to_fs16(SYSV_SB(sb), ino);
85 			if (i == sbi->s_fic_size)
86 				break;
87 		}
88 		if ((ino++ & sbi->s_inodes_per_block_1) == 0) {
89 			brelse(bh);
90 			raw_inode = sysv_raw_inode(sb, ino, &bh);
91 			if (!raw_inode)
92 				goto out;
93 		} else
94 			raw_inode++;
95 	}
96 	brelse(bh);
97 out:
98 	return i;
99 }
100 
101 void sysv_free_inode(struct inode * inode)
102 {
103 	struct super_block *sb = inode->i_sb;
104 	struct sysv_sb_info *sbi = SYSV_SB(sb);
105 	unsigned int ino;
106 	struct buffer_head * bh;
107 	struct sysv_inode * raw_inode;
108 	unsigned count;
109 
110 	sb = inode->i_sb;
111 	ino = inode->i_ino;
112 	if (ino <= SYSV_ROOT_INO || ino > sbi->s_ninodes) {
113 		printk("sysv_free_inode: inode 0,1,2 or nonexistent inode\n");
114 		return;
115 	}
116 	raw_inode = sysv_raw_inode(sb, ino, &bh);
117 	if (!raw_inode) {
118 		printk("sysv_free_inode: unable to read inode block on device "
119 		       "%s\n", inode->i_sb->s_id);
120 		return;
121 	}
122 	mutex_lock(&sbi->s_lock);
123 	count = fs16_to_cpu(sbi, *sbi->s_sb_fic_count);
124 	if (count < sbi->s_fic_size) {
125 		*sv_sb_fic_inode(sb,count++) = cpu_to_fs16(sbi, ino);
126 		*sbi->s_sb_fic_count = cpu_to_fs16(sbi, count);
127 	}
128 	fs16_add(sbi, sbi->s_sb_total_free_inodes, 1);
129 	dirty_sb(sb);
130 	memset(raw_inode, 0, sizeof(struct sysv_inode));
131 	mark_buffer_dirty(bh);
132 	mutex_unlock(&sbi->s_lock);
133 	brelse(bh);
134 }
135 
136 struct inode * sysv_new_inode(const struct inode * dir, umode_t mode)
137 {
138 	struct super_block *sb = dir->i_sb;
139 	struct sysv_sb_info *sbi = SYSV_SB(sb);
140 	struct inode *inode;
141 	sysv_ino_t ino;
142 	unsigned count;
143 	struct writeback_control wbc = {
144 		.sync_mode = WB_SYNC_NONE
145 	};
146 
147 	inode = new_inode(sb);
148 	if (!inode)
149 		return ERR_PTR(-ENOMEM);
150 
151 	mutex_lock(&sbi->s_lock);
152 	count = fs16_to_cpu(sbi, *sbi->s_sb_fic_count);
153 	if (count == 0 || (*sv_sb_fic_inode(sb,count-1) == 0)) {
154 		count = refill_free_cache(sb);
155 		if (count == 0) {
156 			iput(inode);
157 			mutex_unlock(&sbi->s_lock);
158 			return ERR_PTR(-ENOSPC);
159 		}
160 	}
161 	/* Now count > 0. */
162 	ino = *sv_sb_fic_inode(sb,--count);
163 	*sbi->s_sb_fic_count = cpu_to_fs16(sbi, count);
164 	fs16_add(sbi, sbi->s_sb_total_free_inodes, -1);
165 	dirty_sb(sb);
166 	inode_init_owner(&nop_mnt_idmap, inode, dir, mode);
167 	inode->i_ino = fs16_to_cpu(sbi, ino);
168 	inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
169 	inode->i_blocks = 0;
170 	memset(SYSV_I(inode)->i_data, 0, sizeof(SYSV_I(inode)->i_data));
171 	SYSV_I(inode)->i_dir_start_lookup = 0;
172 	insert_inode_hash(inode);
173 	mark_inode_dirty(inode);
174 
175 	sysv_write_inode(inode, &wbc);	/* ensure inode not allocated again */
176 	mark_inode_dirty(inode);	/* cleared by sysv_write_inode() */
177 	/* That's it. */
178 	mutex_unlock(&sbi->s_lock);
179 	return inode;
180 }
181 
182 unsigned long sysv_count_free_inodes(struct super_block * sb)
183 {
184 	struct sysv_sb_info *sbi = SYSV_SB(sb);
185 	struct buffer_head * bh;
186 	struct sysv_inode * raw_inode;
187 	int ino, count, sb_count;
188 
189 	mutex_lock(&sbi->s_lock);
190 
191 	sb_count = fs16_to_cpu(sbi, *sbi->s_sb_total_free_inodes);
192 
193 	if (0)
194 		goto trust_sb;
195 
196 	/* this causes a lot of disk traffic ... */
197 	count = 0;
198 	ino = SYSV_ROOT_INO+1;
199 	raw_inode = sysv_raw_inode(sb, ino, &bh);
200 	if (!raw_inode)
201 		goto Eio;
202 	while (ino <= sbi->s_ninodes) {
203 		if (raw_inode->i_mode == 0 && raw_inode->i_nlink == 0)
204 			count++;
205 		if ((ino++ & sbi->s_inodes_per_block_1) == 0) {
206 			brelse(bh);
207 			raw_inode = sysv_raw_inode(sb, ino, &bh);
208 			if (!raw_inode)
209 				goto Eio;
210 		} else
211 			raw_inode++;
212 	}
213 	brelse(bh);
214 	if (count != sb_count)
215 		goto Einval;
216 out:
217 	mutex_unlock(&sbi->s_lock);
218 	return count;
219 
220 Einval:
221 	printk("sysv_count_free_inodes: "
222 		"free inode count was %d, correcting to %d\n",
223 		sb_count, count);
224 	if (!sb_rdonly(sb)) {
225 		*sbi->s_sb_total_free_inodes = cpu_to_fs16(SYSV_SB(sb), count);
226 		dirty_sb(sb);
227 	}
228 	goto out;
229 
230 Eio:
231 	printk("sysv_count_free_inodes: unable to read inode table\n");
232 trust_sb:
233 	count = sb_count;
234 	goto out;
235 }
236