xref: /openbmc/linux/fs/sysv/inode.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *  linux/fs/sysv/inode.c
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  *  minix/inode.c
61da177e4SLinus Torvalds  *  Copyright (C) 1991, 1992  Linus Torvalds
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  *  xenix/inode.c
91da177e4SLinus Torvalds  *  Copyright (C) 1992  Doug Evans
101da177e4SLinus Torvalds  *
111da177e4SLinus Torvalds  *  coh/inode.c
121da177e4SLinus Torvalds  *  Copyright (C) 1993  Pascal Haible, Bruno Haible
131da177e4SLinus Torvalds  *
141da177e4SLinus Torvalds  *  sysv/inode.c
151da177e4SLinus Torvalds  *  Copyright (C) 1993  Paul B. Monday
161da177e4SLinus Torvalds  *
171da177e4SLinus Torvalds  *  sysv/inode.c
181da177e4SLinus Torvalds  *  Copyright (C) 1993  Bruno Haible
191da177e4SLinus Torvalds  *  Copyright (C) 1997, 1998  Krzysztof G. Baranowski
201da177e4SLinus Torvalds  *
211da177e4SLinus Torvalds  *  This file contains code for allocating/freeing inodes and for read/writing
221da177e4SLinus Torvalds  *  the superblock.
231da177e4SLinus Torvalds  */
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds #include <linux/highuid.h>
261da177e4SLinus Torvalds #include <linux/slab.h>
271da177e4SLinus Torvalds #include <linux/init.h>
281da177e4SLinus Torvalds #include <linux/buffer_head.h>
291da177e4SLinus Torvalds #include <linux/vfs.h>
30a9185b41SChristoph Hellwig #include <linux/writeback.h>
3121acaf8eSDuane Griffin #include <linux/namei.h>
321da177e4SLinus Torvalds #include <asm/byteorder.h>
331da177e4SLinus Torvalds #include "sysv.h"
341da177e4SLinus Torvalds 
sysv_sync_fs(struct super_block * sb,int wait)35ad43ffdeSChristoph Hellwig static int sysv_sync_fs(struct super_block *sb, int wait)
361da177e4SLinus Torvalds {
371da177e4SLinus Torvalds 	struct sysv_sb_info *sbi = SYSV_SB(sb);
383e811f05SArnd Bergmann 	u32 time = (u32)ktime_get_real_seconds(), old_time;
391da177e4SLinus Torvalds 
40c07cb01cSMarco Stornelli 	mutex_lock(&sbi->s_lock);
411da177e4SLinus Torvalds 
421da177e4SLinus Torvalds 	/*
431da177e4SLinus Torvalds 	 * If we are going to write out the super block,
441da177e4SLinus Torvalds 	 * then attach current time stamp.
451da177e4SLinus Torvalds 	 * But if the filesystem was marked clean, keep it clean.
461da177e4SLinus Torvalds 	 */
471da177e4SLinus Torvalds 	old_time = fs32_to_cpu(sbi, *sbi->s_sb_time);
481da177e4SLinus Torvalds 	if (sbi->s_type == FSTYPE_SYSV4) {
493e811f05SArnd Bergmann 		if (*sbi->s_sb_state == cpu_to_fs32(sbi, 0x7c269d38u - old_time))
503e811f05SArnd Bergmann 			*sbi->s_sb_state = cpu_to_fs32(sbi, 0x7c269d38u - time);
511da177e4SLinus Torvalds 		*sbi->s_sb_time = cpu_to_fs32(sbi, time);
521da177e4SLinus Torvalds 		mark_buffer_dirty(sbi->s_bh2);
531da177e4SLinus Torvalds 	}
54ad43ffdeSChristoph Hellwig 
55c07cb01cSMarco Stornelli 	mutex_unlock(&sbi->s_lock);
56ad43ffdeSChristoph Hellwig 
57ad43ffdeSChristoph Hellwig 	return 0;
58ad43ffdeSChristoph Hellwig }
59ad43ffdeSChristoph Hellwig 
sysv_remount(struct super_block * sb,int * flags,char * data)601da177e4SLinus Torvalds static int sysv_remount(struct super_block *sb, int *flags, char *data)
611da177e4SLinus Torvalds {
621da177e4SLinus Torvalds 	struct sysv_sb_info *sbi = SYSV_SB(sb);
63eee45893SArtem Bityutskiy 
6402b9984dSTheodore Ts'o 	sync_filesystem(sb);
651da177e4SLinus Torvalds 	if (sbi->s_forced_ro)
661751e8a6SLinus Torvalds 		*flags |= SB_RDONLY;
671da177e4SLinus Torvalds 	return 0;
681da177e4SLinus Torvalds }
691da177e4SLinus Torvalds 
sysv_put_super(struct super_block * sb)701da177e4SLinus Torvalds static void sysv_put_super(struct super_block *sb)
711da177e4SLinus Torvalds {
721da177e4SLinus Torvalds 	struct sysv_sb_info *sbi = SYSV_SB(sb);
731da177e4SLinus Torvalds 
74bc98a42cSDavid Howells 	if (!sb_rdonly(sb)) {
751da177e4SLinus Torvalds 		/* XXX ext2 also updates the state here */
761da177e4SLinus Torvalds 		mark_buffer_dirty(sbi->s_bh1);
771da177e4SLinus Torvalds 		if (sbi->s_bh1 != sbi->s_bh2)
781da177e4SLinus Torvalds 			mark_buffer_dirty(sbi->s_bh2);
791da177e4SLinus Torvalds 	}
801da177e4SLinus Torvalds 
811da177e4SLinus Torvalds 	brelse(sbi->s_bh1);
821da177e4SLinus Torvalds 	if (sbi->s_bh1 != sbi->s_bh2)
831da177e4SLinus Torvalds 		brelse(sbi->s_bh2);
841da177e4SLinus Torvalds 
851da177e4SLinus Torvalds 	kfree(sbi);
861da177e4SLinus Torvalds }
871da177e4SLinus Torvalds 
sysv_statfs(struct dentry * dentry,struct kstatfs * buf)88726c3342SDavid Howells static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf)
891da177e4SLinus Torvalds {
90726c3342SDavid Howells 	struct super_block *sb = dentry->d_sb;
911da177e4SLinus Torvalds 	struct sysv_sb_info *sbi = SYSV_SB(sb);
921c5b4541SColy Li 	u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
931da177e4SLinus Torvalds 
941da177e4SLinus Torvalds 	buf->f_type = sb->s_magic;
951da177e4SLinus Torvalds 	buf->f_bsize = sb->s_blocksize;
961da177e4SLinus Torvalds 	buf->f_blocks = sbi->s_ndatazones;
971da177e4SLinus Torvalds 	buf->f_bavail = buf->f_bfree = sysv_count_free_blocks(sb);
981da177e4SLinus Torvalds 	buf->f_files = sbi->s_ninodes;
991da177e4SLinus Torvalds 	buf->f_ffree = sysv_count_free_inodes(sb);
1001da177e4SLinus Torvalds 	buf->f_namelen = SYSV_NAMELEN;
1016d1349c7SAl Viro 	buf->f_fsid = u64_to_fsid(id);
1021da177e4SLinus Torvalds 	return 0;
1031da177e4SLinus Torvalds }
1041da177e4SLinus Torvalds 
1051da177e4SLinus Torvalds /*
1061da177e4SLinus Torvalds  * NXI <-> N0XI for PDP, XIN <-> XIN0 for le32, NIX <-> 0NIX for be32
1071da177e4SLinus Torvalds  */
read3byte(struct sysv_sb_info * sbi,unsigned char * from,unsigned char * to)1081da177e4SLinus Torvalds static inline void read3byte(struct sysv_sb_info *sbi,
1091da177e4SLinus Torvalds 	unsigned char * from, unsigned char * to)
1101da177e4SLinus Torvalds {
1111da177e4SLinus Torvalds 	if (sbi->s_bytesex == BYTESEX_PDP) {
1121da177e4SLinus Torvalds 		to[0] = from[0];
1131da177e4SLinus Torvalds 		to[1] = 0;
1141da177e4SLinus Torvalds 		to[2] = from[1];
1151da177e4SLinus Torvalds 		to[3] = from[2];
1161da177e4SLinus Torvalds 	} else if (sbi->s_bytesex == BYTESEX_LE) {
1171da177e4SLinus Torvalds 		to[0] = from[0];
1181da177e4SLinus Torvalds 		to[1] = from[1];
1191da177e4SLinus Torvalds 		to[2] = from[2];
1201da177e4SLinus Torvalds 		to[3] = 0;
1211da177e4SLinus Torvalds 	} else {
1221da177e4SLinus Torvalds 		to[0] = 0;
1231da177e4SLinus Torvalds 		to[1] = from[0];
1241da177e4SLinus Torvalds 		to[2] = from[1];
1251da177e4SLinus Torvalds 		to[3] = from[2];
1261da177e4SLinus Torvalds 	}
1271da177e4SLinus Torvalds }
1281da177e4SLinus Torvalds 
write3byte(struct sysv_sb_info * sbi,unsigned char * from,unsigned char * to)1291da177e4SLinus Torvalds static inline void write3byte(struct sysv_sb_info *sbi,
1301da177e4SLinus Torvalds 	unsigned char * from, unsigned char * to)
1311da177e4SLinus Torvalds {
1321da177e4SLinus Torvalds 	if (sbi->s_bytesex == BYTESEX_PDP) {
1331da177e4SLinus Torvalds 		to[0] = from[0];
1341da177e4SLinus Torvalds 		to[1] = from[2];
1351da177e4SLinus Torvalds 		to[2] = from[3];
1361da177e4SLinus Torvalds 	} else if (sbi->s_bytesex == BYTESEX_LE) {
1371da177e4SLinus Torvalds 		to[0] = from[0];
1381da177e4SLinus Torvalds 		to[1] = from[1];
1391da177e4SLinus Torvalds 		to[2] = from[2];
1401da177e4SLinus Torvalds 	} else {
1411da177e4SLinus Torvalds 		to[0] = from[1];
1421da177e4SLinus Torvalds 		to[1] = from[2];
1431da177e4SLinus Torvalds 		to[2] = from[3];
1441da177e4SLinus Torvalds 	}
1451da177e4SLinus Torvalds }
1461da177e4SLinus Torvalds 
147c5ef1c42SArjan van de Ven static const struct inode_operations sysv_symlink_inode_operations = {
1486b255391SAl Viro 	.get_link	= page_get_link,
1491da177e4SLinus Torvalds 	.getattr	= sysv_getattr,
1501da177e4SLinus Torvalds };
1511da177e4SLinus Torvalds 
sysv_set_inode(struct inode * inode,dev_t rdev)1521da177e4SLinus Torvalds void sysv_set_inode(struct inode *inode, dev_t rdev)
1531da177e4SLinus Torvalds {
1541da177e4SLinus Torvalds 	if (S_ISREG(inode->i_mode)) {
1551da177e4SLinus Torvalds 		inode->i_op = &sysv_file_inode_operations;
1561da177e4SLinus Torvalds 		inode->i_fop = &sysv_file_operations;
1571da177e4SLinus Torvalds 		inode->i_mapping->a_ops = &sysv_aops;
1581da177e4SLinus Torvalds 	} else if (S_ISDIR(inode->i_mode)) {
1591da177e4SLinus Torvalds 		inode->i_op = &sysv_dir_inode_operations;
1601da177e4SLinus Torvalds 		inode->i_fop = &sysv_dir_operations;
1611da177e4SLinus Torvalds 		inode->i_mapping->a_ops = &sysv_aops;
1621da177e4SLinus Torvalds 	} else if (S_ISLNK(inode->i_mode)) {
1631da177e4SLinus Torvalds 		inode->i_op = &sysv_symlink_inode_operations;
16421fc61c7SAl Viro 		inode_nohighmem(inode);
1651da177e4SLinus Torvalds 		inode->i_mapping->a_ops = &sysv_aops;
1661da177e4SLinus Torvalds 	} else
1671da177e4SLinus Torvalds 		init_special_inode(inode, inode->i_mode, rdev);
1681da177e4SLinus Torvalds }
1691da177e4SLinus Torvalds 
sysv_iget(struct super_block * sb,unsigned int ino)170b8e1343fSDavid Howells struct inode *sysv_iget(struct super_block *sb, unsigned int ino)
1711da177e4SLinus Torvalds {
1721da177e4SLinus Torvalds 	struct sysv_sb_info * sbi = SYSV_SB(sb);
1731da177e4SLinus Torvalds 	struct buffer_head * bh;
1741da177e4SLinus Torvalds 	struct sysv_inode * raw_inode;
1751da177e4SLinus Torvalds 	struct sysv_inode_info * si;
176b8e1343fSDavid Howells 	struct inode *inode;
177b8e1343fSDavid Howells 	unsigned int block;
1781da177e4SLinus Torvalds 
1791da177e4SLinus Torvalds 	if (!ino || ino > sbi->s_ninodes) {
1801da177e4SLinus Torvalds 		printk("Bad inode number on dev %s: %d is out of range\n",
181b8e1343fSDavid Howells 		       sb->s_id, ino);
182b8e1343fSDavid Howells 		return ERR_PTR(-EIO);
1831da177e4SLinus Torvalds 	}
184b8e1343fSDavid Howells 
185b8e1343fSDavid Howells 	inode = iget_locked(sb, ino);
186b8e1343fSDavid Howells 	if (!inode)
187b8e1343fSDavid Howells 		return ERR_PTR(-ENOMEM);
188b8e1343fSDavid Howells 	if (!(inode->i_state & I_NEW))
189b8e1343fSDavid Howells 		return inode;
190b8e1343fSDavid Howells 
1911da177e4SLinus Torvalds 	raw_inode = sysv_raw_inode(sb, ino, &bh);
1921da177e4SLinus Torvalds 	if (!raw_inode) {
1931da177e4SLinus Torvalds 		printk("Major problem: unable to read inode from dev %s\n",
1941da177e4SLinus Torvalds 		       inode->i_sb->s_id);
1951da177e4SLinus Torvalds 		goto bad_inode;
1961da177e4SLinus Torvalds 	}
1971da177e4SLinus Torvalds 	/* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */
1981da177e4SLinus Torvalds 	inode->i_mode = fs16_to_cpu(sbi, raw_inode->i_mode);
199a726ecceSEric W. Biederman 	i_uid_write(inode, (uid_t)fs16_to_cpu(sbi, raw_inode->i_uid));
200a726ecceSEric W. Biederman 	i_gid_write(inode, (gid_t)fs16_to_cpu(sbi, raw_inode->i_gid));
201bfe86848SMiklos Szeredi 	set_nlink(inode, fs16_to_cpu(sbi, raw_inode->i_nlink));
2021da177e4SLinus Torvalds 	inode->i_size = fs32_to_cpu(sbi, raw_inode->i_size);
2031da177e4SLinus Torvalds 	inode->i_atime.tv_sec = fs32_to_cpu(sbi, raw_inode->i_atime);
2041da177e4SLinus Torvalds 	inode->i_mtime.tv_sec = fs32_to_cpu(sbi, raw_inode->i_mtime);
205*c801b095SJeff Layton 	inode_set_ctime(inode, fs32_to_cpu(sbi, raw_inode->i_ctime), 0);
2061da177e4SLinus Torvalds 	inode->i_atime.tv_nsec = 0;
2071da177e4SLinus Torvalds 	inode->i_mtime.tv_nsec = 0;
208ba52de12STheodore Ts'o 	inode->i_blocks = 0;
2091da177e4SLinus Torvalds 
2101da177e4SLinus Torvalds 	si = SYSV_I(inode);
2111da177e4SLinus Torvalds 	for (block = 0; block < 10+1+1+1; block++)
2121da177e4SLinus Torvalds 		read3byte(sbi, &raw_inode->i_data[3*block],
2131da177e4SLinus Torvalds 				(u8 *)&si->i_data[block]);
2141da177e4SLinus Torvalds 	brelse(bh);
2151da177e4SLinus Torvalds 	si->i_dir_start_lookup = 0;
2161da177e4SLinus Torvalds 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
2171da177e4SLinus Torvalds 		sysv_set_inode(inode,
2181da177e4SLinus Torvalds 			       old_decode_dev(fs32_to_cpu(sbi, si->i_data[0])));
2191da177e4SLinus Torvalds 	else
2201da177e4SLinus Torvalds 		sysv_set_inode(inode, 0);
221b8e1343fSDavid Howells 	unlock_new_inode(inode);
222b8e1343fSDavid Howells 	return inode;
2231da177e4SLinus Torvalds 
2241da177e4SLinus Torvalds bad_inode:
225b8e1343fSDavid Howells 	iget_failed(inode);
226b8e1343fSDavid Howells 	return ERR_PTR(-EIO);
2271da177e4SLinus Torvalds }
2281da177e4SLinus Torvalds 
__sysv_write_inode(struct inode * inode,int wait)229a9185b41SChristoph Hellwig static int __sysv_write_inode(struct inode *inode, int wait)
2301da177e4SLinus Torvalds {
2311da177e4SLinus Torvalds 	struct super_block * sb = inode->i_sb;
2321da177e4SLinus Torvalds 	struct sysv_sb_info * sbi = SYSV_SB(sb);
2331da177e4SLinus Torvalds 	struct buffer_head * bh;
2341da177e4SLinus Torvalds 	struct sysv_inode * raw_inode;
2351da177e4SLinus Torvalds 	struct sysv_inode_info * si;
2361da177e4SLinus Torvalds 	unsigned int ino, block;
23705459ca8SAl Viro 	int err = 0;
2381da177e4SLinus Torvalds 
2391da177e4SLinus Torvalds 	ino = inode->i_ino;
2401da177e4SLinus Torvalds 	if (!ino || ino > sbi->s_ninodes) {
2411da177e4SLinus Torvalds 		printk("Bad inode number on dev %s: %d is out of range\n",
2421da177e4SLinus Torvalds 		       inode->i_sb->s_id, ino);
24305459ca8SAl Viro 		return -EIO;
2441da177e4SLinus Torvalds 	}
2451da177e4SLinus Torvalds 	raw_inode = sysv_raw_inode(sb, ino, &bh);
2461da177e4SLinus Torvalds 	if (!raw_inode) {
2471da177e4SLinus Torvalds 		printk("unable to read i-node block\n");
24805459ca8SAl Viro 		return -EIO;
2491da177e4SLinus Torvalds 	}
2501da177e4SLinus Torvalds 
2511da177e4SLinus Torvalds 	raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode);
252a726ecceSEric W. Biederman 	raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(i_uid_read(inode)));
253a726ecceSEric W. Biederman 	raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(i_gid_read(inode)));
2541da177e4SLinus Torvalds 	raw_inode->i_nlink = cpu_to_fs16(sbi, inode->i_nlink);
2551da177e4SLinus Torvalds 	raw_inode->i_size = cpu_to_fs32(sbi, inode->i_size);
2561da177e4SLinus Torvalds 	raw_inode->i_atime = cpu_to_fs32(sbi, inode->i_atime.tv_sec);
2571da177e4SLinus Torvalds 	raw_inode->i_mtime = cpu_to_fs32(sbi, inode->i_mtime.tv_sec);
258*c801b095SJeff Layton 	raw_inode->i_ctime = cpu_to_fs32(sbi, inode_get_ctime(inode).tv_sec);
2591da177e4SLinus Torvalds 
2601da177e4SLinus Torvalds 	si = SYSV_I(inode);
2611da177e4SLinus Torvalds 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
2621da177e4SLinus Torvalds 		si->i_data[0] = cpu_to_fs32(sbi, old_encode_dev(inode->i_rdev));
2631da177e4SLinus Torvalds 	for (block = 0; block < 10+1+1+1; block++)
2641da177e4SLinus Torvalds 		write3byte(sbi, (u8 *)&si->i_data[block],
2651da177e4SLinus Torvalds 			&raw_inode->i_data[3*block]);
26605459ca8SAl Viro 	mark_buffer_dirty(bh);
26705459ca8SAl Viro 	if (wait) {
26805459ca8SAl Viro                 sync_dirty_buffer(bh);
26905459ca8SAl Viro                 if (buffer_req(bh) && !buffer_uptodate(bh)) {
27005459ca8SAl Viro                         printk ("IO error syncing sysv inode [%s:%08x]\n",
27105459ca8SAl Viro                                 sb->s_id, ino);
27205459ca8SAl Viro                         err = -EIO;
27305459ca8SAl Viro                 }
27405459ca8SAl Viro         }
27505459ca8SAl Viro 	brelse(bh);
276c4b7d1baSYueHaibing 	return err;
2771da177e4SLinus Torvalds }
2781da177e4SLinus Torvalds 
sysv_write_inode(struct inode * inode,struct writeback_control * wbc)279a9185b41SChristoph Hellwig int sysv_write_inode(struct inode *inode, struct writeback_control *wbc)
280a9185b41SChristoph Hellwig {
281a9185b41SChristoph Hellwig 	return __sysv_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
282a9185b41SChristoph Hellwig }
283a9185b41SChristoph Hellwig 
sysv_sync_inode(struct inode * inode)2841da177e4SLinus Torvalds int sysv_sync_inode(struct inode *inode)
2851da177e4SLinus Torvalds {
286a9185b41SChristoph Hellwig 	return __sysv_write_inode(inode, 1);
2871da177e4SLinus Torvalds }
2881da177e4SLinus Torvalds 
sysv_evict_inode(struct inode * inode)289d299eadcSAl Viro static void sysv_evict_inode(struct inode *inode)
2901da177e4SLinus Torvalds {
29191b0abe3SJohannes Weiner 	truncate_inode_pages_final(&inode->i_data);
292d299eadcSAl Viro 	if (!inode->i_nlink) {
2931da177e4SLinus Torvalds 		inode->i_size = 0;
2941da177e4SLinus Torvalds 		sysv_truncate(inode);
295d299eadcSAl Viro 	}
296d299eadcSAl Viro 	invalidate_inode_buffers(inode);
297dbd5768fSJan Kara 	clear_inode(inode);
298d299eadcSAl Viro 	if (!inode->i_nlink)
2991da177e4SLinus Torvalds 		sysv_free_inode(inode);
3001da177e4SLinus Torvalds }
3011da177e4SLinus Torvalds 
302e18b890bSChristoph Lameter static struct kmem_cache *sysv_inode_cachep;
3031da177e4SLinus Torvalds 
sysv_alloc_inode(struct super_block * sb)3041da177e4SLinus Torvalds static struct inode *sysv_alloc_inode(struct super_block *sb)
3051da177e4SLinus Torvalds {
3061da177e4SLinus Torvalds 	struct sysv_inode_info *si;
3071da177e4SLinus Torvalds 
308fd60b288SMuchun Song 	si = alloc_inode_sb(sb, sysv_inode_cachep, GFP_KERNEL);
3091da177e4SLinus Torvalds 	if (!si)
3101da177e4SLinus Torvalds 		return NULL;
3111da177e4SLinus Torvalds 	return &si->vfs_inode;
3121da177e4SLinus Torvalds }
3131da177e4SLinus Torvalds 
sysv_free_in_core_inode(struct inode * inode)3146becf8edSAl Viro static void sysv_free_in_core_inode(struct inode *inode)
315fa0d7e3dSNick Piggin {
316fa0d7e3dSNick Piggin 	kmem_cache_free(sysv_inode_cachep, SYSV_I(inode));
317fa0d7e3dSNick Piggin }
318fa0d7e3dSNick Piggin 
init_once(void * p)31951cc5068SAlexey Dobriyan static void init_once(void *p)
3201da177e4SLinus Torvalds {
3211da177e4SLinus Torvalds 	struct sysv_inode_info *si = (struct sysv_inode_info *)p;
3221da177e4SLinus Torvalds 
3231da177e4SLinus Torvalds 	inode_init_once(&si->vfs_inode);
3241da177e4SLinus Torvalds }
3251da177e4SLinus Torvalds 
326ee9b6d61SJosef 'Jeff' Sipek const struct super_operations sysv_sops = {
3271da177e4SLinus Torvalds 	.alloc_inode	= sysv_alloc_inode,
3286becf8edSAl Viro 	.free_inode	= sysv_free_in_core_inode,
3291da177e4SLinus Torvalds 	.write_inode	= sysv_write_inode,
330d299eadcSAl Viro 	.evict_inode	= sysv_evict_inode,
3311da177e4SLinus Torvalds 	.put_super	= sysv_put_super,
332ad43ffdeSChristoph Hellwig 	.sync_fs	= sysv_sync_fs,
3331da177e4SLinus Torvalds 	.remount_fs	= sysv_remount,
3341da177e4SLinus Torvalds 	.statfs		= sysv_statfs,
3351da177e4SLinus Torvalds };
3361da177e4SLinus Torvalds 
sysv_init_icache(void)3371da177e4SLinus Torvalds int __init sysv_init_icache(void)
3381da177e4SLinus Torvalds {
3391da177e4SLinus Torvalds 	sysv_inode_cachep = kmem_cache_create("sysv_inode_cache",
3401da177e4SLinus Torvalds 			sizeof(struct sysv_inode_info), 0,
3415d097056SVladimir Davydov 			SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD|SLAB_ACCOUNT,
34220c2df83SPaul Mundt 			init_once);
3431da177e4SLinus Torvalds 	if (!sysv_inode_cachep)
3441da177e4SLinus Torvalds 		return -ENOMEM;
3451da177e4SLinus Torvalds 	return 0;
3461da177e4SLinus Torvalds }
3471da177e4SLinus Torvalds 
sysv_destroy_icache(void)3481da177e4SLinus Torvalds void sysv_destroy_icache(void)
3491da177e4SLinus Torvalds {
3508c0a8537SKirill A. Shutemov 	/*
3518c0a8537SKirill A. Shutemov 	 * Make sure all delayed rcu free inodes are flushed before we
3528c0a8537SKirill A. Shutemov 	 * destroy cache.
3538c0a8537SKirill A. Shutemov 	 */
3548c0a8537SKirill A. Shutemov 	rcu_barrier();
3551da177e4SLinus Torvalds 	kmem_cache_destroy(sysv_inode_cachep);
3561da177e4SLinus Torvalds }
357