Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'vfs-6.15-rc1.sysv' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs sysv removal from Christian Brauner:
"This removes the sysv filesystem. We've discussed this various times.

It's time to try"

* tag 'vfs-6.15-rc1.sysv' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
sysv: Remove the filesystem

-3472
-1
Documentation/filesystems/index.rst
··· 118 118 spufs/index 119 119 squashfs 120 120 sysfs 121 - sysv-fs 122 121 tmpfs 123 122 ubifs 124 123 ubifs-authentication
-264
Documentation/filesystems/sysv-fs.rst
··· 1 - .. SPDX-License-Identifier: GPL-2.0 2 - 3 - ================== 4 - SystemV Filesystem 5 - ================== 6 - 7 - It implements all of 8 - - Xenix FS, 9 - - SystemV/386 FS, 10 - - Coherent FS. 11 - 12 - To install: 13 - 14 - * Answer the 'System V and Coherent filesystem support' question with 'y' 15 - when configuring the kernel. 16 - * To mount a disk or a partition, use:: 17 - 18 - mount [-r] -t sysv device mountpoint 19 - 20 - The file system type names:: 21 - 22 - -t sysv 23 - -t xenix 24 - -t coherent 25 - 26 - may be used interchangeably, but the last two will eventually disappear. 27 - 28 - Bugs in the present implementation: 29 - 30 - - Coherent FS: 31 - 32 - - The "free list interleave" n:m is currently ignored. 33 - - Only file systems with no filesystem name and no pack name are recognized. 34 - (See Coherent "man mkfs" for a description of these features.) 35 - 36 - - SystemV Release 2 FS: 37 - 38 - The superblock is only searched in the blocks 9, 15, 18, which 39 - corresponds to the beginning of track 1 on floppy disks. No support 40 - for this FS on hard disk yet. 41 - 42 - 43 - These filesystems are rather similar. Here is a comparison with Minix FS: 44 - 45 - * Linux fdisk reports on partitions 46 - 47 - - Minix FS 0x81 Linux/Minix 48 - - Xenix FS ?? 49 - - SystemV FS ?? 50 - - Coherent FS 0x08 AIX bootable 51 - 52 - * Size of a block or zone (data allocation unit on disk) 53 - 54 - - Minix FS 1024 55 - - Xenix FS 1024 (also 512 ??) 56 - - SystemV FS 1024 (also 512 and 2048) 57 - - Coherent FS 512 58 - 59 - * General layout: all have one boot block, one super block and 60 - separate areas for inodes and for directories/data. 61 - On SystemV Release 2 FS (e.g. Microport) the first track is reserved and 62 - all the block numbers (including the super block) are offset by one track. 63 - 64 - * Byte ordering of "short" (16 bit entities) on disk: 65 - 66 - - Minix FS little endian 0 1 67 - - Xenix FS little endian 0 1 68 - - SystemV FS little endian 0 1 69 - - Coherent FS little endian 0 1 70 - 71 - Of course, this affects only the file system, not the data of files on it! 72 - 73 - * Byte ordering of "long" (32 bit entities) on disk: 74 - 75 - - Minix FS little endian 0 1 2 3 76 - - Xenix FS little endian 0 1 2 3 77 - - SystemV FS little endian 0 1 2 3 78 - - Coherent FS PDP-11 2 3 0 1 79 - 80 - Of course, this affects only the file system, not the data of files on it! 81 - 82 - * Inode on disk: "short", 0 means non-existent, the root dir ino is: 83 - 84 - ================================= == 85 - Minix FS 1 86 - Xenix FS, SystemV FS, Coherent FS 2 87 - ================================= == 88 - 89 - * Maximum number of hard links to a file: 90 - 91 - =========== ========= 92 - Minix FS 250 93 - Xenix FS ?? 94 - SystemV FS ?? 95 - Coherent FS >=10000 96 - =========== ========= 97 - 98 - * Free inode management: 99 - 100 - - Minix FS 101 - a bitmap 102 - - Xenix FS, SystemV FS, Coherent FS 103 - There is a cache of a certain number of free inodes in the super-block. 104 - When it is exhausted, new free inodes are found using a linear search. 105 - 106 - * Free block management: 107 - 108 - - Minix FS 109 - a bitmap 110 - - Xenix FS, SystemV FS, Coherent FS 111 - Free blocks are organized in a "free list". Maybe a misleading term, 112 - since it is not true that every free block contains a pointer to 113 - the next free block. Rather, the free blocks are organized in chunks 114 - of limited size, and every now and then a free block contains pointers 115 - to the free blocks pertaining to the next chunk; the first of these 116 - contains pointers and so on. The list terminates with a "block number" 117 - 0 on Xenix FS and SystemV FS, with a block zeroed out on Coherent FS. 118 - 119 - * Super-block location: 120 - 121 - =========== ========================== 122 - Minix FS block 1 = bytes 1024..2047 123 - Xenix FS block 1 = bytes 1024..2047 124 - SystemV FS bytes 512..1023 125 - Coherent FS block 1 = bytes 512..1023 126 - =========== ========================== 127 - 128 - * Super-block layout: 129 - 130 - - Minix FS:: 131 - 132 - unsigned short s_ninodes; 133 - unsigned short s_nzones; 134 - unsigned short s_imap_blocks; 135 - unsigned short s_zmap_blocks; 136 - unsigned short s_firstdatazone; 137 - unsigned short s_log_zone_size; 138 - unsigned long s_max_size; 139 - unsigned short s_magic; 140 - 141 - - Xenix FS, SystemV FS, Coherent FS:: 142 - 143 - unsigned short s_firstdatazone; 144 - unsigned long s_nzones; 145 - unsigned short s_fzone_count; 146 - unsigned long s_fzones[NICFREE]; 147 - unsigned short s_finode_count; 148 - unsigned short s_finodes[NICINOD]; 149 - char s_flock; 150 - char s_ilock; 151 - char s_modified; 152 - char s_rdonly; 153 - unsigned long s_time; 154 - short s_dinfo[4]; -- SystemV FS only 155 - unsigned long s_free_zones; 156 - unsigned short s_free_inodes; 157 - short s_dinfo[4]; -- Xenix FS only 158 - unsigned short s_interleave_m,s_interleave_n; -- Coherent FS only 159 - char s_fname[6]; 160 - char s_fpack[6]; 161 - 162 - then they differ considerably: 163 - 164 - Xenix FS:: 165 - 166 - char s_clean; 167 - char s_fill[371]; 168 - long s_magic; 169 - long s_type; 170 - 171 - SystemV FS:: 172 - 173 - long s_fill[12 or 14]; 174 - long s_state; 175 - long s_magic; 176 - long s_type; 177 - 178 - Coherent FS:: 179 - 180 - unsigned long s_unique; 181 - 182 - Note that Coherent FS has no magic. 183 - 184 - * Inode layout: 185 - 186 - - Minix FS:: 187 - 188 - unsigned short i_mode; 189 - unsigned short i_uid; 190 - unsigned long i_size; 191 - unsigned long i_time; 192 - unsigned char i_gid; 193 - unsigned char i_nlinks; 194 - unsigned short i_zone[7+1+1]; 195 - 196 - - Xenix FS, SystemV FS, Coherent FS:: 197 - 198 - unsigned short i_mode; 199 - unsigned short i_nlink; 200 - unsigned short i_uid; 201 - unsigned short i_gid; 202 - unsigned long i_size; 203 - unsigned char i_zone[3*(10+1+1+1)]; 204 - unsigned long i_atime; 205 - unsigned long i_mtime; 206 - unsigned long i_ctime; 207 - 208 - 209 - * Regular file data blocks are organized as 210 - 211 - - Minix FS: 212 - 213 - - 7 direct blocks 214 - - 1 indirect block (pointers to blocks) 215 - - 1 double-indirect block (pointer to pointers to blocks) 216 - 217 - - Xenix FS, SystemV FS, Coherent FS: 218 - 219 - - 10 direct blocks 220 - - 1 indirect block (pointers to blocks) 221 - - 1 double-indirect block (pointer to pointers to blocks) 222 - - 1 triple-indirect block (pointer to pointers to pointers to blocks) 223 - 224 - 225 - =========== ========== ================ 226 - Inode size inodes per block 227 - =========== ========== ================ 228 - Minix FS 32 32 229 - Xenix FS 64 16 230 - SystemV FS 64 16 231 - Coherent FS 64 8 232 - =========== ========== ================ 233 - 234 - * Directory entry on disk 235 - 236 - - Minix FS:: 237 - 238 - unsigned short inode; 239 - char name[14/30]; 240 - 241 - - Xenix FS, SystemV FS, Coherent FS:: 242 - 243 - unsigned short inode; 244 - char name[14]; 245 - 246 - =========== ============== ===================== 247 - Dir entry size dir entries per block 248 - =========== ============== ===================== 249 - Minix FS 16/32 64/32 250 - Xenix FS 16 64 251 - SystemV FS 16 64 252 - Coherent FS 16 32 253 - =========== ============== ===================== 254 - 255 - * How to implement symbolic links such that the host fsck doesn't scream: 256 - 257 - - Minix FS normal 258 - - Xenix FS kludge: as regular files with chmod 1000 259 - - SystemV FS ?? 260 - - Coherent FS kludge: as regular files with chmod 1000 261 - 262 - 263 - Notation: We often speak of a "block" but mean a zone (the allocation unit) 264 - and not the disk driver's notion of "block".
-6
MAINTAINERS
··· 23119 23119 S: Maintained 23120 23120 F: drivers/platform/x86/system76_acpi.c 23121 23121 23122 - SYSV FILESYSTEM 23123 - S: Orphan 23124 - F: Documentation/filesystems/sysv-fs.rst 23125 - F: fs/sysv/ 23126 - F: include/linux/sysv_fs.h 23127 - 23128 23122 TASKSTATS STATISTICS INTERFACE 23129 23123 M: Balbir Singh <bsingharora@gmail.com> 23130 23124 S: Maintained
-1
arch/loongarch/configs/loongson3_defconfig
··· 981 981 CONFIG_ROMFS_FS=m 982 982 CONFIG_PSTORE=m 983 983 CONFIG_PSTORE_COMPRESS=y 984 - CONFIG_SYSV_FS=m 985 984 CONFIG_UFS_FS=m 986 985 CONFIG_EROFS_FS=m 987 986 CONFIG_EROFS_FS_ZIP_LZMA=y
-1
arch/m68k/configs/amiga_defconfig
··· 486 486 CONFIG_HPFS_FS=m 487 487 CONFIG_QNX4FS_FS=m 488 488 CONFIG_QNX6FS_FS=m 489 - CONFIG_SYSV_FS=m 490 489 CONFIG_UFS_FS=m 491 490 CONFIG_EROFS_FS=m 492 491 CONFIG_NFS_FS=y
-1
arch/m68k/configs/apollo_defconfig
··· 443 443 CONFIG_HPFS_FS=m 444 444 CONFIG_QNX4FS_FS=m 445 445 CONFIG_QNX6FS_FS=m 446 - CONFIG_SYSV_FS=m 447 446 CONFIG_UFS_FS=m 448 447 CONFIG_EROFS_FS=m 449 448 CONFIG_NFS_FS=y
-1
arch/m68k/configs/atari_defconfig
··· 463 463 CONFIG_HPFS_FS=m 464 464 CONFIG_QNX4FS_FS=m 465 465 CONFIG_QNX6FS_FS=m 466 - CONFIG_SYSV_FS=m 467 466 CONFIG_UFS_FS=m 468 467 CONFIG_EROFS_FS=m 469 468 CONFIG_NFS_FS=y
-1
arch/m68k/configs/bvme6000_defconfig
··· 435 435 CONFIG_HPFS_FS=m 436 436 CONFIG_QNX4FS_FS=m 437 437 CONFIG_QNX6FS_FS=m 438 - CONFIG_SYSV_FS=m 439 438 CONFIG_UFS_FS=m 440 439 CONFIG_EROFS_FS=m 441 440 CONFIG_NFS_FS=y
-1
arch/m68k/configs/hp300_defconfig
··· 445 445 CONFIG_HPFS_FS=m 446 446 CONFIG_QNX4FS_FS=m 447 447 CONFIG_QNX6FS_FS=m 448 - CONFIG_SYSV_FS=m 449 448 CONFIG_UFS_FS=m 450 449 CONFIG_EROFS_FS=m 451 450 CONFIG_NFS_FS=y
-1
arch/m68k/configs/mac_defconfig
··· 462 462 CONFIG_HPFS_FS=m 463 463 CONFIG_QNX4FS_FS=m 464 464 CONFIG_QNX6FS_FS=m 465 - CONFIG_SYSV_FS=m 466 465 CONFIG_UFS_FS=m 467 466 CONFIG_EROFS_FS=m 468 467 CONFIG_NFS_FS=y
-1
arch/m68k/configs/multi_defconfig
··· 549 549 CONFIG_HPFS_FS=m 550 550 CONFIG_QNX4FS_FS=m 551 551 CONFIG_QNX6FS_FS=m 552 - CONFIG_SYSV_FS=m 553 552 CONFIG_UFS_FS=m 554 553 CONFIG_EROFS_FS=m 555 554 CONFIG_NFS_FS=y
-1
arch/m68k/configs/mvme147_defconfig
··· 435 435 CONFIG_HPFS_FS=m 436 436 CONFIG_QNX4FS_FS=m 437 437 CONFIG_QNX6FS_FS=m 438 - CONFIG_SYSV_FS=m 439 438 CONFIG_UFS_FS=m 440 439 CONFIG_EROFS_FS=m 441 440 CONFIG_NFS_FS=y
-1
arch/m68k/configs/mvme16x_defconfig
··· 436 436 CONFIG_HPFS_FS=m 437 437 CONFIG_QNX4FS_FS=m 438 438 CONFIG_QNX6FS_FS=m 439 - CONFIG_SYSV_FS=m 440 439 CONFIG_UFS_FS=m 441 440 CONFIG_EROFS_FS=m 442 441 CONFIG_NFS_FS=y
-1
arch/m68k/configs/q40_defconfig
··· 452 452 CONFIG_HPFS_FS=m 453 453 CONFIG_QNX4FS_FS=m 454 454 CONFIG_QNX6FS_FS=m 455 - CONFIG_SYSV_FS=m 456 455 CONFIG_UFS_FS=m 457 456 CONFIG_EROFS_FS=m 458 457 CONFIG_NFS_FS=y
-1
arch/m68k/configs/sun3_defconfig
··· 433 433 CONFIG_HPFS_FS=m 434 434 CONFIG_QNX4FS_FS=m 435 435 CONFIG_QNX6FS_FS=m 436 - CONFIG_SYSV_FS=m 437 436 CONFIG_UFS_FS=m 438 437 CONFIG_EROFS_FS=m 439 438 CONFIG_NFS_FS=y
-1
arch/m68k/configs/sun3x_defconfig
··· 433 433 CONFIG_HPFS_FS=m 434 434 CONFIG_QNX4FS_FS=m 435 435 CONFIG_QNX6FS_FS=m 436 - CONFIG_SYSV_FS=m 437 436 CONFIG_UFS_FS=m 438 437 CONFIG_EROFS_FS=m 439 438 CONFIG_NFS_FS=y
-1
arch/mips/configs/malta_defconfig
··· 347 347 CONFIG_VXFS_FS=m 348 348 CONFIG_MINIX_FS=m 349 349 CONFIG_ROMFS_FS=m 350 - CONFIG_SYSV_FS=m 351 350 CONFIG_UFS_FS=m 352 351 CONFIG_NFS_FS=y 353 352 CONFIG_ROOT_NFS=y
-1
arch/mips/configs/malta_kvm_defconfig
··· 354 354 CONFIG_VXFS_FS=m 355 355 CONFIG_MINIX_FS=m 356 356 CONFIG_ROMFS_FS=m 357 - CONFIG_SYSV_FS=m 358 357 CONFIG_UFS_FS=m 359 358 CONFIG_NFS_FS=y 360 359 CONFIG_ROOT_NFS=y
-1
arch/mips/configs/maltaup_xpa_defconfig
··· 353 353 CONFIG_VXFS_FS=m 354 354 CONFIG_MINIX_FS=m 355 355 CONFIG_ROMFS_FS=m 356 - CONFIG_SYSV_FS=m 357 356 CONFIG_UFS_FS=m 358 357 CONFIG_NFS_FS=y 359 358 CONFIG_ROOT_NFS=y
-1
arch/mips/configs/rm200_defconfig
··· 336 336 CONFIG_HPFS_FS=m 337 337 CONFIG_QNX4FS_FS=m 338 338 CONFIG_ROMFS_FS=m 339 - CONFIG_SYSV_FS=m 340 339 CONFIG_UFS_FS=m 341 340 CONFIG_NFS_FS=m 342 341 CONFIG_NFSD=m
-1
arch/parisc/configs/generic-64bit_defconfig
··· 268 268 CONFIG_TMPFS=y 269 269 CONFIG_TMPFS_XATTR=y 270 270 CONFIG_CONFIGFS_FS=y 271 - CONFIG_SYSV_FS=y 272 271 CONFIG_NFS_FS=m 273 272 CONFIG_NFS_V4=m 274 273 CONFIG_NFS_V4_1=y
-1
arch/powerpc/configs/fsl-emb-nonhw.config
··· 112 112 CONFIG_RCU_TRACE=y 113 113 CONFIG_RESET_CONTROLLER=y 114 114 CONFIG_ROOT_NFS=y 115 - CONFIG_SYSV_FS=m 116 115 CONFIG_SYSVIPC=y 117 116 CONFIG_TMPFS=y 118 117 CONFIG_UBIFS_FS=y
-1
arch/powerpc/configs/ppc6xx_defconfig
··· 986 986 CONFIG_OMFS_FS=m 987 987 CONFIG_QNX4FS_FS=m 988 988 CONFIG_ROMFS_FS=m 989 - CONFIG_SYSV_FS=m 990 989 CONFIG_UFS_FS=m 991 990 CONFIG_NFS_FS=m 992 991 CONFIG_NFS_V3_ACL=y
-1
fs/Kconfig
··· 336 336 source "fs/qnx6/Kconfig" 337 337 source "fs/romfs/Kconfig" 338 338 source "fs/pstore/Kconfig" 339 - source "fs/sysv/Kconfig" 340 339 source "fs/ufs/Kconfig" 341 340 source "fs/erofs/Kconfig" 342 341 source "fs/vboxsf/Kconfig"
-1
fs/Makefile
··· 87 87 obj-$(CONFIG_LOCKD) += lockd/ 88 88 obj-$(CONFIG_NLS) += nls/ 89 89 obj-y += unicode/ 90 - obj-$(CONFIG_SYSV_FS) += sysv/ 91 90 obj-$(CONFIG_SMBFS) += smb/ 92 91 obj-$(CONFIG_HPFS_FS) += hpfs/ 93 92 obj-$(CONFIG_NTFS3_FS) += ntfs3/
-38
fs/sysv/Kconfig
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - config SYSV_FS 3 - tristate "System V/Xenix/V7/Coherent file system support" 4 - depends on BLOCK 5 - select BUFFER_HEAD 6 - help 7 - SCO, Xenix and Coherent are commercial Unix systems for Intel 8 - machines, and Version 7 was used on the DEC PDP-11. Saying Y 9 - here would allow you to read from their floppies and hard disk 10 - partitions. 11 - 12 - If you have floppies or hard disk partitions like that, it is likely 13 - that they contain binaries from those other Unix systems; in order 14 - to run these binaries, you will want to install linux-abi which is 15 - a set of kernel modules that lets you run SCO, Xenix, Wyse, 16 - UnixWare, Dell Unix and System V programs under Linux. It is 17 - available via FTP (user: ftp) from 18 - <ftp://ftp.openlinux.org/pub/people/hch/linux-abi/>). 19 - NOTE: that will work only for binaries from Intel-based systems; 20 - PDP ones will have to wait until somebody ports Linux to -11 ;-) 21 - 22 - If you only intend to mount files from some other Unix over the 23 - network using NFS, you don't need the System V file system support 24 - (but you need NFS file system support obviously). 25 - 26 - Note that this option is generally not needed for floppies, since a 27 - good portable way to transport files and directories between unixes 28 - (and even other operating systems) is given by the tar program ("man 29 - tar" or preferably "info tar"). Note also that this option has 30 - nothing whatsoever to do with the option "System V IPC". Read about 31 - the System V file system in 32 - <file:Documentation/filesystems/sysv-fs.rst>. 33 - Saying Y here will enlarge your kernel by about 27 KB. 34 - 35 - To compile this as a module, choose M here: the module will be called 36 - sysv. 37 - 38 - If you haven't heard about all of this before, it's safe to say N.
-9
fs/sysv/Makefile
··· 1 - # SPDX-License-Identifier: GPL-2.0-only 2 - # 3 - # Makefile for the Linux SystemV/Coherent filesystem routines. 4 - # 5 - 6 - obj-$(CONFIG_SYSV_FS) += sysv.o 7 - 8 - sysv-objs := ialloc.o balloc.o inode.o itree.o file.o dir.o \ 9 - namei.o super.o
-240
fs/sysv/balloc.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * linux/fs/sysv/balloc.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/balloc.c 18 - * Copyright (C) 1993 Bruno Haible 19 - * 20 - * This file contains code for allocating/freeing blocks. 21 - */ 22 - 23 - #include <linux/buffer_head.h> 24 - #include <linux/string.h> 25 - #include "sysv.h" 26 - 27 - /* We don't trust the value of 28 - sb->sv_sbd2->s_tfree = *sb->sv_free_blocks 29 - but we nevertheless keep it up to date. */ 30 - 31 - static inline sysv_zone_t *get_chunk(struct super_block *sb, struct buffer_head *bh) 32 - { 33 - char *bh_data = bh->b_data; 34 - 35 - if (SYSV_SB(sb)->s_type == FSTYPE_SYSV4) 36 - return (sysv_zone_t*)(bh_data+4); 37 - else 38 - return (sysv_zone_t*)(bh_data+2); 39 - } 40 - 41 - /* NOTE NOTE NOTE: nr is a block number _as_ _stored_ _on_ _disk_ */ 42 - 43 - void sysv_free_block(struct super_block * sb, sysv_zone_t nr) 44 - { 45 - struct sysv_sb_info * sbi = SYSV_SB(sb); 46 - struct buffer_head * bh; 47 - sysv_zone_t *blocks = sbi->s_bcache; 48 - unsigned count; 49 - unsigned block = fs32_to_cpu(sbi, nr); 50 - 51 - /* 52 - * This code does not work at all for AFS (it has a bitmap 53 - * free list). As AFS is supposed to be read-only no one 54 - * should call this for an AFS filesystem anyway... 55 - */ 56 - if (sbi->s_type == FSTYPE_AFS) 57 - return; 58 - 59 - if (block < sbi->s_firstdatazone || block >= sbi->s_nzones) { 60 - printk("sysv_free_block: trying to free block not in datazone\n"); 61 - return; 62 - } 63 - 64 - mutex_lock(&sbi->s_lock); 65 - count = fs16_to_cpu(sbi, *sbi->s_bcache_count); 66 - 67 - if (count > sbi->s_flc_size) { 68 - printk("sysv_free_block: flc_count > flc_size\n"); 69 - mutex_unlock(&sbi->s_lock); 70 - return; 71 - } 72 - /* If the free list head in super-block is full, it is copied 73 - * into this block being freed, ditto if it's completely empty 74 - * (applies only on Coherent). 75 - */ 76 - if (count == sbi->s_flc_size || count == 0) { 77 - block += sbi->s_block_base; 78 - bh = sb_getblk(sb, block); 79 - if (!bh) { 80 - printk("sysv_free_block: getblk() failed\n"); 81 - mutex_unlock(&sbi->s_lock); 82 - return; 83 - } 84 - memset(bh->b_data, 0, sb->s_blocksize); 85 - *(__fs16*)bh->b_data = cpu_to_fs16(sbi, count); 86 - memcpy(get_chunk(sb,bh), blocks, count * sizeof(sysv_zone_t)); 87 - mark_buffer_dirty(bh); 88 - set_buffer_uptodate(bh); 89 - brelse(bh); 90 - count = 0; 91 - } 92 - sbi->s_bcache[count++] = nr; 93 - 94 - *sbi->s_bcache_count = cpu_to_fs16(sbi, count); 95 - fs32_add(sbi, sbi->s_free_blocks, 1); 96 - dirty_sb(sb); 97 - mutex_unlock(&sbi->s_lock); 98 - } 99 - 100 - sysv_zone_t sysv_new_block(struct super_block * sb) 101 - { 102 - struct sysv_sb_info *sbi = SYSV_SB(sb); 103 - unsigned int block; 104 - sysv_zone_t nr; 105 - struct buffer_head * bh; 106 - unsigned count; 107 - 108 - mutex_lock(&sbi->s_lock); 109 - count = fs16_to_cpu(sbi, *sbi->s_bcache_count); 110 - 111 - if (count == 0) /* Applies only to Coherent FS */ 112 - goto Enospc; 113 - nr = sbi->s_bcache[--count]; 114 - if (nr == 0) /* Applies only to Xenix FS, SystemV FS */ 115 - goto Enospc; 116 - 117 - block = fs32_to_cpu(sbi, nr); 118 - 119 - *sbi->s_bcache_count = cpu_to_fs16(sbi, count); 120 - 121 - if (block < sbi->s_firstdatazone || block >= sbi->s_nzones) { 122 - printk("sysv_new_block: new block %d is not in data zone\n", 123 - block); 124 - goto Enospc; 125 - } 126 - 127 - if (count == 0) { /* the last block continues the free list */ 128 - unsigned count; 129 - 130 - block += sbi->s_block_base; 131 - if (!(bh = sb_bread(sb, block))) { 132 - printk("sysv_new_block: cannot read free-list block\n"); 133 - /* retry this same block next time */ 134 - *sbi->s_bcache_count = cpu_to_fs16(sbi, 1); 135 - goto Enospc; 136 - } 137 - count = fs16_to_cpu(sbi, *(__fs16*)bh->b_data); 138 - if (count > sbi->s_flc_size) { 139 - printk("sysv_new_block: free-list block with >flc_size entries\n"); 140 - brelse(bh); 141 - goto Enospc; 142 - } 143 - *sbi->s_bcache_count = cpu_to_fs16(sbi, count); 144 - memcpy(sbi->s_bcache, get_chunk(sb, bh), 145 - count * sizeof(sysv_zone_t)); 146 - brelse(bh); 147 - } 148 - /* Now the free list head in the superblock is valid again. */ 149 - fs32_add(sbi, sbi->s_free_blocks, -1); 150 - dirty_sb(sb); 151 - mutex_unlock(&sbi->s_lock); 152 - return nr; 153 - 154 - Enospc: 155 - mutex_unlock(&sbi->s_lock); 156 - return 0; 157 - } 158 - 159 - unsigned long sysv_count_free_blocks(struct super_block * sb) 160 - { 161 - struct sysv_sb_info * sbi = SYSV_SB(sb); 162 - int sb_count; 163 - int count; 164 - struct buffer_head * bh = NULL; 165 - sysv_zone_t *blocks; 166 - unsigned block; 167 - int n; 168 - 169 - /* 170 - * This code does not work at all for AFS (it has a bitmap 171 - * free list). As AFS is supposed to be read-only we just 172 - * lie and say it has no free block at all. 173 - */ 174 - if (sbi->s_type == FSTYPE_AFS) 175 - return 0; 176 - 177 - mutex_lock(&sbi->s_lock); 178 - sb_count = fs32_to_cpu(sbi, *sbi->s_free_blocks); 179 - 180 - if (0) 181 - goto trust_sb; 182 - 183 - /* this causes a lot of disk traffic ... */ 184 - count = 0; 185 - n = fs16_to_cpu(sbi, *sbi->s_bcache_count); 186 - blocks = sbi->s_bcache; 187 - while (1) { 188 - sysv_zone_t zone; 189 - if (n > sbi->s_flc_size) 190 - goto E2big; 191 - zone = 0; 192 - while (n && (zone = blocks[--n]) != 0) 193 - count++; 194 - if (zone == 0) 195 - break; 196 - 197 - block = fs32_to_cpu(sbi, zone); 198 - if (bh) 199 - brelse(bh); 200 - 201 - if (block < sbi->s_firstdatazone || block >= sbi->s_nzones) 202 - goto Einval; 203 - block += sbi->s_block_base; 204 - bh = sb_bread(sb, block); 205 - if (!bh) 206 - goto Eio; 207 - n = fs16_to_cpu(sbi, *(__fs16*)bh->b_data); 208 - blocks = get_chunk(sb, bh); 209 - } 210 - if (bh) 211 - brelse(bh); 212 - if (count != sb_count) 213 - goto Ecount; 214 - done: 215 - mutex_unlock(&sbi->s_lock); 216 - return count; 217 - 218 - Einval: 219 - printk("sysv_count_free_blocks: new block %d is not in data zone\n", 220 - block); 221 - goto trust_sb; 222 - Eio: 223 - printk("sysv_count_free_blocks: cannot read free-list block\n"); 224 - goto trust_sb; 225 - E2big: 226 - printk("sysv_count_free_blocks: >flc_size entries in free-list block\n"); 227 - if (bh) 228 - brelse(bh); 229 - trust_sb: 230 - count = sb_count; 231 - goto done; 232 - Ecount: 233 - printk("sysv_count_free_blocks: free block count was %d, " 234 - "correcting to %d\n", sb_count, count); 235 - if (!sb_rdonly(sb)) { 236 - *sbi->s_free_blocks = cpu_to_fs32(sbi, count); 237 - dirty_sb(sb); 238 - } 239 - goto done; 240 - }
-378
fs/sysv/dir.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * linux/fs/sysv/dir.c 4 - * 5 - * minix/dir.c 6 - * Copyright (C) 1991, 1992 Linus Torvalds 7 - * 8 - * coh/dir.c 9 - * Copyright (C) 1993 Pascal Haible, Bruno Haible 10 - * 11 - * sysv/dir.c 12 - * Copyright (C) 1993 Bruno Haible 13 - * 14 - * SystemV/Coherent directory handling functions 15 - */ 16 - 17 - #include <linux/pagemap.h> 18 - #include <linux/highmem.h> 19 - #include <linux/swap.h> 20 - #include "sysv.h" 21 - 22 - static int sysv_readdir(struct file *, struct dir_context *); 23 - 24 - const struct file_operations sysv_dir_operations = { 25 - .llseek = generic_file_llseek, 26 - .read = generic_read_dir, 27 - .iterate_shared = sysv_readdir, 28 - .fsync = generic_file_fsync, 29 - }; 30 - 31 - static void dir_commit_chunk(struct folio *folio, loff_t pos, unsigned len) 32 - { 33 - struct address_space *mapping = folio->mapping; 34 - struct inode *dir = mapping->host; 35 - 36 - block_write_end(NULL, mapping, pos, len, len, folio, NULL); 37 - if (pos+len > dir->i_size) { 38 - i_size_write(dir, pos+len); 39 - mark_inode_dirty(dir); 40 - } 41 - folio_unlock(folio); 42 - } 43 - 44 - static int sysv_handle_dirsync(struct inode *dir) 45 - { 46 - int err; 47 - 48 - err = filemap_write_and_wait(dir->i_mapping); 49 - if (!err) 50 - err = sync_inode_metadata(dir, 1); 51 - return err; 52 - } 53 - 54 - /* 55 - * Calls to dir_get_folio()/folio_release_kmap() must be nested according to the 56 - * rules documented in mm/highmem.rst. 57 - * 58 - * NOTE: sysv_find_entry() and sysv_dotdot() act as calls to dir_get_folio() 59 - * and must be treated accordingly for nesting purposes. 60 - */ 61 - static void *dir_get_folio(struct inode *dir, unsigned long n, 62 - struct folio **foliop) 63 - { 64 - struct folio *folio = read_mapping_folio(dir->i_mapping, n, NULL); 65 - 66 - if (IS_ERR(folio)) 67 - return ERR_CAST(folio); 68 - *foliop = folio; 69 - return kmap_local_folio(folio, 0); 70 - } 71 - 72 - static int sysv_readdir(struct file *file, struct dir_context *ctx) 73 - { 74 - unsigned long pos = ctx->pos; 75 - struct inode *inode = file_inode(file); 76 - struct super_block *sb = inode->i_sb; 77 - unsigned long npages = dir_pages(inode); 78 - unsigned offset; 79 - unsigned long n; 80 - 81 - ctx->pos = pos = (pos + SYSV_DIRSIZE-1) & ~(SYSV_DIRSIZE-1); 82 - if (pos >= inode->i_size) 83 - return 0; 84 - 85 - offset = pos & ~PAGE_MASK; 86 - n = pos >> PAGE_SHIFT; 87 - 88 - for ( ; n < npages; n++, offset = 0) { 89 - char *kaddr, *limit; 90 - struct sysv_dir_entry *de; 91 - struct folio *folio; 92 - 93 - kaddr = dir_get_folio(inode, n, &folio); 94 - if (IS_ERR(kaddr)) 95 - continue; 96 - de = (struct sysv_dir_entry *)(kaddr+offset); 97 - limit = kaddr + PAGE_SIZE - SYSV_DIRSIZE; 98 - for ( ;(char*)de <= limit; de++, ctx->pos += sizeof(*de)) { 99 - char *name = de->name; 100 - 101 - if (!de->inode) 102 - continue; 103 - 104 - if (!dir_emit(ctx, name, strnlen(name,SYSV_NAMELEN), 105 - fs16_to_cpu(SYSV_SB(sb), de->inode), 106 - DT_UNKNOWN)) { 107 - folio_release_kmap(folio, kaddr); 108 - return 0; 109 - } 110 - } 111 - folio_release_kmap(folio, kaddr); 112 - } 113 - return 0; 114 - } 115 - 116 - /* compare strings: name[0..len-1] (not zero-terminated) and 117 - * buffer[0..] (filled with zeroes up to buffer[0..maxlen-1]) 118 - */ 119 - static inline int namecompare(int len, int maxlen, 120 - const char * name, const char * buffer) 121 - { 122 - if (len < maxlen && buffer[len]) 123 - return 0; 124 - return !memcmp(name, buffer, len); 125 - } 126 - 127 - /* 128 - * sysv_find_entry() 129 - * 130 - * finds an entry in the specified directory with the wanted name. 131 - * It does NOT read the inode of the 132 - * entry - you'll have to do that yourself if you want to. 133 - * 134 - * On Success folio_release_kmap() should be called on *foliop. 135 - * 136 - * sysv_find_entry() acts as a call to dir_get_folio() and must be treated 137 - * accordingly for nesting purposes. 138 - */ 139 - struct sysv_dir_entry *sysv_find_entry(struct dentry *dentry, struct folio **foliop) 140 - { 141 - const char * name = dentry->d_name.name; 142 - int namelen = dentry->d_name.len; 143 - struct inode * dir = d_inode(dentry->d_parent); 144 - unsigned long start, n; 145 - unsigned long npages = dir_pages(dir); 146 - struct sysv_dir_entry *de; 147 - 148 - start = SYSV_I(dir)->i_dir_start_lookup; 149 - if (start >= npages) 150 - start = 0; 151 - n = start; 152 - 153 - do { 154 - char *kaddr = dir_get_folio(dir, n, foliop); 155 - 156 - if (!IS_ERR(kaddr)) { 157 - de = (struct sysv_dir_entry *)kaddr; 158 - kaddr += folio_size(*foliop) - SYSV_DIRSIZE; 159 - for ( ; (char *) de <= kaddr ; de++) { 160 - if (!de->inode) 161 - continue; 162 - if (namecompare(namelen, SYSV_NAMELEN, 163 - name, de->name)) 164 - goto found; 165 - } 166 - folio_release_kmap(*foliop, kaddr); 167 - } 168 - 169 - if (++n >= npages) 170 - n = 0; 171 - } while (n != start); 172 - 173 - return NULL; 174 - 175 - found: 176 - SYSV_I(dir)->i_dir_start_lookup = n; 177 - return de; 178 - } 179 - 180 - int sysv_add_link(struct dentry *dentry, struct inode *inode) 181 - { 182 - struct inode *dir = d_inode(dentry->d_parent); 183 - const char * name = dentry->d_name.name; 184 - int namelen = dentry->d_name.len; 185 - struct folio *folio = NULL; 186 - struct sysv_dir_entry * de; 187 - unsigned long npages = dir_pages(dir); 188 - unsigned long n; 189 - char *kaddr; 190 - loff_t pos; 191 - int err; 192 - 193 - /* We take care of directory expansion in the same loop */ 194 - for (n = 0; n <= npages; n++) { 195 - kaddr = dir_get_folio(dir, n, &folio); 196 - if (IS_ERR(kaddr)) 197 - return PTR_ERR(kaddr); 198 - de = (struct sysv_dir_entry *)kaddr; 199 - kaddr += PAGE_SIZE - SYSV_DIRSIZE; 200 - while ((char *)de <= kaddr) { 201 - if (!de->inode) 202 - goto got_it; 203 - err = -EEXIST; 204 - if (namecompare(namelen, SYSV_NAMELEN, name, de->name)) 205 - goto out_folio; 206 - de++; 207 - } 208 - folio_release_kmap(folio, kaddr); 209 - } 210 - BUG(); 211 - return -EINVAL; 212 - 213 - got_it: 214 - pos = folio_pos(folio) + offset_in_folio(folio, de); 215 - folio_lock(folio); 216 - err = sysv_prepare_chunk(folio, pos, SYSV_DIRSIZE); 217 - if (err) 218 - goto out_unlock; 219 - memcpy (de->name, name, namelen); 220 - memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2); 221 - de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); 222 - dir_commit_chunk(folio, pos, SYSV_DIRSIZE); 223 - inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); 224 - mark_inode_dirty(dir); 225 - err = sysv_handle_dirsync(dir); 226 - out_folio: 227 - folio_release_kmap(folio, kaddr); 228 - return err; 229 - out_unlock: 230 - folio_unlock(folio); 231 - goto out_folio; 232 - } 233 - 234 - int sysv_delete_entry(struct sysv_dir_entry *de, struct folio *folio) 235 - { 236 - struct inode *inode = folio->mapping->host; 237 - loff_t pos = folio_pos(folio) + offset_in_folio(folio, de); 238 - int err; 239 - 240 - folio_lock(folio); 241 - err = sysv_prepare_chunk(folio, pos, SYSV_DIRSIZE); 242 - if (err) { 243 - folio_unlock(folio); 244 - return err; 245 - } 246 - de->inode = 0; 247 - dir_commit_chunk(folio, pos, SYSV_DIRSIZE); 248 - inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); 249 - mark_inode_dirty(inode); 250 - return sysv_handle_dirsync(inode); 251 - } 252 - 253 - int sysv_make_empty(struct inode *inode, struct inode *dir) 254 - { 255 - struct folio *folio = filemap_grab_folio(inode->i_mapping, 0); 256 - struct sysv_dir_entry * de; 257 - char *kaddr; 258 - int err; 259 - 260 - if (IS_ERR(folio)) 261 - return PTR_ERR(folio); 262 - err = sysv_prepare_chunk(folio, 0, 2 * SYSV_DIRSIZE); 263 - if (err) { 264 - folio_unlock(folio); 265 - goto fail; 266 - } 267 - kaddr = kmap_local_folio(folio, 0); 268 - memset(kaddr, 0, folio_size(folio)); 269 - 270 - de = (struct sysv_dir_entry *)kaddr; 271 - de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); 272 - strcpy(de->name,"."); 273 - de++; 274 - de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), dir->i_ino); 275 - strcpy(de->name,".."); 276 - 277 - kunmap_local(kaddr); 278 - dir_commit_chunk(folio, 0, 2 * SYSV_DIRSIZE); 279 - err = sysv_handle_dirsync(inode); 280 - fail: 281 - folio_put(folio); 282 - return err; 283 - } 284 - 285 - /* 286 - * routine to check that the specified directory is empty (for rmdir) 287 - */ 288 - int sysv_empty_dir(struct inode * inode) 289 - { 290 - struct super_block *sb = inode->i_sb; 291 - struct folio *folio = NULL; 292 - unsigned long i, npages = dir_pages(inode); 293 - char *kaddr; 294 - 295 - for (i = 0; i < npages; i++) { 296 - struct sysv_dir_entry *de; 297 - 298 - kaddr = dir_get_folio(inode, i, &folio); 299 - if (IS_ERR(kaddr)) 300 - continue; 301 - 302 - de = (struct sysv_dir_entry *)kaddr; 303 - kaddr += folio_size(folio) - SYSV_DIRSIZE; 304 - 305 - for ( ;(char *)de <= kaddr; de++) { 306 - if (!de->inode) 307 - continue; 308 - /* check for . and .. */ 309 - if (de->name[0] != '.') 310 - goto not_empty; 311 - if (!de->name[1]) { 312 - if (de->inode == cpu_to_fs16(SYSV_SB(sb), 313 - inode->i_ino)) 314 - continue; 315 - goto not_empty; 316 - } 317 - if (de->name[1] != '.' || de->name[2]) 318 - goto not_empty; 319 - } 320 - folio_release_kmap(folio, kaddr); 321 - } 322 - return 1; 323 - 324 - not_empty: 325 - folio_release_kmap(folio, kaddr); 326 - return 0; 327 - } 328 - 329 - /* Releases the page */ 330 - int sysv_set_link(struct sysv_dir_entry *de, struct folio *folio, 331 - struct inode *inode) 332 - { 333 - struct inode *dir = folio->mapping->host; 334 - loff_t pos = folio_pos(folio) + offset_in_folio(folio, de); 335 - int err; 336 - 337 - folio_lock(folio); 338 - err = sysv_prepare_chunk(folio, pos, SYSV_DIRSIZE); 339 - if (err) { 340 - folio_unlock(folio); 341 - return err; 342 - } 343 - de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); 344 - dir_commit_chunk(folio, pos, SYSV_DIRSIZE); 345 - inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir)); 346 - mark_inode_dirty(dir); 347 - return sysv_handle_dirsync(inode); 348 - } 349 - 350 - /* 351 - * Calls to dir_get_folio()/folio_release_kmap() must be nested according to the 352 - * rules documented in mm/highmem.rst. 353 - * 354 - * sysv_dotdot() acts as a call to dir_get_folio() and must be treated 355 - * accordingly for nesting purposes. 356 - */ 357 - struct sysv_dir_entry *sysv_dotdot(struct inode *dir, struct folio **foliop) 358 - { 359 - struct sysv_dir_entry *de = dir_get_folio(dir, 0, foliop); 360 - 361 - if (IS_ERR(de)) 362 - return NULL; 363 - /* ".." is the second directory entry */ 364 - return de + 1; 365 - } 366 - 367 - ino_t sysv_inode_by_name(struct dentry *dentry) 368 - { 369 - struct folio *folio; 370 - struct sysv_dir_entry *de = sysv_find_entry (dentry, &folio); 371 - ino_t res = 0; 372 - 373 - if (de) { 374 - res = fs16_to_cpu(SYSV_SB(dentry->d_sb), de->inode); 375 - folio_release_kmap(folio, de); 376 - } 377 - return res; 378 - }
-59
fs/sysv/file.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * linux/fs/sysv/file.c 4 - * 5 - * minix/file.c 6 - * Copyright (C) 1991, 1992 Linus Torvalds 7 - * 8 - * coh/file.c 9 - * Copyright (C) 1993 Pascal Haible, Bruno Haible 10 - * 11 - * sysv/file.c 12 - * Copyright (C) 1993 Bruno Haible 13 - * 14 - * SystemV/Coherent regular file handling primitives 15 - */ 16 - 17 - #include "sysv.h" 18 - 19 - /* 20 - * We have mostly NULLs here: the current defaults are OK for 21 - * the coh filesystem. 22 - */ 23 - const struct file_operations sysv_file_operations = { 24 - .llseek = generic_file_llseek, 25 - .read_iter = generic_file_read_iter, 26 - .write_iter = generic_file_write_iter, 27 - .mmap = generic_file_mmap, 28 - .fsync = generic_file_fsync, 29 - .splice_read = filemap_splice_read, 30 - }; 31 - 32 - static int sysv_setattr(struct mnt_idmap *idmap, 33 - struct dentry *dentry, struct iattr *attr) 34 - { 35 - struct inode *inode = d_inode(dentry); 36 - int error; 37 - 38 - error = setattr_prepare(&nop_mnt_idmap, dentry, attr); 39 - if (error) 40 - return error; 41 - 42 - if ((attr->ia_valid & ATTR_SIZE) && 43 - attr->ia_size != i_size_read(inode)) { 44 - error = inode_newsize_ok(inode, attr->ia_size); 45 - if (error) 46 - return error; 47 - truncate_setsize(inode, attr->ia_size); 48 - sysv_truncate(inode); 49 - } 50 - 51 - setattr_copy(&nop_mnt_idmap, inode, attr); 52 - mark_inode_dirty(inode); 53 - return 0; 54 - } 55 - 56 - const struct inode_operations sysv_file_inode_operations = { 57 - .setattr = sysv_setattr, 58 - .getattr = sysv_getattr, 59 - };
-235
fs/sysv/ialloc.c
··· 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 - simple_inode_init_ts(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 - }
-354
fs/sysv/inode.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * linux/fs/sysv/inode.c 4 - * 5 - * minix/inode.c 6 - * Copyright (C) 1991, 1992 Linus Torvalds 7 - * 8 - * xenix/inode.c 9 - * Copyright (C) 1992 Doug Evans 10 - * 11 - * coh/inode.c 12 - * Copyright (C) 1993 Pascal Haible, Bruno Haible 13 - * 14 - * sysv/inode.c 15 - * Copyright (C) 1993 Paul B. Monday 16 - * 17 - * sysv/inode.c 18 - * Copyright (C) 1993 Bruno Haible 19 - * Copyright (C) 1997, 1998 Krzysztof G. Baranowski 20 - * 21 - * This file contains code for allocating/freeing inodes and for read/writing 22 - * the superblock. 23 - */ 24 - 25 - #include <linux/highuid.h> 26 - #include <linux/slab.h> 27 - #include <linux/init.h> 28 - #include <linux/buffer_head.h> 29 - #include <linux/vfs.h> 30 - #include <linux/writeback.h> 31 - #include <linux/namei.h> 32 - #include <asm/byteorder.h> 33 - #include "sysv.h" 34 - 35 - static int sysv_sync_fs(struct super_block *sb, int wait) 36 - { 37 - struct sysv_sb_info *sbi = SYSV_SB(sb); 38 - u32 time = (u32)ktime_get_real_seconds(), old_time; 39 - 40 - mutex_lock(&sbi->s_lock); 41 - 42 - /* 43 - * If we are going to write out the super block, 44 - * then attach current time stamp. 45 - * But if the filesystem was marked clean, keep it clean. 46 - */ 47 - old_time = fs32_to_cpu(sbi, *sbi->s_sb_time); 48 - if (sbi->s_type == FSTYPE_SYSV4) { 49 - if (*sbi->s_sb_state == cpu_to_fs32(sbi, 0x7c269d38u - old_time)) 50 - *sbi->s_sb_state = cpu_to_fs32(sbi, 0x7c269d38u - time); 51 - *sbi->s_sb_time = cpu_to_fs32(sbi, time); 52 - mark_buffer_dirty(sbi->s_bh2); 53 - } 54 - 55 - mutex_unlock(&sbi->s_lock); 56 - 57 - return 0; 58 - } 59 - 60 - static int sysv_remount(struct super_block *sb, int *flags, char *data) 61 - { 62 - struct sysv_sb_info *sbi = SYSV_SB(sb); 63 - 64 - sync_filesystem(sb); 65 - if (sbi->s_forced_ro) 66 - *flags |= SB_RDONLY; 67 - return 0; 68 - } 69 - 70 - static void sysv_put_super(struct super_block *sb) 71 - { 72 - struct sysv_sb_info *sbi = SYSV_SB(sb); 73 - 74 - if (!sb_rdonly(sb)) { 75 - /* XXX ext2 also updates the state here */ 76 - mark_buffer_dirty(sbi->s_bh1); 77 - if (sbi->s_bh1 != sbi->s_bh2) 78 - mark_buffer_dirty(sbi->s_bh2); 79 - } 80 - 81 - brelse(sbi->s_bh1); 82 - if (sbi->s_bh1 != sbi->s_bh2) 83 - brelse(sbi->s_bh2); 84 - 85 - kfree(sbi); 86 - } 87 - 88 - static int sysv_statfs(struct dentry *dentry, struct kstatfs *buf) 89 - { 90 - struct super_block *sb = dentry->d_sb; 91 - struct sysv_sb_info *sbi = SYSV_SB(sb); 92 - u64 id = huge_encode_dev(sb->s_bdev->bd_dev); 93 - 94 - buf->f_type = sb->s_magic; 95 - buf->f_bsize = sb->s_blocksize; 96 - buf->f_blocks = sbi->s_ndatazones; 97 - buf->f_bavail = buf->f_bfree = sysv_count_free_blocks(sb); 98 - buf->f_files = sbi->s_ninodes; 99 - buf->f_ffree = sysv_count_free_inodes(sb); 100 - buf->f_namelen = SYSV_NAMELEN; 101 - buf->f_fsid = u64_to_fsid(id); 102 - return 0; 103 - } 104 - 105 - /* 106 - * NXI <-> N0XI for PDP, XIN <-> XIN0 for le32, NIX <-> 0NIX for be32 107 - */ 108 - static inline void read3byte(struct sysv_sb_info *sbi, 109 - unsigned char * from, unsigned char * to) 110 - { 111 - if (sbi->s_bytesex == BYTESEX_PDP) { 112 - to[0] = from[0]; 113 - to[1] = 0; 114 - to[2] = from[1]; 115 - to[3] = from[2]; 116 - } else if (sbi->s_bytesex == BYTESEX_LE) { 117 - to[0] = from[0]; 118 - to[1] = from[1]; 119 - to[2] = from[2]; 120 - to[3] = 0; 121 - } else { 122 - to[0] = 0; 123 - to[1] = from[0]; 124 - to[2] = from[1]; 125 - to[3] = from[2]; 126 - } 127 - } 128 - 129 - static inline void write3byte(struct sysv_sb_info *sbi, 130 - unsigned char * from, unsigned char * to) 131 - { 132 - if (sbi->s_bytesex == BYTESEX_PDP) { 133 - to[0] = from[0]; 134 - to[1] = from[2]; 135 - to[2] = from[3]; 136 - } else if (sbi->s_bytesex == BYTESEX_LE) { 137 - to[0] = from[0]; 138 - to[1] = from[1]; 139 - to[2] = from[2]; 140 - } else { 141 - to[0] = from[1]; 142 - to[1] = from[2]; 143 - to[2] = from[3]; 144 - } 145 - } 146 - 147 - static const struct inode_operations sysv_symlink_inode_operations = { 148 - .get_link = page_get_link, 149 - .getattr = sysv_getattr, 150 - }; 151 - 152 - void sysv_set_inode(struct inode *inode, dev_t rdev) 153 - { 154 - if (S_ISREG(inode->i_mode)) { 155 - inode->i_op = &sysv_file_inode_operations; 156 - inode->i_fop = &sysv_file_operations; 157 - inode->i_mapping->a_ops = &sysv_aops; 158 - } else if (S_ISDIR(inode->i_mode)) { 159 - inode->i_op = &sysv_dir_inode_operations; 160 - inode->i_fop = &sysv_dir_operations; 161 - inode->i_mapping->a_ops = &sysv_aops; 162 - } else if (S_ISLNK(inode->i_mode)) { 163 - inode->i_op = &sysv_symlink_inode_operations; 164 - inode_nohighmem(inode); 165 - inode->i_mapping->a_ops = &sysv_aops; 166 - } else 167 - init_special_inode(inode, inode->i_mode, rdev); 168 - } 169 - 170 - struct inode *sysv_iget(struct super_block *sb, unsigned int ino) 171 - { 172 - struct sysv_sb_info * sbi = SYSV_SB(sb); 173 - struct buffer_head * bh; 174 - struct sysv_inode * raw_inode; 175 - struct sysv_inode_info * si; 176 - struct inode *inode; 177 - unsigned int block; 178 - 179 - if (!ino || ino > sbi->s_ninodes) { 180 - printk("Bad inode number on dev %s: %d is out of range\n", 181 - sb->s_id, ino); 182 - return ERR_PTR(-EIO); 183 - } 184 - 185 - inode = iget_locked(sb, ino); 186 - if (!inode) 187 - return ERR_PTR(-ENOMEM); 188 - if (!(inode->i_state & I_NEW)) 189 - return inode; 190 - 191 - raw_inode = sysv_raw_inode(sb, ino, &bh); 192 - if (!raw_inode) { 193 - printk("Major problem: unable to read inode from dev %s\n", 194 - inode->i_sb->s_id); 195 - goto bad_inode; 196 - } 197 - /* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */ 198 - inode->i_mode = fs16_to_cpu(sbi, raw_inode->i_mode); 199 - i_uid_write(inode, (uid_t)fs16_to_cpu(sbi, raw_inode->i_uid)); 200 - i_gid_write(inode, (gid_t)fs16_to_cpu(sbi, raw_inode->i_gid)); 201 - set_nlink(inode, fs16_to_cpu(sbi, raw_inode->i_nlink)); 202 - inode->i_size = fs32_to_cpu(sbi, raw_inode->i_size); 203 - inode_set_atime(inode, fs32_to_cpu(sbi, raw_inode->i_atime), 0); 204 - inode_set_mtime(inode, fs32_to_cpu(sbi, raw_inode->i_mtime), 0); 205 - inode_set_ctime(inode, fs32_to_cpu(sbi, raw_inode->i_ctime), 0); 206 - inode->i_blocks = 0; 207 - 208 - si = SYSV_I(inode); 209 - for (block = 0; block < 10+1+1+1; block++) 210 - read3byte(sbi, &raw_inode->i_data[3*block], 211 - (u8 *)&si->i_data[block]); 212 - brelse(bh); 213 - si->i_dir_start_lookup = 0; 214 - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) 215 - sysv_set_inode(inode, 216 - old_decode_dev(fs32_to_cpu(sbi, si->i_data[0]))); 217 - else 218 - sysv_set_inode(inode, 0); 219 - unlock_new_inode(inode); 220 - return inode; 221 - 222 - bad_inode: 223 - iget_failed(inode); 224 - return ERR_PTR(-EIO); 225 - } 226 - 227 - static int __sysv_write_inode(struct inode *inode, int wait) 228 - { 229 - struct super_block * sb = inode->i_sb; 230 - struct sysv_sb_info * sbi = SYSV_SB(sb); 231 - struct buffer_head * bh; 232 - struct sysv_inode * raw_inode; 233 - struct sysv_inode_info * si; 234 - unsigned int ino, block; 235 - int err = 0; 236 - 237 - ino = inode->i_ino; 238 - if (!ino || ino > sbi->s_ninodes) { 239 - printk("Bad inode number on dev %s: %d is out of range\n", 240 - inode->i_sb->s_id, ino); 241 - return -EIO; 242 - } 243 - raw_inode = sysv_raw_inode(sb, ino, &bh); 244 - if (!raw_inode) { 245 - printk("unable to read i-node block\n"); 246 - return -EIO; 247 - } 248 - 249 - raw_inode->i_mode = cpu_to_fs16(sbi, inode->i_mode); 250 - raw_inode->i_uid = cpu_to_fs16(sbi, fs_high2lowuid(i_uid_read(inode))); 251 - raw_inode->i_gid = cpu_to_fs16(sbi, fs_high2lowgid(i_gid_read(inode))); 252 - raw_inode->i_nlink = cpu_to_fs16(sbi, inode->i_nlink); 253 - raw_inode->i_size = cpu_to_fs32(sbi, inode->i_size); 254 - raw_inode->i_atime = cpu_to_fs32(sbi, inode_get_atime_sec(inode)); 255 - raw_inode->i_mtime = cpu_to_fs32(sbi, inode_get_mtime_sec(inode)); 256 - raw_inode->i_ctime = cpu_to_fs32(sbi, inode_get_ctime_sec(inode)); 257 - 258 - si = SYSV_I(inode); 259 - if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) 260 - si->i_data[0] = cpu_to_fs32(sbi, old_encode_dev(inode->i_rdev)); 261 - for (block = 0; block < 10+1+1+1; block++) 262 - write3byte(sbi, (u8 *)&si->i_data[block], 263 - &raw_inode->i_data[3*block]); 264 - mark_buffer_dirty(bh); 265 - if (wait) { 266 - sync_dirty_buffer(bh); 267 - if (buffer_req(bh) && !buffer_uptodate(bh)) { 268 - printk ("IO error syncing sysv inode [%s:%08x]\n", 269 - sb->s_id, ino); 270 - err = -EIO; 271 - } 272 - } 273 - brelse(bh); 274 - return err; 275 - } 276 - 277 - int sysv_write_inode(struct inode *inode, struct writeback_control *wbc) 278 - { 279 - return __sysv_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); 280 - } 281 - 282 - int sysv_sync_inode(struct inode *inode) 283 - { 284 - return __sysv_write_inode(inode, 1); 285 - } 286 - 287 - static void sysv_evict_inode(struct inode *inode) 288 - { 289 - truncate_inode_pages_final(&inode->i_data); 290 - if (!inode->i_nlink) { 291 - inode->i_size = 0; 292 - sysv_truncate(inode); 293 - } 294 - invalidate_inode_buffers(inode); 295 - clear_inode(inode); 296 - if (!inode->i_nlink) 297 - sysv_free_inode(inode); 298 - } 299 - 300 - static struct kmem_cache *sysv_inode_cachep; 301 - 302 - static struct inode *sysv_alloc_inode(struct super_block *sb) 303 - { 304 - struct sysv_inode_info *si; 305 - 306 - si = alloc_inode_sb(sb, sysv_inode_cachep, GFP_KERNEL); 307 - if (!si) 308 - return NULL; 309 - return &si->vfs_inode; 310 - } 311 - 312 - static void sysv_free_in_core_inode(struct inode *inode) 313 - { 314 - kmem_cache_free(sysv_inode_cachep, SYSV_I(inode)); 315 - } 316 - 317 - static void init_once(void *p) 318 - { 319 - struct sysv_inode_info *si = (struct sysv_inode_info *)p; 320 - 321 - inode_init_once(&si->vfs_inode); 322 - } 323 - 324 - const struct super_operations sysv_sops = { 325 - .alloc_inode = sysv_alloc_inode, 326 - .free_inode = sysv_free_in_core_inode, 327 - .write_inode = sysv_write_inode, 328 - .evict_inode = sysv_evict_inode, 329 - .put_super = sysv_put_super, 330 - .sync_fs = sysv_sync_fs, 331 - .remount_fs = sysv_remount, 332 - .statfs = sysv_statfs, 333 - }; 334 - 335 - int __init sysv_init_icache(void) 336 - { 337 - sysv_inode_cachep = kmem_cache_create("sysv_inode_cache", 338 - sizeof(struct sysv_inode_info), 0, 339 - SLAB_RECLAIM_ACCOUNT|SLAB_ACCOUNT, 340 - init_once); 341 - if (!sysv_inode_cachep) 342 - return -ENOMEM; 343 - return 0; 344 - } 345 - 346 - void sysv_destroy_icache(void) 347 - { 348 - /* 349 - * Make sure all delayed rcu free inodes are flushed before we 350 - * destroy cache. 351 - */ 352 - rcu_barrier(); 353 - kmem_cache_destroy(sysv_inode_cachep); 354 - }
-511
fs/sysv/itree.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * linux/fs/sysv/itree.c 4 - * 5 - * Handling of indirect blocks' trees. 6 - * AV, Sep--Dec 2000 7 - */ 8 - 9 - #include <linux/buffer_head.h> 10 - #include <linux/mount.h> 11 - #include <linux/mpage.h> 12 - #include <linux/string.h> 13 - #include "sysv.h" 14 - 15 - enum {DIRECT = 10, DEPTH = 4}; /* Have triple indirect */ 16 - 17 - static inline void dirty_indirect(struct buffer_head *bh, struct inode *inode) 18 - { 19 - mark_buffer_dirty_inode(bh, inode); 20 - if (IS_SYNC(inode)) 21 - sync_dirty_buffer(bh); 22 - } 23 - 24 - static int block_to_path(struct inode *inode, long block, int offsets[DEPTH]) 25 - { 26 - struct super_block *sb = inode->i_sb; 27 - struct sysv_sb_info *sbi = SYSV_SB(sb); 28 - int ptrs_bits = sbi->s_ind_per_block_bits; 29 - unsigned long indirect_blocks = sbi->s_ind_per_block, 30 - double_blocks = sbi->s_ind_per_block_2; 31 - int n = 0; 32 - 33 - if (block < 0) { 34 - printk("sysv_block_map: block < 0\n"); 35 - } else if (block < DIRECT) { 36 - offsets[n++] = block; 37 - } else if ( (block -= DIRECT) < indirect_blocks) { 38 - offsets[n++] = DIRECT; 39 - offsets[n++] = block; 40 - } else if ((block -= indirect_blocks) < double_blocks) { 41 - offsets[n++] = DIRECT+1; 42 - offsets[n++] = block >> ptrs_bits; 43 - offsets[n++] = block & (indirect_blocks - 1); 44 - } else if (((block -= double_blocks) >> (ptrs_bits * 2)) < indirect_blocks) { 45 - offsets[n++] = DIRECT+2; 46 - offsets[n++] = block >> (ptrs_bits * 2); 47 - offsets[n++] = (block >> ptrs_bits) & (indirect_blocks - 1); 48 - offsets[n++] = block & (indirect_blocks - 1); 49 - } else { 50 - /* nothing */; 51 - } 52 - return n; 53 - } 54 - 55 - static inline int block_to_cpu(struct sysv_sb_info *sbi, sysv_zone_t nr) 56 - { 57 - return sbi->s_block_base + fs32_to_cpu(sbi, nr); 58 - } 59 - 60 - typedef struct { 61 - sysv_zone_t *p; 62 - sysv_zone_t key; 63 - struct buffer_head *bh; 64 - } Indirect; 65 - 66 - static DEFINE_RWLOCK(pointers_lock); 67 - 68 - static inline void add_chain(Indirect *p, struct buffer_head *bh, sysv_zone_t *v) 69 - { 70 - p->key = *(p->p = v); 71 - p->bh = bh; 72 - } 73 - 74 - static inline int verify_chain(Indirect *from, Indirect *to) 75 - { 76 - while (from <= to && from->key == *from->p) 77 - from++; 78 - return (from > to); 79 - } 80 - 81 - static inline sysv_zone_t *block_end(struct buffer_head *bh) 82 - { 83 - return (sysv_zone_t*)((char*)bh->b_data + bh->b_size); 84 - } 85 - 86 - static Indirect *get_branch(struct inode *inode, 87 - int depth, 88 - int offsets[], 89 - Indirect chain[], 90 - int *err) 91 - { 92 - struct super_block *sb = inode->i_sb; 93 - Indirect *p = chain; 94 - struct buffer_head *bh; 95 - 96 - *err = 0; 97 - add_chain(chain, NULL, SYSV_I(inode)->i_data + *offsets); 98 - if (!p->key) 99 - goto no_block; 100 - while (--depth) { 101 - int block = block_to_cpu(SYSV_SB(sb), p->key); 102 - bh = sb_bread(sb, block); 103 - if (!bh) 104 - goto failure; 105 - read_lock(&pointers_lock); 106 - if (!verify_chain(chain, p)) 107 - goto changed; 108 - add_chain(++p, bh, (sysv_zone_t*)bh->b_data + *++offsets); 109 - read_unlock(&pointers_lock); 110 - if (!p->key) 111 - goto no_block; 112 - } 113 - return NULL; 114 - 115 - changed: 116 - read_unlock(&pointers_lock); 117 - brelse(bh); 118 - *err = -EAGAIN; 119 - goto no_block; 120 - failure: 121 - *err = -EIO; 122 - no_block: 123 - return p; 124 - } 125 - 126 - static int alloc_branch(struct inode *inode, 127 - int num, 128 - int *offsets, 129 - Indirect *branch) 130 - { 131 - int blocksize = inode->i_sb->s_blocksize; 132 - int n = 0; 133 - int i; 134 - 135 - branch[0].key = sysv_new_block(inode->i_sb); 136 - if (branch[0].key) for (n = 1; n < num; n++) { 137 - struct buffer_head *bh; 138 - int parent; 139 - /* Allocate the next block */ 140 - branch[n].key = sysv_new_block(inode->i_sb); 141 - if (!branch[n].key) 142 - break; 143 - /* 144 - * Get buffer_head for parent block, zero it out and set 145 - * the pointer to new one, then send parent to disk. 146 - */ 147 - parent = block_to_cpu(SYSV_SB(inode->i_sb), branch[n-1].key); 148 - bh = sb_getblk(inode->i_sb, parent); 149 - if (!bh) { 150 - sysv_free_block(inode->i_sb, branch[n].key); 151 - break; 152 - } 153 - lock_buffer(bh); 154 - memset(bh->b_data, 0, blocksize); 155 - branch[n].bh = bh; 156 - branch[n].p = (sysv_zone_t*) bh->b_data + offsets[n]; 157 - *branch[n].p = branch[n].key; 158 - set_buffer_uptodate(bh); 159 - unlock_buffer(bh); 160 - dirty_indirect(bh, inode); 161 - } 162 - if (n == num) 163 - return 0; 164 - 165 - /* Allocation failed, free what we already allocated */ 166 - for (i = 1; i < n; i++) 167 - bforget(branch[i].bh); 168 - for (i = 0; i < n; i++) 169 - sysv_free_block(inode->i_sb, branch[i].key); 170 - return -ENOSPC; 171 - } 172 - 173 - static inline int splice_branch(struct inode *inode, 174 - Indirect chain[], 175 - Indirect *where, 176 - int num) 177 - { 178 - int i; 179 - 180 - /* Verify that place we are splicing to is still there and vacant */ 181 - write_lock(&pointers_lock); 182 - if (!verify_chain(chain, where-1) || *where->p) 183 - goto changed; 184 - *where->p = where->key; 185 - write_unlock(&pointers_lock); 186 - 187 - inode_set_ctime_current(inode); 188 - 189 - /* had we spliced it onto indirect block? */ 190 - if (where->bh) 191 - dirty_indirect(where->bh, inode); 192 - 193 - if (IS_SYNC(inode)) 194 - sysv_sync_inode(inode); 195 - else 196 - mark_inode_dirty(inode); 197 - return 0; 198 - 199 - changed: 200 - write_unlock(&pointers_lock); 201 - for (i = 1; i < num; i++) 202 - bforget(where[i].bh); 203 - for (i = 0; i < num; i++) 204 - sysv_free_block(inode->i_sb, where[i].key); 205 - return -EAGAIN; 206 - } 207 - 208 - static int get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) 209 - { 210 - int err = -EIO; 211 - int offsets[DEPTH]; 212 - Indirect chain[DEPTH]; 213 - struct super_block *sb = inode->i_sb; 214 - Indirect *partial; 215 - int left; 216 - int depth = block_to_path(inode, iblock, offsets); 217 - 218 - if (depth == 0) 219 - goto out; 220 - 221 - reread: 222 - partial = get_branch(inode, depth, offsets, chain, &err); 223 - 224 - /* Simplest case - block found, no allocation needed */ 225 - if (!partial) { 226 - got_it: 227 - map_bh(bh_result, sb, block_to_cpu(SYSV_SB(sb), 228 - chain[depth-1].key)); 229 - /* Clean up and exit */ 230 - partial = chain+depth-1; /* the whole chain */ 231 - goto cleanup; 232 - } 233 - 234 - /* Next simple case - plain lookup or failed read of indirect block */ 235 - if (!create || err == -EIO) { 236 - cleanup: 237 - while (partial > chain) { 238 - brelse(partial->bh); 239 - partial--; 240 - } 241 - out: 242 - return err; 243 - } 244 - 245 - /* 246 - * Indirect block might be removed by truncate while we were 247 - * reading it. Handling of that case (forget what we've got and 248 - * reread) is taken out of the main path. 249 - */ 250 - if (err == -EAGAIN) 251 - goto changed; 252 - 253 - left = (chain + depth) - partial; 254 - err = alloc_branch(inode, left, offsets+(partial-chain), partial); 255 - if (err) 256 - goto cleanup; 257 - 258 - if (splice_branch(inode, chain, partial, left) < 0) 259 - goto changed; 260 - 261 - set_buffer_new(bh_result); 262 - goto got_it; 263 - 264 - changed: 265 - while (partial > chain) { 266 - brelse(partial->bh); 267 - partial--; 268 - } 269 - goto reread; 270 - } 271 - 272 - static inline int all_zeroes(sysv_zone_t *p, sysv_zone_t *q) 273 - { 274 - while (p < q) 275 - if (*p++) 276 - return 0; 277 - return 1; 278 - } 279 - 280 - static Indirect *find_shared(struct inode *inode, 281 - int depth, 282 - int offsets[], 283 - Indirect chain[], 284 - sysv_zone_t *top) 285 - { 286 - Indirect *partial, *p; 287 - int k, err; 288 - 289 - *top = 0; 290 - for (k = depth; k > 1 && !offsets[k-1]; k--) 291 - ; 292 - partial = get_branch(inode, k, offsets, chain, &err); 293 - 294 - write_lock(&pointers_lock); 295 - if (!partial) 296 - partial = chain + k-1; 297 - /* 298 - * If the branch acquired continuation since we've looked at it - 299 - * fine, it should all survive and (new) top doesn't belong to us. 300 - */ 301 - if (!partial->key && *partial->p) { 302 - write_unlock(&pointers_lock); 303 - goto no_top; 304 - } 305 - for (p=partial; p>chain && all_zeroes((sysv_zone_t*)p->bh->b_data,p->p); p--) 306 - ; 307 - /* 308 - * OK, we've found the last block that must survive. The rest of our 309 - * branch should be detached before unlocking. However, if that rest 310 - * of branch is all ours and does not grow immediately from the inode 311 - * it's easier to cheat and just decrement partial->p. 312 - */ 313 - if (p == chain + k - 1 && p > chain) { 314 - p->p--; 315 - } else { 316 - *top = *p->p; 317 - *p->p = 0; 318 - } 319 - write_unlock(&pointers_lock); 320 - 321 - while (partial > p) { 322 - brelse(partial->bh); 323 - partial--; 324 - } 325 - no_top: 326 - return partial; 327 - } 328 - 329 - static inline void free_data(struct inode *inode, sysv_zone_t *p, sysv_zone_t *q) 330 - { 331 - for ( ; p < q ; p++) { 332 - sysv_zone_t nr = *p; 333 - if (nr) { 334 - *p = 0; 335 - sysv_free_block(inode->i_sb, nr); 336 - mark_inode_dirty(inode); 337 - } 338 - } 339 - } 340 - 341 - static void free_branches(struct inode *inode, sysv_zone_t *p, sysv_zone_t *q, int depth) 342 - { 343 - struct buffer_head * bh; 344 - struct super_block *sb = inode->i_sb; 345 - 346 - if (depth--) { 347 - for ( ; p < q ; p++) { 348 - int block; 349 - sysv_zone_t nr = *p; 350 - if (!nr) 351 - continue; 352 - *p = 0; 353 - block = block_to_cpu(SYSV_SB(sb), nr); 354 - bh = sb_bread(sb, block); 355 - if (!bh) 356 - continue; 357 - free_branches(inode, (sysv_zone_t*)bh->b_data, 358 - block_end(bh), depth); 359 - bforget(bh); 360 - sysv_free_block(sb, nr); 361 - mark_inode_dirty(inode); 362 - } 363 - } else 364 - free_data(inode, p, q); 365 - } 366 - 367 - void sysv_truncate (struct inode * inode) 368 - { 369 - sysv_zone_t *i_data = SYSV_I(inode)->i_data; 370 - int offsets[DEPTH]; 371 - Indirect chain[DEPTH]; 372 - Indirect *partial; 373 - sysv_zone_t nr = 0; 374 - int n; 375 - long iblock; 376 - unsigned blocksize; 377 - 378 - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || 379 - S_ISLNK(inode->i_mode))) 380 - return; 381 - 382 - blocksize = inode->i_sb->s_blocksize; 383 - iblock = (inode->i_size + blocksize-1) 384 - >> inode->i_sb->s_blocksize_bits; 385 - 386 - block_truncate_page(inode->i_mapping, inode->i_size, get_block); 387 - 388 - n = block_to_path(inode, iblock, offsets); 389 - if (n == 0) 390 - return; 391 - 392 - if (n == 1) { 393 - free_data(inode, i_data+offsets[0], i_data + DIRECT); 394 - goto do_indirects; 395 - } 396 - 397 - partial = find_shared(inode, n, offsets, chain, &nr); 398 - /* Kill the top of shared branch (already detached) */ 399 - if (nr) { 400 - if (partial == chain) 401 - mark_inode_dirty(inode); 402 - else 403 - dirty_indirect(partial->bh, inode); 404 - free_branches(inode, &nr, &nr+1, (chain+n-1) - partial); 405 - } 406 - /* Clear the ends of indirect blocks on the shared branch */ 407 - while (partial > chain) { 408 - free_branches(inode, partial->p + 1, block_end(partial->bh), 409 - (chain+n-1) - partial); 410 - dirty_indirect(partial->bh, inode); 411 - brelse (partial->bh); 412 - partial--; 413 - } 414 - do_indirects: 415 - /* Kill the remaining (whole) subtrees (== subtrees deeper than...) */ 416 - while (n < DEPTH) { 417 - nr = i_data[DIRECT + n - 1]; 418 - if (nr) { 419 - i_data[DIRECT + n - 1] = 0; 420 - mark_inode_dirty(inode); 421 - free_branches(inode, &nr, &nr+1, n); 422 - } 423 - n++; 424 - } 425 - inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); 426 - if (IS_SYNC(inode)) 427 - sysv_sync_inode (inode); 428 - else 429 - mark_inode_dirty(inode); 430 - } 431 - 432 - static unsigned sysv_nblocks(struct super_block *s, loff_t size) 433 - { 434 - struct sysv_sb_info *sbi = SYSV_SB(s); 435 - int ptrs_bits = sbi->s_ind_per_block_bits; 436 - unsigned blocks, res, direct = DIRECT, i = DEPTH; 437 - blocks = (size + s->s_blocksize - 1) >> s->s_blocksize_bits; 438 - res = blocks; 439 - while (--i && blocks > direct) { 440 - blocks = ((blocks - direct - 1) >> ptrs_bits) + 1; 441 - res += blocks; 442 - direct = 1; 443 - } 444 - return res; 445 - } 446 - 447 - int sysv_getattr(struct mnt_idmap *idmap, const struct path *path, 448 - struct kstat *stat, u32 request_mask, unsigned int flags) 449 - { 450 - struct super_block *s = path->dentry->d_sb; 451 - generic_fillattr(&nop_mnt_idmap, request_mask, d_inode(path->dentry), 452 - stat); 453 - stat->blocks = (s->s_blocksize / 512) * sysv_nblocks(s, stat->size); 454 - stat->blksize = s->s_blocksize; 455 - return 0; 456 - } 457 - 458 - static int sysv_writepages(struct address_space *mapping, 459 - struct writeback_control *wbc) 460 - { 461 - return mpage_writepages(mapping, wbc, get_block); 462 - } 463 - 464 - static int sysv_read_folio(struct file *file, struct folio *folio) 465 - { 466 - return block_read_full_folio(folio, get_block); 467 - } 468 - 469 - int sysv_prepare_chunk(struct folio *folio, loff_t pos, unsigned len) 470 - { 471 - return __block_write_begin(folio, pos, len, get_block); 472 - } 473 - 474 - static void sysv_write_failed(struct address_space *mapping, loff_t to) 475 - { 476 - struct inode *inode = mapping->host; 477 - 478 - if (to > inode->i_size) { 479 - truncate_pagecache(inode, inode->i_size); 480 - sysv_truncate(inode); 481 - } 482 - } 483 - 484 - static int sysv_write_begin(struct file *file, struct address_space *mapping, 485 - loff_t pos, unsigned len, 486 - struct folio **foliop, void **fsdata) 487 - { 488 - int ret; 489 - 490 - ret = block_write_begin(mapping, pos, len, foliop, get_block); 491 - if (unlikely(ret)) 492 - sysv_write_failed(mapping, pos + len); 493 - 494 - return ret; 495 - } 496 - 497 - static sector_t sysv_bmap(struct address_space *mapping, sector_t block) 498 - { 499 - return generic_block_bmap(mapping,block,get_block); 500 - } 501 - 502 - const struct address_space_operations sysv_aops = { 503 - .dirty_folio = block_dirty_folio, 504 - .invalidate_folio = block_invalidate_folio, 505 - .read_folio = sysv_read_folio, 506 - .writepages = sysv_writepages, 507 - .write_begin = sysv_write_begin, 508 - .write_end = generic_write_end, 509 - .migrate_folio = buffer_migrate_folio, 510 - .bmap = sysv_bmap 511 - };
-280
fs/sysv/namei.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * linux/fs/sysv/namei.c 4 - * 5 - * minix/namei.c 6 - * Copyright (C) 1991, 1992 Linus Torvalds 7 - * 8 - * coh/namei.c 9 - * Copyright (C) 1993 Pascal Haible, Bruno Haible 10 - * 11 - * sysv/namei.c 12 - * Copyright (C) 1993 Bruno Haible 13 - * Copyright (C) 1997, 1998 Krzysztof G. Baranowski 14 - */ 15 - 16 - #include <linux/pagemap.h> 17 - #include "sysv.h" 18 - 19 - static int add_nondir(struct dentry *dentry, struct inode *inode) 20 - { 21 - int err = sysv_add_link(dentry, inode); 22 - if (!err) { 23 - d_instantiate(dentry, inode); 24 - return 0; 25 - } 26 - inode_dec_link_count(inode); 27 - iput(inode); 28 - return err; 29 - } 30 - 31 - static struct dentry *sysv_lookup(struct inode * dir, struct dentry * dentry, unsigned int flags) 32 - { 33 - struct inode * inode = NULL; 34 - ino_t ino; 35 - 36 - if (dentry->d_name.len > SYSV_NAMELEN) 37 - return ERR_PTR(-ENAMETOOLONG); 38 - ino = sysv_inode_by_name(dentry); 39 - if (ino) 40 - inode = sysv_iget(dir->i_sb, ino); 41 - return d_splice_alias(inode, dentry); 42 - } 43 - 44 - static int sysv_mknod(struct mnt_idmap *idmap, struct inode *dir, 45 - struct dentry *dentry, umode_t mode, dev_t rdev) 46 - { 47 - struct inode * inode; 48 - int err; 49 - 50 - if (!old_valid_dev(rdev)) 51 - return -EINVAL; 52 - 53 - inode = sysv_new_inode(dir, mode); 54 - err = PTR_ERR(inode); 55 - 56 - if (!IS_ERR(inode)) { 57 - sysv_set_inode(inode, rdev); 58 - mark_inode_dirty(inode); 59 - err = add_nondir(dentry, inode); 60 - } 61 - return err; 62 - } 63 - 64 - static int sysv_create(struct mnt_idmap *idmap, struct inode *dir, 65 - struct dentry *dentry, umode_t mode, bool excl) 66 - { 67 - return sysv_mknod(&nop_mnt_idmap, dir, dentry, mode, 0); 68 - } 69 - 70 - static int sysv_symlink(struct mnt_idmap *idmap, struct inode *dir, 71 - struct dentry *dentry, const char *symname) 72 - { 73 - int err = -ENAMETOOLONG; 74 - int l = strlen(symname)+1; 75 - struct inode * inode; 76 - 77 - if (l > dir->i_sb->s_blocksize) 78 - goto out; 79 - 80 - inode = sysv_new_inode(dir, S_IFLNK|0777); 81 - err = PTR_ERR(inode); 82 - if (IS_ERR(inode)) 83 - goto out; 84 - 85 - sysv_set_inode(inode, 0); 86 - err = page_symlink(inode, symname, l); 87 - if (err) 88 - goto out_fail; 89 - 90 - mark_inode_dirty(inode); 91 - err = add_nondir(dentry, inode); 92 - out: 93 - return err; 94 - 95 - out_fail: 96 - inode_dec_link_count(inode); 97 - iput(inode); 98 - goto out; 99 - } 100 - 101 - static int sysv_link(struct dentry * old_dentry, struct inode * dir, 102 - struct dentry * dentry) 103 - { 104 - struct inode *inode = d_inode(old_dentry); 105 - 106 - inode_set_ctime_current(inode); 107 - inode_inc_link_count(inode); 108 - ihold(inode); 109 - 110 - return add_nondir(dentry, inode); 111 - } 112 - 113 - static struct dentry *sysv_mkdir(struct mnt_idmap *idmap, struct inode *dir, 114 - struct dentry *dentry, umode_t mode) 115 - { 116 - struct inode * inode; 117 - int err; 118 - 119 - inode_inc_link_count(dir); 120 - 121 - inode = sysv_new_inode(dir, S_IFDIR|mode); 122 - err = PTR_ERR(inode); 123 - if (IS_ERR(inode)) 124 - goto out_dir; 125 - 126 - sysv_set_inode(inode, 0); 127 - 128 - inode_inc_link_count(inode); 129 - 130 - err = sysv_make_empty(inode, dir); 131 - if (err) 132 - goto out_fail; 133 - 134 - err = sysv_add_link(dentry, inode); 135 - if (err) 136 - goto out_fail; 137 - 138 - d_instantiate(dentry, inode); 139 - out: 140 - return ERR_PTR(err); 141 - 142 - out_fail: 143 - inode_dec_link_count(inode); 144 - inode_dec_link_count(inode); 145 - iput(inode); 146 - out_dir: 147 - inode_dec_link_count(dir); 148 - goto out; 149 - } 150 - 151 - static int sysv_unlink(struct inode * dir, struct dentry * dentry) 152 - { 153 - struct inode * inode = d_inode(dentry); 154 - struct folio *folio; 155 - struct sysv_dir_entry * de; 156 - int err; 157 - 158 - de = sysv_find_entry(dentry, &folio); 159 - if (!de) 160 - return -ENOENT; 161 - 162 - err = sysv_delete_entry(de, folio); 163 - if (!err) { 164 - inode_set_ctime_to_ts(inode, inode_get_ctime(dir)); 165 - inode_dec_link_count(inode); 166 - } 167 - folio_release_kmap(folio, de); 168 - return err; 169 - } 170 - 171 - static int sysv_rmdir(struct inode * dir, struct dentry * dentry) 172 - { 173 - struct inode *inode = d_inode(dentry); 174 - int err = -ENOTEMPTY; 175 - 176 - if (sysv_empty_dir(inode)) { 177 - err = sysv_unlink(dir, dentry); 178 - if (!err) { 179 - inode->i_size = 0; 180 - inode_dec_link_count(inode); 181 - inode_dec_link_count(dir); 182 - } 183 - } 184 - return err; 185 - } 186 - 187 - /* 188 - * Anybody can rename anything with this: the permission checks are left to the 189 - * higher-level routines. 190 - */ 191 - static int sysv_rename(struct mnt_idmap *idmap, struct inode *old_dir, 192 - struct dentry *old_dentry, struct inode *new_dir, 193 - struct dentry *new_dentry, unsigned int flags) 194 - { 195 - struct inode * old_inode = d_inode(old_dentry); 196 - struct inode * new_inode = d_inode(new_dentry); 197 - struct folio *dir_folio; 198 - struct sysv_dir_entry * dir_de = NULL; 199 - struct folio *old_folio; 200 - struct sysv_dir_entry * old_de; 201 - int err = -ENOENT; 202 - 203 - if (flags & ~RENAME_NOREPLACE) 204 - return -EINVAL; 205 - 206 - old_de = sysv_find_entry(old_dentry, &old_folio); 207 - if (!old_de) 208 - goto out; 209 - 210 - if (S_ISDIR(old_inode->i_mode)) { 211 - err = -EIO; 212 - dir_de = sysv_dotdot(old_inode, &dir_folio); 213 - if (!dir_de) 214 - goto out_old; 215 - } 216 - 217 - if (new_inode) { 218 - struct folio *new_folio; 219 - struct sysv_dir_entry * new_de; 220 - 221 - err = -ENOTEMPTY; 222 - if (dir_de && !sysv_empty_dir(new_inode)) 223 - goto out_dir; 224 - 225 - err = -ENOENT; 226 - new_de = sysv_find_entry(new_dentry, &new_folio); 227 - if (!new_de) 228 - goto out_dir; 229 - err = sysv_set_link(new_de, new_folio, old_inode); 230 - folio_release_kmap(new_folio, new_de); 231 - if (err) 232 - goto out_dir; 233 - inode_set_ctime_current(new_inode); 234 - if (dir_de) 235 - drop_nlink(new_inode); 236 - inode_dec_link_count(new_inode); 237 - } else { 238 - err = sysv_add_link(new_dentry, old_inode); 239 - if (err) 240 - goto out_dir; 241 - if (dir_de) 242 - inode_inc_link_count(new_dir); 243 - } 244 - 245 - err = sysv_delete_entry(old_de, old_folio); 246 - if (err) 247 - goto out_dir; 248 - 249 - mark_inode_dirty(old_inode); 250 - 251 - if (dir_de) { 252 - err = sysv_set_link(dir_de, dir_folio, new_dir); 253 - if (!err) 254 - inode_dec_link_count(old_dir); 255 - } 256 - 257 - out_dir: 258 - if (dir_de) 259 - folio_release_kmap(dir_folio, dir_de); 260 - out_old: 261 - folio_release_kmap(old_folio, old_de); 262 - out: 263 - return err; 264 - } 265 - 266 - /* 267 - * directories can handle most operations... 268 - */ 269 - const struct inode_operations sysv_dir_inode_operations = { 270 - .create = sysv_create, 271 - .lookup = sysv_lookup, 272 - .link = sysv_link, 273 - .unlink = sysv_unlink, 274 - .symlink = sysv_symlink, 275 - .mkdir = sysv_mkdir, 276 - .rmdir = sysv_rmdir, 277 - .mknod = sysv_mknod, 278 - .rename = sysv_rename, 279 - .getattr = sysv_getattr, 280 - };
-616
fs/sysv/super.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * linux/fs/sysv/inode.c 4 - * 5 - * minix/inode.c 6 - * Copyright (C) 1991, 1992 Linus Torvalds 7 - * 8 - * xenix/inode.c 9 - * Copyright (C) 1992 Doug Evans 10 - * 11 - * coh/inode.c 12 - * Copyright (C) 1993 Pascal Haible, Bruno Haible 13 - * 14 - * sysv/inode.c 15 - * Copyright (C) 1993 Paul B. Monday 16 - * 17 - * sysv/inode.c 18 - * Copyright (C) 1993 Bruno Haible 19 - * Copyright (C) 1997, 1998 Krzysztof G. Baranowski 20 - * 21 - * This file contains code for read/parsing the superblock. 22 - */ 23 - 24 - #include <linux/module.h> 25 - #include <linux/init.h> 26 - #include <linux/slab.h> 27 - #include <linux/buffer_head.h> 28 - #include <linux/fs_context.h> 29 - #include "sysv.h" 30 - 31 - /* 32 - * The following functions try to recognize specific filesystems. 33 - * 34 - * We recognize: 35 - * - Xenix FS by its magic number. 36 - * - SystemV FS by its magic number. 37 - * - Coherent FS by its funny fname/fpack field. 38 - * - SCO AFS by s_nfree == 0xffff 39 - * - V7 FS has no distinguishing features. 40 - * 41 - * We discriminate among SystemV4 and SystemV2 FS by the assumption that 42 - * the time stamp is not < 01-01-1980. 43 - */ 44 - 45 - enum { 46 - JAN_1_1980 = (10*365 + 2) * 24 * 60 * 60 47 - }; 48 - 49 - static void detected_xenix(struct sysv_sb_info *sbi, unsigned *max_links) 50 - { 51 - struct buffer_head *bh1 = sbi->s_bh1; 52 - struct buffer_head *bh2 = sbi->s_bh2; 53 - struct xenix_super_block * sbd1; 54 - struct xenix_super_block * sbd2; 55 - 56 - if (bh1 != bh2) 57 - sbd1 = sbd2 = (struct xenix_super_block *) bh1->b_data; 58 - else { 59 - /* block size = 512, so bh1 != bh2 */ 60 - sbd1 = (struct xenix_super_block *) bh1->b_data; 61 - sbd2 = (struct xenix_super_block *) (bh2->b_data - 512); 62 - } 63 - 64 - *max_links = XENIX_LINK_MAX; 65 - sbi->s_fic_size = XENIX_NICINOD; 66 - sbi->s_flc_size = XENIX_NICFREE; 67 - sbi->s_sbd1 = (char *)sbd1; 68 - sbi->s_sbd2 = (char *)sbd2; 69 - sbi->s_sb_fic_count = &sbd1->s_ninode; 70 - sbi->s_sb_fic_inodes = &sbd1->s_inode[0]; 71 - sbi->s_sb_total_free_inodes = &sbd2->s_tinode; 72 - sbi->s_bcache_count = &sbd1->s_nfree; 73 - sbi->s_bcache = &sbd1->s_free[0]; 74 - sbi->s_free_blocks = &sbd2->s_tfree; 75 - sbi->s_sb_time = &sbd2->s_time; 76 - sbi->s_firstdatazone = fs16_to_cpu(sbi, sbd1->s_isize); 77 - sbi->s_nzones = fs32_to_cpu(sbi, sbd1->s_fsize); 78 - } 79 - 80 - static void detected_sysv4(struct sysv_sb_info *sbi, unsigned *max_links) 81 - { 82 - struct sysv4_super_block * sbd; 83 - struct buffer_head *bh1 = sbi->s_bh1; 84 - struct buffer_head *bh2 = sbi->s_bh2; 85 - 86 - if (bh1 == bh2) 87 - sbd = (struct sysv4_super_block *) (bh1->b_data + BLOCK_SIZE/2); 88 - else 89 - sbd = (struct sysv4_super_block *) bh2->b_data; 90 - 91 - *max_links = SYSV_LINK_MAX; 92 - sbi->s_fic_size = SYSV_NICINOD; 93 - sbi->s_flc_size = SYSV_NICFREE; 94 - sbi->s_sbd1 = (char *)sbd; 95 - sbi->s_sbd2 = (char *)sbd; 96 - sbi->s_sb_fic_count = &sbd->s_ninode; 97 - sbi->s_sb_fic_inodes = &sbd->s_inode[0]; 98 - sbi->s_sb_total_free_inodes = &sbd->s_tinode; 99 - sbi->s_bcache_count = &sbd->s_nfree; 100 - sbi->s_bcache = &sbd->s_free[0]; 101 - sbi->s_free_blocks = &sbd->s_tfree; 102 - sbi->s_sb_time = &sbd->s_time; 103 - sbi->s_sb_state = &sbd->s_state; 104 - sbi->s_firstdatazone = fs16_to_cpu(sbi, sbd->s_isize); 105 - sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize); 106 - } 107 - 108 - static void detected_sysv2(struct sysv_sb_info *sbi, unsigned *max_links) 109 - { 110 - struct sysv2_super_block *sbd; 111 - struct buffer_head *bh1 = sbi->s_bh1; 112 - struct buffer_head *bh2 = sbi->s_bh2; 113 - 114 - if (bh1 == bh2) 115 - sbd = (struct sysv2_super_block *) (bh1->b_data + BLOCK_SIZE/2); 116 - else 117 - sbd = (struct sysv2_super_block *) bh2->b_data; 118 - 119 - *max_links = SYSV_LINK_MAX; 120 - sbi->s_fic_size = SYSV_NICINOD; 121 - sbi->s_flc_size = SYSV_NICFREE; 122 - sbi->s_sbd1 = (char *)sbd; 123 - sbi->s_sbd2 = (char *)sbd; 124 - sbi->s_sb_fic_count = &sbd->s_ninode; 125 - sbi->s_sb_fic_inodes = &sbd->s_inode[0]; 126 - sbi->s_sb_total_free_inodes = &sbd->s_tinode; 127 - sbi->s_bcache_count = &sbd->s_nfree; 128 - sbi->s_bcache = &sbd->s_free[0]; 129 - sbi->s_free_blocks = &sbd->s_tfree; 130 - sbi->s_sb_time = &sbd->s_time; 131 - sbi->s_sb_state = &sbd->s_state; 132 - sbi->s_firstdatazone = fs16_to_cpu(sbi, sbd->s_isize); 133 - sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize); 134 - } 135 - 136 - static void detected_coherent(struct sysv_sb_info *sbi, unsigned *max_links) 137 - { 138 - struct coh_super_block * sbd; 139 - struct buffer_head *bh1 = sbi->s_bh1; 140 - 141 - sbd = (struct coh_super_block *) bh1->b_data; 142 - 143 - *max_links = COH_LINK_MAX; 144 - sbi->s_fic_size = COH_NICINOD; 145 - sbi->s_flc_size = COH_NICFREE; 146 - sbi->s_sbd1 = (char *)sbd; 147 - sbi->s_sbd2 = (char *)sbd; 148 - sbi->s_sb_fic_count = &sbd->s_ninode; 149 - sbi->s_sb_fic_inodes = &sbd->s_inode[0]; 150 - sbi->s_sb_total_free_inodes = &sbd->s_tinode; 151 - sbi->s_bcache_count = &sbd->s_nfree; 152 - sbi->s_bcache = &sbd->s_free[0]; 153 - sbi->s_free_blocks = &sbd->s_tfree; 154 - sbi->s_sb_time = &sbd->s_time; 155 - sbi->s_firstdatazone = fs16_to_cpu(sbi, sbd->s_isize); 156 - sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize); 157 - } 158 - 159 - static void detected_v7(struct sysv_sb_info *sbi, unsigned *max_links) 160 - { 161 - struct buffer_head *bh2 = sbi->s_bh2; 162 - struct v7_super_block *sbd = (struct v7_super_block *)bh2->b_data; 163 - 164 - *max_links = V7_LINK_MAX; 165 - sbi->s_fic_size = V7_NICINOD; 166 - sbi->s_flc_size = V7_NICFREE; 167 - sbi->s_sbd1 = (char *)sbd; 168 - sbi->s_sbd2 = (char *)sbd; 169 - sbi->s_sb_fic_count = &sbd->s_ninode; 170 - sbi->s_sb_fic_inodes = &sbd->s_inode[0]; 171 - sbi->s_sb_total_free_inodes = &sbd->s_tinode; 172 - sbi->s_bcache_count = &sbd->s_nfree; 173 - sbi->s_bcache = &sbd->s_free[0]; 174 - sbi->s_free_blocks = &sbd->s_tfree; 175 - sbi->s_sb_time = &sbd->s_time; 176 - sbi->s_firstdatazone = fs16_to_cpu(sbi, sbd->s_isize); 177 - sbi->s_nzones = fs32_to_cpu(sbi, sbd->s_fsize); 178 - } 179 - 180 - static int detect_xenix(struct sysv_sb_info *sbi, struct buffer_head *bh) 181 - { 182 - struct xenix_super_block *sbd = (struct xenix_super_block *)bh->b_data; 183 - if (*(__le32 *)&sbd->s_magic == cpu_to_le32(0x2b5544)) 184 - sbi->s_bytesex = BYTESEX_LE; 185 - else if (*(__be32 *)&sbd->s_magic == cpu_to_be32(0x2b5544)) 186 - sbi->s_bytesex = BYTESEX_BE; 187 - else 188 - return 0; 189 - switch (fs32_to_cpu(sbi, sbd->s_type)) { 190 - case 1: 191 - sbi->s_type = FSTYPE_XENIX; 192 - return 1; 193 - case 2: 194 - sbi->s_type = FSTYPE_XENIX; 195 - return 2; 196 - default: 197 - return 0; 198 - } 199 - } 200 - 201 - static int detect_sysv(struct sysv_sb_info *sbi, struct buffer_head *bh) 202 - { 203 - struct super_block *sb = sbi->s_sb; 204 - /* All relevant fields are at the same offsets in R2 and R4 */ 205 - struct sysv4_super_block * sbd; 206 - u32 type; 207 - 208 - sbd = (struct sysv4_super_block *) (bh->b_data + BLOCK_SIZE/2); 209 - if (*(__le32 *)&sbd->s_magic == cpu_to_le32(0xfd187e20)) 210 - sbi->s_bytesex = BYTESEX_LE; 211 - else if (*(__be32 *)&sbd->s_magic == cpu_to_be32(0xfd187e20)) 212 - sbi->s_bytesex = BYTESEX_BE; 213 - else 214 - return 0; 215 - 216 - type = fs32_to_cpu(sbi, sbd->s_type); 217 - 218 - if (fs16_to_cpu(sbi, sbd->s_nfree) == 0xffff) { 219 - sbi->s_type = FSTYPE_AFS; 220 - sbi->s_forced_ro = 1; 221 - if (!sb_rdonly(sb)) { 222 - printk("SysV FS: SCO EAFS on %s detected, " 223 - "forcing read-only mode.\n", 224 - sb->s_id); 225 - } 226 - return type; 227 - } 228 - 229 - if (fs32_to_cpu(sbi, sbd->s_time) < JAN_1_1980) { 230 - /* this is likely to happen on SystemV2 FS */ 231 - if (type > 3 || type < 1) 232 - return 0; 233 - sbi->s_type = FSTYPE_SYSV2; 234 - return type; 235 - } 236 - if ((type > 3 || type < 1) && (type > 0x30 || type < 0x10)) 237 - return 0; 238 - 239 - /* On Interactive Unix (ISC) Version 4.0/3.x s_type field = 0x10, 240 - 0x20 or 0x30 indicates that symbolic links and the 14-character 241 - filename limit is gone. Due to lack of information about this 242 - feature read-only mode seems to be a reasonable approach... -KGB */ 243 - 244 - if (type >= 0x10) { 245 - printk("SysV FS: can't handle long file names on %s, " 246 - "forcing read-only mode.\n", sb->s_id); 247 - sbi->s_forced_ro = 1; 248 - } 249 - 250 - sbi->s_type = FSTYPE_SYSV4; 251 - return type >= 0x10 ? type >> 4 : type; 252 - } 253 - 254 - static int detect_coherent(struct sysv_sb_info *sbi, struct buffer_head *bh) 255 - { 256 - struct coh_super_block * sbd; 257 - 258 - sbd = (struct coh_super_block *) (bh->b_data + BLOCK_SIZE/2); 259 - if ((memcmp(sbd->s_fname,"noname",6) && memcmp(sbd->s_fname,"xxxxx ",6)) 260 - || (memcmp(sbd->s_fpack,"nopack",6) && memcmp(sbd->s_fpack,"xxxxx\n",6))) 261 - return 0; 262 - sbi->s_bytesex = BYTESEX_PDP; 263 - sbi->s_type = FSTYPE_COH; 264 - return 1; 265 - } 266 - 267 - static int detect_sysv_odd(struct sysv_sb_info *sbi, struct buffer_head *bh) 268 - { 269 - int size = detect_sysv(sbi, bh); 270 - 271 - return size>2 ? 0 : size; 272 - } 273 - 274 - static struct { 275 - int block; 276 - int (*test)(struct sysv_sb_info *, struct buffer_head *); 277 - } flavours[] = { 278 - {1, detect_xenix}, 279 - {0, detect_sysv}, 280 - {0, detect_coherent}, 281 - {9, detect_sysv_odd}, 282 - {15,detect_sysv_odd}, 283 - {18,detect_sysv}, 284 - }; 285 - 286 - static char *flavour_names[] = { 287 - [FSTYPE_XENIX] = "Xenix", 288 - [FSTYPE_SYSV4] = "SystemV", 289 - [FSTYPE_SYSV2] = "SystemV Release 2", 290 - [FSTYPE_COH] = "Coherent", 291 - [FSTYPE_V7] = "V7", 292 - [FSTYPE_AFS] = "AFS", 293 - }; 294 - 295 - static void (*flavour_setup[])(struct sysv_sb_info *, unsigned *) = { 296 - [FSTYPE_XENIX] = detected_xenix, 297 - [FSTYPE_SYSV4] = detected_sysv4, 298 - [FSTYPE_SYSV2] = detected_sysv2, 299 - [FSTYPE_COH] = detected_coherent, 300 - [FSTYPE_V7] = detected_v7, 301 - [FSTYPE_AFS] = detected_sysv4, 302 - }; 303 - 304 - static int complete_read_super(struct super_block *sb, int silent, int size) 305 - { 306 - struct sysv_sb_info *sbi = SYSV_SB(sb); 307 - struct inode *root_inode; 308 - char *found = flavour_names[sbi->s_type]; 309 - u_char n_bits = size+8; 310 - int bsize = 1 << n_bits; 311 - int bsize_4 = bsize >> 2; 312 - 313 - sbi->s_firstinodezone = 2; 314 - 315 - flavour_setup[sbi->s_type](sbi, &sb->s_max_links); 316 - if (sbi->s_firstdatazone < sbi->s_firstinodezone) 317 - return 0; 318 - 319 - sbi->s_ndatazones = sbi->s_nzones - sbi->s_firstdatazone; 320 - sbi->s_inodes_per_block = bsize >> 6; 321 - sbi->s_inodes_per_block_1 = (bsize >> 6)-1; 322 - sbi->s_inodes_per_block_bits = n_bits-6; 323 - sbi->s_ind_per_block = bsize_4; 324 - sbi->s_ind_per_block_2 = bsize_4*bsize_4; 325 - sbi->s_toobig_block = 10 + bsize_4 * (1 + bsize_4 * (1 + bsize_4)); 326 - sbi->s_ind_per_block_bits = n_bits-2; 327 - 328 - sbi->s_ninodes = (sbi->s_firstdatazone - sbi->s_firstinodezone) 329 - << sbi->s_inodes_per_block_bits; 330 - 331 - if (!silent) 332 - printk("VFS: Found a %s FS (block size = %ld) on device %s\n", 333 - found, sb->s_blocksize, sb->s_id); 334 - 335 - sb->s_magic = SYSV_MAGIC_BASE + sbi->s_type; 336 - /* set up enough so that it can read an inode */ 337 - sb->s_op = &sysv_sops; 338 - if (sbi->s_forced_ro) 339 - sb->s_flags |= SB_RDONLY; 340 - root_inode = sysv_iget(sb, SYSV_ROOT_INO); 341 - if (IS_ERR(root_inode)) { 342 - printk("SysV FS: get root inode failed\n"); 343 - return 0; 344 - } 345 - sb->s_root = d_make_root(root_inode); 346 - if (!sb->s_root) { 347 - printk("SysV FS: get root dentry failed\n"); 348 - return 0; 349 - } 350 - return 1; 351 - } 352 - 353 - static int sysv_fill_super(struct super_block *sb, struct fs_context *fc) 354 - { 355 - struct buffer_head *bh1, *bh = NULL; 356 - struct sysv_sb_info *sbi; 357 - unsigned long blocknr; 358 - int size = 0, i; 359 - int silent = fc->sb_flags & SB_SILENT; 360 - 361 - BUILD_BUG_ON(1024 != sizeof (struct xenix_super_block)); 362 - BUILD_BUG_ON(512 != sizeof (struct sysv4_super_block)); 363 - BUILD_BUG_ON(512 != sizeof (struct sysv2_super_block)); 364 - BUILD_BUG_ON(500 != sizeof (struct coh_super_block)); 365 - BUILD_BUG_ON(64 != sizeof (struct sysv_inode)); 366 - 367 - sbi = kzalloc(sizeof(struct sysv_sb_info), GFP_KERNEL); 368 - if (!sbi) 369 - return -ENOMEM; 370 - 371 - sbi->s_sb = sb; 372 - sbi->s_block_base = 0; 373 - mutex_init(&sbi->s_lock); 374 - sb->s_fs_info = sbi; 375 - sb->s_time_min = 0; 376 - sb->s_time_max = U32_MAX; 377 - sb_set_blocksize(sb, BLOCK_SIZE); 378 - 379 - for (i = 0; i < ARRAY_SIZE(flavours) && !size; i++) { 380 - brelse(bh); 381 - bh = sb_bread(sb, flavours[i].block); 382 - if (!bh) 383 - continue; 384 - size = flavours[i].test(SYSV_SB(sb), bh); 385 - } 386 - 387 - if (!size) 388 - goto Eunknown; 389 - 390 - switch (size) { 391 - case 1: 392 - blocknr = bh->b_blocknr << 1; 393 - brelse(bh); 394 - sb_set_blocksize(sb, 512); 395 - bh1 = sb_bread(sb, blocknr); 396 - bh = sb_bread(sb, blocknr + 1); 397 - break; 398 - case 2: 399 - bh1 = bh; 400 - break; 401 - case 3: 402 - blocknr = bh->b_blocknr >> 1; 403 - brelse(bh); 404 - sb_set_blocksize(sb, 2048); 405 - bh1 = bh = sb_bread(sb, blocknr); 406 - break; 407 - default: 408 - goto Ebadsize; 409 - } 410 - 411 - if (bh && bh1) { 412 - sbi->s_bh1 = bh1; 413 - sbi->s_bh2 = bh; 414 - if (complete_read_super(sb, silent, size)) 415 - return 0; 416 - } 417 - 418 - brelse(bh1); 419 - brelse(bh); 420 - sb_set_blocksize(sb, BLOCK_SIZE); 421 - printk("oldfs: cannot read superblock\n"); 422 - failed: 423 - kfree(sbi); 424 - return -EINVAL; 425 - 426 - Eunknown: 427 - brelse(bh); 428 - if (!silent) 429 - printk("VFS: unable to find oldfs superblock on device %s\n", 430 - sb->s_id); 431 - goto failed; 432 - Ebadsize: 433 - brelse(bh); 434 - if (!silent) 435 - printk("VFS: oldfs: unsupported block size (%dKb)\n", 436 - 1<<(size-2)); 437 - goto failed; 438 - } 439 - 440 - static int v7_sanity_check(struct super_block *sb, struct buffer_head *bh) 441 - { 442 - struct v7_super_block *v7sb; 443 - struct sysv_inode *v7i; 444 - struct buffer_head *bh2; 445 - struct sysv_sb_info *sbi; 446 - 447 - sbi = sb->s_fs_info; 448 - 449 - /* plausibility check on superblock */ 450 - v7sb = (struct v7_super_block *) bh->b_data; 451 - if (fs16_to_cpu(sbi, v7sb->s_nfree) > V7_NICFREE || 452 - fs16_to_cpu(sbi, v7sb->s_ninode) > V7_NICINOD || 453 - fs32_to_cpu(sbi, v7sb->s_fsize) > V7_MAXSIZE) 454 - return 0; 455 - 456 - /* plausibility check on root inode: it is a directory, 457 - with a nonzero size that is a multiple of 16 */ 458 - bh2 = sb_bread(sb, 2); 459 - if (bh2 == NULL) 460 - return 0; 461 - 462 - v7i = (struct sysv_inode *)(bh2->b_data + 64); 463 - if ((fs16_to_cpu(sbi, v7i->i_mode) & ~0777) != S_IFDIR || 464 - (fs32_to_cpu(sbi, v7i->i_size) == 0) || 465 - (fs32_to_cpu(sbi, v7i->i_size) & 017) || 466 - (fs32_to_cpu(sbi, v7i->i_size) > V7_NFILES * 467 - sizeof(struct sysv_dir_entry))) { 468 - brelse(bh2); 469 - return 0; 470 - } 471 - 472 - brelse(bh2); 473 - return 1; 474 - } 475 - 476 - static int v7_fill_super(struct super_block *sb, struct fs_context *fc) 477 - { 478 - struct sysv_sb_info *sbi; 479 - struct buffer_head *bh; 480 - int silent = fc->sb_flags & SB_SILENT; 481 - 482 - BUILD_BUG_ON(sizeof(struct v7_super_block) != 440); 483 - BUILD_BUG_ON(sizeof(struct sysv_inode) != 64); 484 - 485 - sbi = kzalloc(sizeof(struct sysv_sb_info), GFP_KERNEL); 486 - if (!sbi) 487 - return -ENOMEM; 488 - 489 - sbi->s_sb = sb; 490 - sbi->s_block_base = 0; 491 - sbi->s_type = FSTYPE_V7; 492 - mutex_init(&sbi->s_lock); 493 - sb->s_fs_info = sbi; 494 - sb->s_time_min = 0; 495 - sb->s_time_max = U32_MAX; 496 - 497 - sb_set_blocksize(sb, 512); 498 - 499 - if ((bh = sb_bread(sb, 1)) == NULL) { 500 - if (!silent) 501 - printk("VFS: unable to read V7 FS superblock on " 502 - "device %s.\n", sb->s_id); 503 - goto failed; 504 - } 505 - 506 - /* Try PDP-11 UNIX */ 507 - sbi->s_bytesex = BYTESEX_PDP; 508 - if (v7_sanity_check(sb, bh)) 509 - goto detected; 510 - 511 - /* Try PC/IX, v7/x86 */ 512 - sbi->s_bytesex = BYTESEX_LE; 513 - if (v7_sanity_check(sb, bh)) 514 - goto detected; 515 - 516 - goto failed; 517 - 518 - detected: 519 - sbi->s_bh1 = bh; 520 - sbi->s_bh2 = bh; 521 - if (complete_read_super(sb, silent, 1)) 522 - return 0; 523 - 524 - failed: 525 - printk(KERN_ERR "VFS: could not find a valid V7 on %s.\n", 526 - sb->s_id); 527 - brelse(bh); 528 - kfree(sbi); 529 - return -EINVAL; 530 - } 531 - 532 - /* Every kernel module contains stuff like this. */ 533 - 534 - static int sysv_get_tree(struct fs_context *fc) 535 - { 536 - return get_tree_bdev(fc, sysv_fill_super); 537 - } 538 - 539 - static int v7_get_tree(struct fs_context *fc) 540 - { 541 - return get_tree_bdev(fc, v7_fill_super); 542 - } 543 - 544 - static const struct fs_context_operations sysv_context_ops = { 545 - .get_tree = sysv_get_tree, 546 - }; 547 - 548 - static const struct fs_context_operations v7_context_ops = { 549 - .get_tree = v7_get_tree, 550 - }; 551 - 552 - static int sysv_init_fs_context(struct fs_context *fc) 553 - { 554 - fc->ops = &sysv_context_ops; 555 - return 0; 556 - } 557 - 558 - static int v7_init_fs_context(struct fs_context *fc) 559 - { 560 - fc->ops = &v7_context_ops; 561 - return 0; 562 - } 563 - 564 - static struct file_system_type sysv_fs_type = { 565 - .owner = THIS_MODULE, 566 - .name = "sysv", 567 - .kill_sb = kill_block_super, 568 - .fs_flags = FS_REQUIRES_DEV, 569 - .init_fs_context = sysv_init_fs_context, 570 - }; 571 - MODULE_ALIAS_FS("sysv"); 572 - 573 - static struct file_system_type v7_fs_type = { 574 - .owner = THIS_MODULE, 575 - .name = "v7", 576 - .kill_sb = kill_block_super, 577 - .fs_flags = FS_REQUIRES_DEV, 578 - .init_fs_context = v7_init_fs_context, 579 - }; 580 - MODULE_ALIAS_FS("v7"); 581 - MODULE_ALIAS("v7"); 582 - 583 - static int __init init_sysv_fs(void) 584 - { 585 - int error; 586 - 587 - error = sysv_init_icache(); 588 - if (error) 589 - goto out; 590 - error = register_filesystem(&sysv_fs_type); 591 - if (error) 592 - goto destroy_icache; 593 - error = register_filesystem(&v7_fs_type); 594 - if (error) 595 - goto unregister; 596 - return 0; 597 - 598 - unregister: 599 - unregister_filesystem(&sysv_fs_type); 600 - destroy_icache: 601 - sysv_destroy_icache(); 602 - out: 603 - return error; 604 - } 605 - 606 - static void __exit exit_sysv_fs(void) 607 - { 608 - unregister_filesystem(&sysv_fs_type); 609 - unregister_filesystem(&v7_fs_type); 610 - sysv_destroy_icache(); 611 - } 612 - 613 - module_init(init_sysv_fs) 614 - module_exit(exit_sysv_fs) 615 - MODULE_DESCRIPTION("SystemV Filesystem"); 616 - MODULE_LICENSE("GPL");
-245
fs/sysv/sysv.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef _SYSV_H 3 - #define _SYSV_H 4 - 5 - #include <linux/buffer_head.h> 6 - 7 - typedef __u16 __bitwise __fs16; 8 - typedef __u32 __bitwise __fs32; 9 - 10 - #include <linux/sysv_fs.h> 11 - 12 - /* 13 - * SystemV/V7/Coherent super-block data in memory 14 - * 15 - * The SystemV/V7/Coherent superblock contains dynamic data (it gets modified 16 - * while the system is running). This is in contrast to the Minix and Berkeley 17 - * filesystems (where the superblock is never modified). This affects the 18 - * sync() operation: we must keep the superblock in a disk buffer and use this 19 - * one as our "working copy". 20 - */ 21 - 22 - struct sysv_sb_info { 23 - struct super_block *s_sb; /* VFS superblock */ 24 - int s_type; /* file system type: FSTYPE_{XENIX|SYSV|COH} */ 25 - char s_bytesex; /* bytesex (le/be/pdp) */ 26 - unsigned int s_inodes_per_block; /* number of inodes per block */ 27 - unsigned int s_inodes_per_block_1; /* inodes_per_block - 1 */ 28 - unsigned int s_inodes_per_block_bits; /* log2(inodes_per_block) */ 29 - unsigned int s_ind_per_block; /* number of indirections per block */ 30 - unsigned int s_ind_per_block_bits; /* log2(ind_per_block) */ 31 - unsigned int s_ind_per_block_2; /* ind_per_block ^ 2 */ 32 - unsigned int s_toobig_block; /* 10 + ipb + ipb^2 + ipb^3 */ 33 - unsigned int s_block_base; /* physical block number of block 0 */ 34 - unsigned short s_fic_size; /* free inode cache size, NICINOD */ 35 - unsigned short s_flc_size; /* free block list chunk size, NICFREE */ 36 - /* The superblock is kept in one or two disk buffers: */ 37 - struct buffer_head *s_bh1; 38 - struct buffer_head *s_bh2; 39 - /* These are pointers into the disk buffer, to compensate for 40 - different superblock layout. */ 41 - char * s_sbd1; /* entire superblock data, for part 1 */ 42 - char * s_sbd2; /* entire superblock data, for part 2 */ 43 - __fs16 *s_sb_fic_count; /* pointer to s_sbd->s_ninode */ 44 - sysv_ino_t *s_sb_fic_inodes; /* pointer to s_sbd->s_inode */ 45 - __fs16 *s_sb_total_free_inodes; /* pointer to s_sbd->s_tinode */ 46 - __fs16 *s_bcache_count; /* pointer to s_sbd->s_nfree */ 47 - sysv_zone_t *s_bcache; /* pointer to s_sbd->s_free */ 48 - __fs32 *s_free_blocks; /* pointer to s_sbd->s_tfree */ 49 - __fs32 *s_sb_time; /* pointer to s_sbd->s_time */ 50 - __fs32 *s_sb_state; /* pointer to s_sbd->s_state, only FSTYPE_SYSV */ 51 - /* We keep those superblock entities that don't change here; 52 - this saves us an indirection and perhaps a conversion. */ 53 - u32 s_firstinodezone; /* index of first inode zone */ 54 - u32 s_firstdatazone; /* same as s_sbd->s_isize */ 55 - u32 s_ninodes; /* total number of inodes */ 56 - u32 s_ndatazones; /* total number of data zones */ 57 - u32 s_nzones; /* same as s_sbd->s_fsize */ 58 - u16 s_namelen; /* max length of dir entry */ 59 - int s_forced_ro; 60 - struct mutex s_lock; 61 - }; 62 - 63 - /* 64 - * SystemV/V7/Coherent FS inode data in memory 65 - */ 66 - struct sysv_inode_info { 67 - __fs32 i_data[13]; 68 - u32 i_dir_start_lookup; 69 - struct inode vfs_inode; 70 - }; 71 - 72 - 73 - static inline struct sysv_inode_info *SYSV_I(struct inode *inode) 74 - { 75 - return container_of(inode, struct sysv_inode_info, vfs_inode); 76 - } 77 - 78 - static inline struct sysv_sb_info *SYSV_SB(struct super_block *sb) 79 - { 80 - return sb->s_fs_info; 81 - } 82 - 83 - 84 - /* identify the FS in memory */ 85 - enum { 86 - FSTYPE_NONE = 0, 87 - FSTYPE_XENIX, 88 - FSTYPE_SYSV4, 89 - FSTYPE_SYSV2, 90 - FSTYPE_COH, 91 - FSTYPE_V7, 92 - FSTYPE_AFS, 93 - FSTYPE_END, 94 - }; 95 - 96 - #define SYSV_MAGIC_BASE 0x012FF7B3 97 - 98 - #define XENIX_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_XENIX) 99 - #define SYSV4_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_SYSV4) 100 - #define SYSV2_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_SYSV2) 101 - #define COH_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_COH) 102 - 103 - 104 - /* Admissible values for i_nlink: 0.._LINK_MAX */ 105 - enum { 106 - XENIX_LINK_MAX = 126, /* ?? */ 107 - SYSV_LINK_MAX = 126, /* 127? 251? */ 108 - V7_LINK_MAX = 126, /* ?? */ 109 - COH_LINK_MAX = 10000, 110 - }; 111 - 112 - 113 - static inline void dirty_sb(struct super_block *sb) 114 - { 115 - struct sysv_sb_info *sbi = SYSV_SB(sb); 116 - 117 - mark_buffer_dirty(sbi->s_bh1); 118 - if (sbi->s_bh1 != sbi->s_bh2) 119 - mark_buffer_dirty(sbi->s_bh2); 120 - } 121 - 122 - 123 - /* ialloc.c */ 124 - extern struct sysv_inode *sysv_raw_inode(struct super_block *, unsigned, 125 - struct buffer_head **); 126 - extern struct inode * sysv_new_inode(const struct inode *, umode_t); 127 - extern void sysv_free_inode(struct inode *); 128 - extern unsigned long sysv_count_free_inodes(struct super_block *); 129 - 130 - /* balloc.c */ 131 - extern sysv_zone_t sysv_new_block(struct super_block *); 132 - extern void sysv_free_block(struct super_block *, sysv_zone_t); 133 - extern unsigned long sysv_count_free_blocks(struct super_block *); 134 - 135 - /* itree.c */ 136 - void sysv_truncate(struct inode *); 137 - int sysv_prepare_chunk(struct folio *folio, loff_t pos, unsigned len); 138 - 139 - /* inode.c */ 140 - extern struct inode *sysv_iget(struct super_block *, unsigned int); 141 - extern int sysv_write_inode(struct inode *, struct writeback_control *wbc); 142 - extern int sysv_sync_inode(struct inode *); 143 - extern void sysv_set_inode(struct inode *, dev_t); 144 - extern int sysv_getattr(struct mnt_idmap *, const struct path *, 145 - struct kstat *, u32, unsigned int); 146 - extern int sysv_init_icache(void); 147 - extern void sysv_destroy_icache(void); 148 - 149 - 150 - /* dir.c */ 151 - struct sysv_dir_entry *sysv_find_entry(struct dentry *, struct folio **); 152 - int sysv_add_link(struct dentry *, struct inode *); 153 - int sysv_delete_entry(struct sysv_dir_entry *, struct folio *); 154 - int sysv_make_empty(struct inode *, struct inode *); 155 - int sysv_empty_dir(struct inode *); 156 - int sysv_set_link(struct sysv_dir_entry *, struct folio *, 157 - struct inode *); 158 - struct sysv_dir_entry *sysv_dotdot(struct inode *, struct folio **); 159 - ino_t sysv_inode_by_name(struct dentry *); 160 - 161 - 162 - extern const struct inode_operations sysv_file_inode_operations; 163 - extern const struct inode_operations sysv_dir_inode_operations; 164 - extern const struct file_operations sysv_file_operations; 165 - extern const struct file_operations sysv_dir_operations; 166 - extern const struct address_space_operations sysv_aops; 167 - extern const struct super_operations sysv_sops; 168 - 169 - 170 - enum { 171 - BYTESEX_LE, 172 - BYTESEX_PDP, 173 - BYTESEX_BE, 174 - }; 175 - 176 - static inline u32 PDP_swab(u32 x) 177 - { 178 - #ifdef __LITTLE_ENDIAN 179 - return ((x & 0xffff) << 16) | ((x & 0xffff0000) >> 16); 180 - #else 181 - #ifdef __BIG_ENDIAN 182 - return ((x & 0xff00ff) << 8) | ((x & 0xff00ff00) >> 8); 183 - #else 184 - #error BYTESEX 185 - #endif 186 - #endif 187 - } 188 - 189 - static inline __u32 fs32_to_cpu(struct sysv_sb_info *sbi, __fs32 n) 190 - { 191 - if (sbi->s_bytesex == BYTESEX_PDP) 192 - return PDP_swab((__force __u32)n); 193 - else if (sbi->s_bytesex == BYTESEX_LE) 194 - return le32_to_cpu((__force __le32)n); 195 - else 196 - return be32_to_cpu((__force __be32)n); 197 - } 198 - 199 - static inline __fs32 cpu_to_fs32(struct sysv_sb_info *sbi, __u32 n) 200 - { 201 - if (sbi->s_bytesex == BYTESEX_PDP) 202 - return (__force __fs32)PDP_swab(n); 203 - else if (sbi->s_bytesex == BYTESEX_LE) 204 - return (__force __fs32)cpu_to_le32(n); 205 - else 206 - return (__force __fs32)cpu_to_be32(n); 207 - } 208 - 209 - static inline __fs32 fs32_add(struct sysv_sb_info *sbi, __fs32 *n, int d) 210 - { 211 - if (sbi->s_bytesex == BYTESEX_PDP) 212 - *(__u32*)n = PDP_swab(PDP_swab(*(__u32*)n)+d); 213 - else if (sbi->s_bytesex == BYTESEX_LE) 214 - le32_add_cpu((__le32 *)n, d); 215 - else 216 - be32_add_cpu((__be32 *)n, d); 217 - return *n; 218 - } 219 - 220 - static inline __u16 fs16_to_cpu(struct sysv_sb_info *sbi, __fs16 n) 221 - { 222 - if (sbi->s_bytesex != BYTESEX_BE) 223 - return le16_to_cpu((__force __le16)n); 224 - else 225 - return be16_to_cpu((__force __be16)n); 226 - } 227 - 228 - static inline __fs16 cpu_to_fs16(struct sysv_sb_info *sbi, __u16 n) 229 - { 230 - if (sbi->s_bytesex != BYTESEX_BE) 231 - return (__force __fs16)cpu_to_le16(n); 232 - else 233 - return (__force __fs16)cpu_to_be16(n); 234 - } 235 - 236 - static inline __fs16 fs16_add(struct sysv_sb_info *sbi, __fs16 *n, int d) 237 - { 238 - if (sbi->s_bytesex != BYTESEX_BE) 239 - le16_add_cpu((__le16 *)n, d); 240 - else 241 - be16_add_cpu((__be16 *)n, d); 242 - return *n; 243 - } 244 - 245 - #endif /* _SYSV_H */
-214
include/linux/sysv_fs.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef _LINUX_SYSV_FS_H 3 - #define _LINUX_SYSV_FS_H 4 - 5 - #define __packed2__ __attribute__((packed, aligned(2))) 6 - 7 - 8 - #ifndef __KERNEL__ 9 - typedef u16 __fs16; 10 - typedef u32 __fs16; 11 - #endif 12 - 13 - /* inode numbers are 16 bit */ 14 - typedef __fs16 sysv_ino_t; 15 - 16 - /* Block numbers are 24 bit, sometimes stored in 32 bit. 17 - On Coherent FS, they are always stored in PDP-11 manner: the least 18 - significant 16 bits come last. */ 19 - typedef __fs32 sysv_zone_t; 20 - 21 - /* 0 is non-existent */ 22 - #define SYSV_BADBL_INO 1 /* inode of bad blocks file */ 23 - #define SYSV_ROOT_INO 2 /* inode of root directory */ 24 - 25 - 26 - /* Xenix super-block data on disk */ 27 - #define XENIX_NICINOD 100 /* number of inode cache entries */ 28 - #define XENIX_NICFREE 100 /* number of free block list chunk entries */ 29 - struct xenix_super_block { 30 - __fs16 s_isize; /* index of first data zone */ 31 - __fs32 s_fsize __packed2__; /* total number of zones of this fs */ 32 - /* the start of the free block list: */ 33 - __fs16 s_nfree; /* number of free blocks in s_free, <= XENIX_NICFREE */ 34 - sysv_zone_t s_free[XENIX_NICFREE]; /* first free block list chunk */ 35 - /* the cache of free inodes: */ 36 - __fs16 s_ninode; /* number of free inodes in s_inode, <= XENIX_NICINOD */ 37 - sysv_ino_t s_inode[XENIX_NICINOD]; /* some free inodes */ 38 - /* locks, not used by Linux: */ 39 - char s_flock; /* lock during free block list manipulation */ 40 - char s_ilock; /* lock during inode cache manipulation */ 41 - char s_fmod; /* super-block modified flag */ 42 - char s_ronly; /* flag whether fs is mounted read-only */ 43 - __fs32 s_time __packed2__; /* time of last super block update */ 44 - __fs32 s_tfree __packed2__; /* total number of free zones */ 45 - __fs16 s_tinode; /* total number of free inodes */ 46 - __fs16 s_dinfo[4]; /* device information ?? */ 47 - char s_fname[6]; /* file system volume name */ 48 - char s_fpack[6]; /* file system pack name */ 49 - char s_clean; /* set to 0x46 when filesystem is properly unmounted */ 50 - char s_fill[371]; 51 - s32 s_magic; /* version of file system */ 52 - __fs32 s_type; /* type of file system: 1 for 512 byte blocks 53 - 2 for 1024 byte blocks 54 - 3 for 2048 byte blocks */ 55 - 56 - }; 57 - 58 - /* 59 - * SystemV FS comes in two variants: 60 - * sysv2: System V Release 2 (e.g. Microport), structure elements aligned(2). 61 - * sysv4: System V Release 4 (e.g. Consensys), structure elements aligned(4). 62 - */ 63 - #define SYSV_NICINOD 100 /* number of inode cache entries */ 64 - #define SYSV_NICFREE 50 /* number of free block list chunk entries */ 65 - 66 - /* SystemV4 super-block data on disk */ 67 - struct sysv4_super_block { 68 - __fs16 s_isize; /* index of first data zone */ 69 - u16 s_pad0; 70 - __fs32 s_fsize; /* total number of zones of this fs */ 71 - /* the start of the free block list: */ 72 - __fs16 s_nfree; /* number of free blocks in s_free, <= SYSV_NICFREE */ 73 - u16 s_pad1; 74 - sysv_zone_t s_free[SYSV_NICFREE]; /* first free block list chunk */ 75 - /* the cache of free inodes: */ 76 - __fs16 s_ninode; /* number of free inodes in s_inode, <= SYSV_NICINOD */ 77 - u16 s_pad2; 78 - sysv_ino_t s_inode[SYSV_NICINOD]; /* some free inodes */ 79 - /* locks, not used by Linux: */ 80 - char s_flock; /* lock during free block list manipulation */ 81 - char s_ilock; /* lock during inode cache manipulation */ 82 - char s_fmod; /* super-block modified flag */ 83 - char s_ronly; /* flag whether fs is mounted read-only */ 84 - __fs32 s_time; /* time of last super block update */ 85 - __fs16 s_dinfo[4]; /* device information ?? */ 86 - __fs32 s_tfree; /* total number of free zones */ 87 - __fs16 s_tinode; /* total number of free inodes */ 88 - u16 s_pad3; 89 - char s_fname[6]; /* file system volume name */ 90 - char s_fpack[6]; /* file system pack name */ 91 - s32 s_fill[12]; 92 - __fs32 s_state; /* file system state: 0x7c269d38-s_time means clean */ 93 - s32 s_magic; /* version of file system */ 94 - __fs32 s_type; /* type of file system: 1 for 512 byte blocks 95 - 2 for 1024 byte blocks */ 96 - }; 97 - 98 - /* SystemV2 super-block data on disk */ 99 - struct sysv2_super_block { 100 - __fs16 s_isize; /* index of first data zone */ 101 - __fs32 s_fsize __packed2__; /* total number of zones of this fs */ 102 - /* the start of the free block list: */ 103 - __fs16 s_nfree; /* number of free blocks in s_free, <= SYSV_NICFREE */ 104 - sysv_zone_t s_free[SYSV_NICFREE]; /* first free block list chunk */ 105 - /* the cache of free inodes: */ 106 - __fs16 s_ninode; /* number of free inodes in s_inode, <= SYSV_NICINOD */ 107 - sysv_ino_t s_inode[SYSV_NICINOD]; /* some free inodes */ 108 - /* locks, not used by Linux: */ 109 - char s_flock; /* lock during free block list manipulation */ 110 - char s_ilock; /* lock during inode cache manipulation */ 111 - char s_fmod; /* super-block modified flag */ 112 - char s_ronly; /* flag whether fs is mounted read-only */ 113 - __fs32 s_time __packed2__; /* time of last super block update */ 114 - __fs16 s_dinfo[4]; /* device information ?? */ 115 - __fs32 s_tfree __packed2__; /* total number of free zones */ 116 - __fs16 s_tinode; /* total number of free inodes */ 117 - char s_fname[6]; /* file system volume name */ 118 - char s_fpack[6]; /* file system pack name */ 119 - s32 s_fill[14]; 120 - __fs32 s_state; /* file system state: 0xcb096f43 means clean */ 121 - s32 s_magic; /* version of file system */ 122 - __fs32 s_type; /* type of file system: 1 for 512 byte blocks 123 - 2 for 1024 byte blocks */ 124 - }; 125 - 126 - /* V7 super-block data on disk */ 127 - #define V7_NICINOD 100 /* number of inode cache entries */ 128 - #define V7_NICFREE 50 /* number of free block list chunk entries */ 129 - struct v7_super_block { 130 - __fs16 s_isize; /* index of first data zone */ 131 - __fs32 s_fsize __packed2__; /* total number of zones of this fs */ 132 - /* the start of the free block list: */ 133 - __fs16 s_nfree; /* number of free blocks in s_free, <= V7_NICFREE */ 134 - sysv_zone_t s_free[V7_NICFREE]; /* first free block list chunk */ 135 - /* the cache of free inodes: */ 136 - __fs16 s_ninode; /* number of free inodes in s_inode, <= V7_NICINOD */ 137 - sysv_ino_t s_inode[V7_NICINOD]; /* some free inodes */ 138 - /* locks, not used by Linux or V7: */ 139 - char s_flock; /* lock during free block list manipulation */ 140 - char s_ilock; /* lock during inode cache manipulation */ 141 - char s_fmod; /* super-block modified flag */ 142 - char s_ronly; /* flag whether fs is mounted read-only */ 143 - __fs32 s_time __packed2__; /* time of last super block update */ 144 - /* the following fields are not maintained by V7: */ 145 - __fs32 s_tfree __packed2__; /* total number of free zones */ 146 - __fs16 s_tinode; /* total number of free inodes */ 147 - __fs16 s_m; /* interleave factor */ 148 - __fs16 s_n; /* interleave factor */ 149 - char s_fname[6]; /* file system name */ 150 - char s_fpack[6]; /* file system pack name */ 151 - }; 152 - /* Constants to aid sanity checking */ 153 - /* This is not a hard limit, nor enforced by v7 kernel. It's actually just 154 - * the limit used by Seventh Edition's ls, though is high enough to assume 155 - * that no reasonable file system would have that much entries in root 156 - * directory. Thus, if we see anything higher, we just probably got the 157 - * endiannes wrong. */ 158 - #define V7_NFILES 1024 159 - /* The disk addresses are three-byte (despite direct block addresses being 160 - * aligned word-wise in inode). If the most significant byte is non-zero, 161 - * something is most likely wrong (not a filesystem, bad bytesex). */ 162 - #define V7_MAXSIZE 0x00ffffff 163 - 164 - /* Coherent super-block data on disk */ 165 - #define COH_NICINOD 100 /* number of inode cache entries */ 166 - #define COH_NICFREE 64 /* number of free block list chunk entries */ 167 - struct coh_super_block { 168 - __fs16 s_isize; /* index of first data zone */ 169 - __fs32 s_fsize __packed2__; /* total number of zones of this fs */ 170 - /* the start of the free block list: */ 171 - __fs16 s_nfree; /* number of free blocks in s_free, <= COH_NICFREE */ 172 - sysv_zone_t s_free[COH_NICFREE] __packed2__; /* first free block list chunk */ 173 - /* the cache of free inodes: */ 174 - __fs16 s_ninode; /* number of free inodes in s_inode, <= COH_NICINOD */ 175 - sysv_ino_t s_inode[COH_NICINOD]; /* some free inodes */ 176 - /* locks, not used by Linux: */ 177 - char s_flock; /* lock during free block list manipulation */ 178 - char s_ilock; /* lock during inode cache manipulation */ 179 - char s_fmod; /* super-block modified flag */ 180 - char s_ronly; /* flag whether fs is mounted read-only */ 181 - __fs32 s_time __packed2__; /* time of last super block update */ 182 - __fs32 s_tfree __packed2__; /* total number of free zones */ 183 - __fs16 s_tinode; /* total number of free inodes */ 184 - __fs16 s_interleave_m; /* interleave factor */ 185 - __fs16 s_interleave_n; 186 - char s_fname[6]; /* file system volume name */ 187 - char s_fpack[6]; /* file system pack name */ 188 - __fs32 s_unique; /* zero, not used */ 189 - }; 190 - 191 - /* SystemV/Coherent inode data on disk */ 192 - struct sysv_inode { 193 - __fs16 i_mode; 194 - __fs16 i_nlink; 195 - __fs16 i_uid; 196 - __fs16 i_gid; 197 - __fs32 i_size; 198 - u8 i_data[3*(10+1+1+1)]; 199 - u8 i_gen; 200 - __fs32 i_atime; /* time of last access */ 201 - __fs32 i_mtime; /* time of last modification */ 202 - __fs32 i_ctime; /* time of creation */ 203 - }; 204 - 205 - /* SystemV/Coherent directory entry on disk */ 206 - #define SYSV_NAMELEN 14 /* max size of name in struct sysv_dir_entry */ 207 - struct sysv_dir_entry { 208 - sysv_ino_t inode; 209 - char name[SYSV_NAMELEN]; /* up to 14 characters, the rest are zeroes */ 210 - }; 211 - 212 - #define SYSV_DIRSIZE sizeof(struct sysv_dir_entry) /* size of every directory entry */ 213 - 214 - #endif /* _LINUX_SYSV_FS_H */