1331722Seadler/* 299193Sjmallett * Copyright (c) 2002 Juli Mallett. All rights reserved. 399193Sjmallett * 499193Sjmallett * This software was written by Juli Mallett <jmallett@FreeBSD.org> for the 599193Sjmallett * FreeBSD project. Redistribution and use in source and binary forms, with 699193Sjmallett * or without modification, are permitted provided that the following 799193Sjmallett * conditions are met: 899193Sjmallett * 999193Sjmallett * 1. Redistribution of source code must retain the above copyright notice, 1099193Sjmallett * this list of conditions and the following disclaimer. 1199193Sjmallett * 2. Redistribution in binary form must reproduce the above copyright 1299193Sjmallett * notice, this list of conditions and the following disclaimer in the 1399193Sjmallett * documentation and/or other materials provided with the distribution. 1499193Sjmallett * 1599193Sjmallett * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1699193Sjmallett * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 1799193Sjmallett * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 1899193Sjmallett * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 1999193Sjmallett * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 2099193Sjmallett * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 2199193Sjmallett * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2299193Sjmallett * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 2399193Sjmallett * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 2499193Sjmallett * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2599193Sjmallett * POSSIBILITY OF SUCH DAMAGE. 2699193Sjmallett */ 2799193Sjmallett 2899193Sjmallett#include <sys/cdefs.h> 2999193Sjmallett__FBSDID("$FreeBSD: stable/11/lib/libufs/inode.c 332638 2018-04-17 00:03:32Z mckusick $"); 3099193Sjmallett 3199193Sjmallett#include <sys/param.h> 3299193Sjmallett#include <sys/mount.h> 3399193Sjmallett#include <sys/disklabel.h> 3499193Sjmallett#include <sys/stat.h> 3599193Sjmallett 3699193Sjmallett#include <ufs/ufs/ufsmount.h> 3799193Sjmallett#include <ufs/ufs/dinode.h> 3899193Sjmallett#include <ufs/ffs/fs.h> 3999193Sjmallett 4099193Sjmallett#include <errno.h> 4199193Sjmallett#include <fcntl.h> 4299193Sjmallett#include <stdio.h> 4399193Sjmallett#include <stdlib.h> 4499193Sjmallett#include <string.h> 4599193Sjmallett#include <unistd.h> 4699193Sjmallett 4799193Sjmallett#include <libufs.h> 4899193Sjmallett 4999193Sjmallettint 5099193Sjmallettgetino(struct uufsd *disk, void **dino, ino_t inode, int *mode) 5199193Sjmallett{ 5299193Sjmallett ino_t min, max; 5399193Sjmallett caddr_t inoblock; 5499193Sjmallett struct ufs1_dinode *dp1; 5599193Sjmallett struct ufs2_dinode *dp2; 5699193Sjmallett struct fs *fs; 5799193Sjmallett 58109462Sjmallett ERROR(disk, NULL); 5999193Sjmallett 6099193Sjmallett fs = &disk->d_fs; 61332638Smckusick if (inode >= (ino_t)fs->fs_ipg * fs->fs_ncg) { 62332638Smckusick ERROR(disk, "inode number out of range"); 63332638Smckusick return (-1); 64332638Smckusick } 6599193Sjmallett inoblock = disk->d_inoblock; 6699193Sjmallett min = disk->d_inomin; 6799193Sjmallett max = disk->d_inomax; 6899193Sjmallett 6999193Sjmallett if (inoblock == NULL) { 7099193Sjmallett inoblock = malloc(fs->fs_bsize); 7199193Sjmallett if (inoblock == NULL) { 72109462Sjmallett ERROR(disk, "unable to allocate inode block"); 73116084Sjmallett return (-1); 7499193Sjmallett } 7599193Sjmallett disk->d_inoblock = inoblock; 7699193Sjmallett } 7799193Sjmallett if (inode >= min && inode < max) 7899193Sjmallett goto gotit; 7999193Sjmallett bread(disk, fsbtodb(fs, ino_to_fsba(fs, inode)), inoblock, 8099193Sjmallett fs->fs_bsize); 81116591Smdodd disk->d_inomin = min = inode - (inode % INOPB(fs)); 8299823Sjmallett disk->d_inomax = max = min + INOPB(fs); 8399193Sjmallettgotit: switch (disk->d_ufs) { 8499193Sjmallett case 1: 8599193Sjmallett dp1 = &((struct ufs1_dinode *)inoblock)[inode - min]; 86332638Smckusick if (mode != NULL) 87332638Smckusick *mode = dp1->di_mode & IFMT; 88332638Smckusick if (dino != NULL) 89332638Smckusick *dino = dp1; 90116084Sjmallett return (0); 9199193Sjmallett case 2: 9299193Sjmallett dp2 = &((struct ufs2_dinode *)inoblock)[inode - min]; 93332638Smckusick if (mode != NULL) 94332638Smckusick *mode = dp2->di_mode & IFMT; 95332638Smckusick if (dino != NULL) 96332638Smckusick *dino = dp2; 97116084Sjmallett return (0); 9899193Sjmallett default: 9999193Sjmallett break; 10099193Sjmallett } 101109462Sjmallett ERROR(disk, "unknown UFS filesystem type"); 102116084Sjmallett return (-1); 10399193Sjmallett} 104207141Sjeff 105207141Sjeffint 106207141Sjeffputino(struct uufsd *disk) 107207141Sjeff{ 108207141Sjeff struct fs *fs; 109207141Sjeff 110207141Sjeff fs = &disk->d_fs; 111207141Sjeff if (disk->d_inoblock == NULL) { 112207141Sjeff ERROR(disk, "No inode block allocated"); 113207141Sjeff return (-1); 114207141Sjeff } 115207141Sjeff if (bwrite(disk, fsbtodb(fs, ino_to_fsba(&disk->d_fs, disk->d_inomin)), 116207141Sjeff disk->d_inoblock, disk->d_fs.fs_bsize) <= 0) 117207141Sjeff return (-1); 118207141Sjeff return (0); 119207141Sjeff} 120