18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _SYSV_H 38c2ecf20Sopenharmony_ci#define _SYSV_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/buffer_head.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_citypedef __u16 __bitwise __fs16; 88c2ecf20Sopenharmony_citypedef __u32 __bitwise __fs32; 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/sysv_fs.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/* 138c2ecf20Sopenharmony_ci * SystemV/V7/Coherent super-block data in memory 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * The SystemV/V7/Coherent superblock contains dynamic data (it gets modified 168c2ecf20Sopenharmony_ci * while the system is running). This is in contrast to the Minix and Berkeley 178c2ecf20Sopenharmony_ci * filesystems (where the superblock is never modified). This affects the 188c2ecf20Sopenharmony_ci * sync() operation: we must keep the superblock in a disk buffer and use this 198c2ecf20Sopenharmony_ci * one as our "working copy". 208c2ecf20Sopenharmony_ci */ 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistruct sysv_sb_info { 238c2ecf20Sopenharmony_ci struct super_block *s_sb; /* VFS superblock */ 248c2ecf20Sopenharmony_ci int s_type; /* file system type: FSTYPE_{XENIX|SYSV|COH} */ 258c2ecf20Sopenharmony_ci char s_bytesex; /* bytesex (le/be/pdp) */ 268c2ecf20Sopenharmony_ci unsigned int s_inodes_per_block; /* number of inodes per block */ 278c2ecf20Sopenharmony_ci unsigned int s_inodes_per_block_1; /* inodes_per_block - 1 */ 288c2ecf20Sopenharmony_ci unsigned int s_inodes_per_block_bits; /* log2(inodes_per_block) */ 298c2ecf20Sopenharmony_ci unsigned int s_ind_per_block; /* number of indirections per block */ 308c2ecf20Sopenharmony_ci unsigned int s_ind_per_block_bits; /* log2(ind_per_block) */ 318c2ecf20Sopenharmony_ci unsigned int s_ind_per_block_2; /* ind_per_block ^ 2 */ 328c2ecf20Sopenharmony_ci unsigned int s_toobig_block; /* 10 + ipb + ipb^2 + ipb^3 */ 338c2ecf20Sopenharmony_ci unsigned int s_block_base; /* physical block number of block 0 */ 348c2ecf20Sopenharmony_ci unsigned short s_fic_size; /* free inode cache size, NICINOD */ 358c2ecf20Sopenharmony_ci unsigned short s_flc_size; /* free block list chunk size, NICFREE */ 368c2ecf20Sopenharmony_ci /* The superblock is kept in one or two disk buffers: */ 378c2ecf20Sopenharmony_ci struct buffer_head *s_bh1; 388c2ecf20Sopenharmony_ci struct buffer_head *s_bh2; 398c2ecf20Sopenharmony_ci /* These are pointers into the disk buffer, to compensate for 408c2ecf20Sopenharmony_ci different superblock layout. */ 418c2ecf20Sopenharmony_ci char * s_sbd1; /* entire superblock data, for part 1 */ 428c2ecf20Sopenharmony_ci char * s_sbd2; /* entire superblock data, for part 2 */ 438c2ecf20Sopenharmony_ci __fs16 *s_sb_fic_count; /* pointer to s_sbd->s_ninode */ 448c2ecf20Sopenharmony_ci sysv_ino_t *s_sb_fic_inodes; /* pointer to s_sbd->s_inode */ 458c2ecf20Sopenharmony_ci __fs16 *s_sb_total_free_inodes; /* pointer to s_sbd->s_tinode */ 468c2ecf20Sopenharmony_ci __fs16 *s_bcache_count; /* pointer to s_sbd->s_nfree */ 478c2ecf20Sopenharmony_ci sysv_zone_t *s_bcache; /* pointer to s_sbd->s_free */ 488c2ecf20Sopenharmony_ci __fs32 *s_free_blocks; /* pointer to s_sbd->s_tfree */ 498c2ecf20Sopenharmony_ci __fs32 *s_sb_time; /* pointer to s_sbd->s_time */ 508c2ecf20Sopenharmony_ci __fs32 *s_sb_state; /* pointer to s_sbd->s_state, only FSTYPE_SYSV */ 518c2ecf20Sopenharmony_ci /* We keep those superblock entities that don't change here; 528c2ecf20Sopenharmony_ci this saves us an indirection and perhaps a conversion. */ 538c2ecf20Sopenharmony_ci u32 s_firstinodezone; /* index of first inode zone */ 548c2ecf20Sopenharmony_ci u32 s_firstdatazone; /* same as s_sbd->s_isize */ 558c2ecf20Sopenharmony_ci u32 s_ninodes; /* total number of inodes */ 568c2ecf20Sopenharmony_ci u32 s_ndatazones; /* total number of data zones */ 578c2ecf20Sopenharmony_ci u32 s_nzones; /* same as s_sbd->s_fsize */ 588c2ecf20Sopenharmony_ci u16 s_namelen; /* max length of dir entry */ 598c2ecf20Sopenharmony_ci int s_forced_ro; 608c2ecf20Sopenharmony_ci struct mutex s_lock; 618c2ecf20Sopenharmony_ci}; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci/* 648c2ecf20Sopenharmony_ci * SystemV/V7/Coherent FS inode data in memory 658c2ecf20Sopenharmony_ci */ 668c2ecf20Sopenharmony_cistruct sysv_inode_info { 678c2ecf20Sopenharmony_ci __fs32 i_data[13]; 688c2ecf20Sopenharmony_ci u32 i_dir_start_lookup; 698c2ecf20Sopenharmony_ci struct inode vfs_inode; 708c2ecf20Sopenharmony_ci}; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_cistatic inline struct sysv_inode_info *SYSV_I(struct inode *inode) 748c2ecf20Sopenharmony_ci{ 758c2ecf20Sopenharmony_ci return container_of(inode, struct sysv_inode_info, vfs_inode); 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cistatic inline struct sysv_sb_info *SYSV_SB(struct super_block *sb) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci return sb->s_fs_info; 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci/* identify the FS in memory */ 858c2ecf20Sopenharmony_cienum { 868c2ecf20Sopenharmony_ci FSTYPE_NONE = 0, 878c2ecf20Sopenharmony_ci FSTYPE_XENIX, 888c2ecf20Sopenharmony_ci FSTYPE_SYSV4, 898c2ecf20Sopenharmony_ci FSTYPE_SYSV2, 908c2ecf20Sopenharmony_ci FSTYPE_COH, 918c2ecf20Sopenharmony_ci FSTYPE_V7, 928c2ecf20Sopenharmony_ci FSTYPE_AFS, 938c2ecf20Sopenharmony_ci FSTYPE_END, 948c2ecf20Sopenharmony_ci}; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci#define SYSV_MAGIC_BASE 0x012FF7B3 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci#define XENIX_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_XENIX) 998c2ecf20Sopenharmony_ci#define SYSV4_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_SYSV4) 1008c2ecf20Sopenharmony_ci#define SYSV2_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_SYSV2) 1018c2ecf20Sopenharmony_ci#define COH_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_COH) 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci/* Admissible values for i_nlink: 0.._LINK_MAX */ 1058c2ecf20Sopenharmony_cienum { 1068c2ecf20Sopenharmony_ci XENIX_LINK_MAX = 126, /* ?? */ 1078c2ecf20Sopenharmony_ci SYSV_LINK_MAX = 126, /* 127? 251? */ 1088c2ecf20Sopenharmony_ci V7_LINK_MAX = 126, /* ?? */ 1098c2ecf20Sopenharmony_ci COH_LINK_MAX = 10000, 1108c2ecf20Sopenharmony_ci}; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_cistatic inline void dirty_sb(struct super_block *sb) 1148c2ecf20Sopenharmony_ci{ 1158c2ecf20Sopenharmony_ci struct sysv_sb_info *sbi = SYSV_SB(sb); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci mark_buffer_dirty(sbi->s_bh1); 1188c2ecf20Sopenharmony_ci if (sbi->s_bh1 != sbi->s_bh2) 1198c2ecf20Sopenharmony_ci mark_buffer_dirty(sbi->s_bh2); 1208c2ecf20Sopenharmony_ci} 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci/* ialloc.c */ 1248c2ecf20Sopenharmony_ciextern struct sysv_inode *sysv_raw_inode(struct super_block *, unsigned, 1258c2ecf20Sopenharmony_ci struct buffer_head **); 1268c2ecf20Sopenharmony_ciextern struct inode * sysv_new_inode(const struct inode *, umode_t); 1278c2ecf20Sopenharmony_ciextern void sysv_free_inode(struct inode *); 1288c2ecf20Sopenharmony_ciextern unsigned long sysv_count_free_inodes(struct super_block *); 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci/* balloc.c */ 1318c2ecf20Sopenharmony_ciextern sysv_zone_t sysv_new_block(struct super_block *); 1328c2ecf20Sopenharmony_ciextern void sysv_free_block(struct super_block *, sysv_zone_t); 1338c2ecf20Sopenharmony_ciextern unsigned long sysv_count_free_blocks(struct super_block *); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci/* itree.c */ 1368c2ecf20Sopenharmony_ciextern void sysv_truncate(struct inode *); 1378c2ecf20Sopenharmony_ciextern int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len); 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci/* inode.c */ 1408c2ecf20Sopenharmony_ciextern struct inode *sysv_iget(struct super_block *, unsigned int); 1418c2ecf20Sopenharmony_ciextern int sysv_write_inode(struct inode *, struct writeback_control *wbc); 1428c2ecf20Sopenharmony_ciextern int sysv_sync_inode(struct inode *); 1438c2ecf20Sopenharmony_ciextern void sysv_set_inode(struct inode *, dev_t); 1448c2ecf20Sopenharmony_ciextern int sysv_getattr(const struct path *, struct kstat *, u32, unsigned int); 1458c2ecf20Sopenharmony_ciextern int sysv_init_icache(void); 1468c2ecf20Sopenharmony_ciextern void sysv_destroy_icache(void); 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci/* dir.c */ 1508c2ecf20Sopenharmony_ciextern struct sysv_dir_entry *sysv_find_entry(struct dentry *, struct page **); 1518c2ecf20Sopenharmony_ciextern int sysv_add_link(struct dentry *, struct inode *); 1528c2ecf20Sopenharmony_ciextern int sysv_delete_entry(struct sysv_dir_entry *, struct page *); 1538c2ecf20Sopenharmony_ciextern int sysv_make_empty(struct inode *, struct inode *); 1548c2ecf20Sopenharmony_ciextern int sysv_empty_dir(struct inode *); 1558c2ecf20Sopenharmony_ciextern void sysv_set_link(struct sysv_dir_entry *, struct page *, 1568c2ecf20Sopenharmony_ci struct inode *); 1578c2ecf20Sopenharmony_ciextern struct sysv_dir_entry *sysv_dotdot(struct inode *, struct page **); 1588c2ecf20Sopenharmony_ciextern ino_t sysv_inode_by_name(struct dentry *); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ciextern const struct inode_operations sysv_file_inode_operations; 1628c2ecf20Sopenharmony_ciextern const struct inode_operations sysv_dir_inode_operations; 1638c2ecf20Sopenharmony_ciextern const struct file_operations sysv_file_operations; 1648c2ecf20Sopenharmony_ciextern const struct file_operations sysv_dir_operations; 1658c2ecf20Sopenharmony_ciextern const struct address_space_operations sysv_aops; 1668c2ecf20Sopenharmony_ciextern const struct super_operations sysv_sops; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cienum { 1708c2ecf20Sopenharmony_ci BYTESEX_LE, 1718c2ecf20Sopenharmony_ci BYTESEX_PDP, 1728c2ecf20Sopenharmony_ci BYTESEX_BE, 1738c2ecf20Sopenharmony_ci}; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_cistatic inline u32 PDP_swab(u32 x) 1768c2ecf20Sopenharmony_ci{ 1778c2ecf20Sopenharmony_ci#ifdef __LITTLE_ENDIAN 1788c2ecf20Sopenharmony_ci return ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16); 1798c2ecf20Sopenharmony_ci#else 1808c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN 1818c2ecf20Sopenharmony_ci return ((x & 0xff00ff) << 8) | ((x & 0xff00ff00) >> 8); 1828c2ecf20Sopenharmony_ci#else 1838c2ecf20Sopenharmony_ci#error BYTESEX 1848c2ecf20Sopenharmony_ci#endif 1858c2ecf20Sopenharmony_ci#endif 1868c2ecf20Sopenharmony_ci} 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_cistatic inline __u32 fs32_to_cpu(struct sysv_sb_info *sbi, __fs32 n) 1898c2ecf20Sopenharmony_ci{ 1908c2ecf20Sopenharmony_ci if (sbi->s_bytesex == BYTESEX_PDP) 1918c2ecf20Sopenharmony_ci return PDP_swab((__force __u32)n); 1928c2ecf20Sopenharmony_ci else if (sbi->s_bytesex == BYTESEX_LE) 1938c2ecf20Sopenharmony_ci return le32_to_cpu((__force __le32)n); 1948c2ecf20Sopenharmony_ci else 1958c2ecf20Sopenharmony_ci return be32_to_cpu((__force __be32)n); 1968c2ecf20Sopenharmony_ci} 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic inline __fs32 cpu_to_fs32(struct sysv_sb_info *sbi, __u32 n) 1998c2ecf20Sopenharmony_ci{ 2008c2ecf20Sopenharmony_ci if (sbi->s_bytesex == BYTESEX_PDP) 2018c2ecf20Sopenharmony_ci return (__force __fs32)PDP_swab(n); 2028c2ecf20Sopenharmony_ci else if (sbi->s_bytesex == BYTESEX_LE) 2038c2ecf20Sopenharmony_ci return (__force __fs32)cpu_to_le32(n); 2048c2ecf20Sopenharmony_ci else 2058c2ecf20Sopenharmony_ci return (__force __fs32)cpu_to_be32(n); 2068c2ecf20Sopenharmony_ci} 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_cistatic inline __fs32 fs32_add(struct sysv_sb_info *sbi, __fs32 *n, int d) 2098c2ecf20Sopenharmony_ci{ 2108c2ecf20Sopenharmony_ci if (sbi->s_bytesex == BYTESEX_PDP) 2118c2ecf20Sopenharmony_ci *(__u32*)n = PDP_swab(PDP_swab(*(__u32*)n)+d); 2128c2ecf20Sopenharmony_ci else if (sbi->s_bytesex == BYTESEX_LE) 2138c2ecf20Sopenharmony_ci le32_add_cpu((__le32 *)n, d); 2148c2ecf20Sopenharmony_ci else 2158c2ecf20Sopenharmony_ci be32_add_cpu((__be32 *)n, d); 2168c2ecf20Sopenharmony_ci return *n; 2178c2ecf20Sopenharmony_ci} 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_cistatic inline __u16 fs16_to_cpu(struct sysv_sb_info *sbi, __fs16 n) 2208c2ecf20Sopenharmony_ci{ 2218c2ecf20Sopenharmony_ci if (sbi->s_bytesex != BYTESEX_BE) 2228c2ecf20Sopenharmony_ci return le16_to_cpu((__force __le16)n); 2238c2ecf20Sopenharmony_ci else 2248c2ecf20Sopenharmony_ci return be16_to_cpu((__force __be16)n); 2258c2ecf20Sopenharmony_ci} 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_cistatic inline __fs16 cpu_to_fs16(struct sysv_sb_info *sbi, __u16 n) 2288c2ecf20Sopenharmony_ci{ 2298c2ecf20Sopenharmony_ci if (sbi->s_bytesex != BYTESEX_BE) 2308c2ecf20Sopenharmony_ci return (__force __fs16)cpu_to_le16(n); 2318c2ecf20Sopenharmony_ci else 2328c2ecf20Sopenharmony_ci return (__force __fs16)cpu_to_be16(n); 2338c2ecf20Sopenharmony_ci} 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cistatic inline __fs16 fs16_add(struct sysv_sb_info *sbi, __fs16 *n, int d) 2368c2ecf20Sopenharmony_ci{ 2378c2ecf20Sopenharmony_ci if (sbi->s_bytesex != BYTESEX_BE) 2388c2ecf20Sopenharmony_ci le16_add_cpu((__le16 *)n, d); 2398c2ecf20Sopenharmony_ci else 2408c2ecf20Sopenharmony_ci be16_add_cpu((__be16 *)n, d); 2418c2ecf20Sopenharmony_ci return *n; 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci#endif /* _SYSV_H */ 245