Annotation of kernel/bsd/ufs/lfs/lfs_alloc.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*     $NetBSD: lfs_alloc.c,v 1.2 1994/06/29 06:46:47 cgd Exp $        */
                     26: 
                     27: /*
                     28:  * Copyright (c) 1991, 1993
                     29:  *     The Regents of the University of California.  All rights reserved.
                     30:  *
                     31:  * Redistribution and use in source and binary forms, with or without
                     32:  * modification, are permitted provided that the following conditions
                     33:  * are met:
                     34:  * 1. Redistributions of source code must retain the above copyright
                     35:  *    notice, this list of conditions and the following disclaimer.
                     36:  * 2. Redistributions in binary form must reproduce the above copyright
                     37:  *    notice, this list of conditions and the following disclaimer in the
                     38:  *    documentation and/or other materials provided with the distribution.
                     39:  * 3. All advertising materials mentioning features or use of this software
                     40:  *    must display the following acknowledgement:
                     41:  *     This product includes software developed by the University of
                     42:  *     California, Berkeley and its contributors.
                     43:  * 4. Neither the name of the University nor the names of its contributors
                     44:  *    may be used to endorse or promote products derived from this software
                     45:  *    without specific prior written permission.
                     46:  *
                     47:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     48:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     49:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     50:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     51:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     52:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     53:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     54:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     55:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     56:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     57:  * SUCH DAMAGE.
                     58:  *
                     59:  *     @(#)lfs_alloc.c 8.4 (Berkeley) 1/4/94
                     60:  */
                     61: 
                     62: #include <sys/param.h>
                     63: #include <sys/kernel.h>
                     64: #include <sys/buf.h>
                     65: #include <sys/vnode.h>
                     66: #include <sys/syslog.h>
                     67: #include <sys/mount.h>
                     68: #include <sys/malloc.h>
                     69: 
                     70: #include <vm/vm.h>
                     71: 
                     72: #include <ufs/ufs/quota.h>
                     73: #include <ufs/ufs/inode.h>
                     74: #include <ufs/ufs/ufsmount.h>
                     75: 
                     76: #include <ufs/lfs/lfs.h>
                     77: #include <ufs/lfs/lfs_extern.h>
                     78: 
                     79: extern u_long nextgennumber;
                     80: 
                     81: /* Allocate a new inode. */
                     82: /* ARGSUSED */
                     83: int
                     84: lfs_valloc(ap)
                     85:        struct vop_valloc_args /* {
                     86:                struct vnode *a_pvp;
                     87:                int a_mode;
                     88:                struct ucred *a_cred;
                     89:                struct vnode **a_vpp;
                     90:        } */ *ap;
                     91: {
                     92:        struct lfs *fs;
                     93:        struct buf *bp;
                     94:        struct ifile *ifp;
                     95:        struct inode *ip;
                     96:        struct vnode *vp;
                     97:        daddr_t blkno;
                     98:        ino_t new_ino;
                     99:        u_long i, max;
                    100:        int error;
                    101: 
                    102:        /* Get the head of the freelist. */
                    103:        fs = VTOI(ap->a_pvp)->i_lfs;
                    104:        new_ino = fs->lfs_free;
                    105: #ifdef ALLOCPRINT
                    106:        printf("lfs_ialloc: allocate inode %d\n", new_ino);
                    107: #endif
                    108: 
                    109:        /*
                    110:         * Remove the inode from the free list and write the new start
                    111:         * of the free list into the superblock.
                    112:         */
                    113:        LFS_IENTRY(ifp, fs, new_ino, bp);
                    114:        if (ifp->if_daddr != LFS_UNUSED_DADDR)
                    115:                panic("lfs_ialloc: inuse inode on the free list");
                    116:        fs->lfs_free = ifp->if_nextfree;
                    117:        brelse(bp);
                    118: 
                    119:        /* Extend IFILE so that the next lfs_valloc will succeed. */
                    120:        if (fs->lfs_free == LFS_UNUSED_INUM) {
                    121:                vp = fs->lfs_ivnode;
                    122:                ip = VTOI(vp);
                    123:                blkno = lblkno(fs, ip->i_size);
                    124:                lfs_balloc(vp, fs->lfs_bsize, blkno, &bp);
                    125:                ip->i_size += fs->lfs_bsize;
                    126:                vnode_pager_setsize(vp, (u_long)ip->i_size);
                    127:                vnode_pager_uncache(vp);
                    128: 
                    129:                i = (blkno - fs->lfs_segtabsz - fs->lfs_cleansz) *
                    130:                    fs->lfs_ifpb;
                    131:                fs->lfs_free = i;
                    132:                max = i + fs->lfs_ifpb;
                    133:                for (ifp = (struct ifile *)bp->b_data; i < max; ++ifp) {
                    134:                        ifp->if_version = 1;
                    135:                        ifp->if_daddr = LFS_UNUSED_DADDR;
                    136:                        ifp->if_nextfree = ++i;
                    137:                }
                    138:                ifp--;
                    139:                ifp->if_nextfree = LFS_UNUSED_INUM;
                    140:                if (error = VOP_BWRITE(bp))
                    141:                        return (error);
                    142:        }
                    143: 
                    144:        /* Create a vnode to associate with the inode. */
                    145:        if (error = lfs_vcreate(ap->a_pvp->v_mount, new_ino, &vp))
                    146:                return (error);
                    147: 
                    148: 
                    149:        ip = VTOI(vp);
                    150:        /* Zero out the direct and indirect block addresses. */
                    151:        bzero(&ip->i_din, sizeof(struct dinode));
                    152:        ip->i_din.di_inumber = new_ino;
                    153: 
                    154:        /* Set a new generation number for this inode. */
                    155:        if (++nextgennumber < (u_long)time.tv_sec)
                    156:                nextgennumber = time.tv_sec;
                    157:        ip->i_gen = nextgennumber;
                    158: 
                    159:        /* Insert into the inode hash table. */
                    160:        ufs_ihashins(ip);
                    161: 
                    162:        if (error = ufs_vinit(vp->v_mount, lfs_specop_p, LFS_FIFOOPS, &vp)) {
                    163:                vput(vp);
                    164:                *ap->a_vpp = NULL;
                    165:                return (error);
                    166:        }
                    167: 
                    168:        *ap->a_vpp = vp;
                    169:        vp->v_flag |= VDIROP;
                    170:        VREF(ip->i_devvp);
                    171: 
                    172:        /* Set superblock modified bit and increment file count. */
                    173:        fs->lfs_fmod = 1;
                    174:        ++fs->lfs_nfiles;
                    175:        return (0);
                    176: }
                    177: 
                    178: /* Create a new vnode/inode pair and initialize what fields we can. */
                    179: int
                    180: lfs_vcreate(mp, ino, vpp)
                    181:        struct mount *mp;
                    182:        ino_t ino;
                    183:        struct vnode **vpp;
                    184: {
                    185:        extern int (**lfs_vnodeop_p)();
                    186:        struct inode *ip;
                    187:        struct ufsmount *ump;
                    188:        int error, i;
                    189: 
                    190:        /* Create the vnode. */
                    191:        if (error = getnewvnode(VT_LFS, mp, lfs_vnodeop_p, vpp)) {
                    192:                *vpp = NULL;
                    193:                return (error);
                    194:        }
                    195: 
                    196:        /* Get a pointer to the private mount structure. */
                    197:        ump = VFSTOUFS(mp);
                    198: 
                    199:        /* Initialize the inode. */
                    200:        MALLOC(ip, struct inode *, sizeof(struct inode), M_LFSNODE, M_WAITOK);
                    201:        (*vpp)->v_data = ip;
                    202:        ip->i_vnode = *vpp;
                    203:        ip->i_devvp = ump->um_devvp;
                    204:        ip->i_flag = IN_MODIFIED;
                    205:        ip->i_dev = ump->um_dev;
                    206:        ip->i_number = ip->i_din.di_inumber = ino;
                    207: ip->i_din.di_spare[0] = 0xdeadbeef;
                    208: ip->i_din.di_spare[1] = 0xdeadbeef;
                    209:        ip->i_lfs = ump->um_lfs;
1.1.1.2 ! root      210: #if QUOTA
1.1       root      211:        for (i = 0; i < MAXQUOTAS; i++)
                    212:                ip->i_dquot[i] = NODQUOT;
                    213: #endif
                    214:        ip->i_lockf = 0;
                    215:        ip->i_diroff = 0;
                    216:        ip->i_mode = 0;
                    217:        ip->i_size = 0;
                    218:        ip->i_blocks = 0;
                    219:        ++ump->um_lfs->lfs_uinodes;
                    220:        return (0);
                    221: }
                    222: 
                    223: /* Free an inode. */
                    224: /* ARGUSED */
                    225: int
                    226: lfs_vfree(ap)
                    227:        struct vop_vfree_args /* {
                    228:                struct vnode *a_pvp;
                    229:                ino_t a_ino;
                    230:                int a_mode;
                    231:        } */ *ap;
                    232: {
                    233:        SEGUSE *sup;
                    234:        struct buf *bp;
                    235:        struct ifile *ifp;
                    236:        struct inode *ip;
                    237:        struct lfs *fs;
                    238:        daddr_t old_iaddr;
                    239:        ino_t ino;
                    240: 
                    241:        /* Get the inode number and file system. */
                    242:        ip = VTOI(ap->a_pvp);
                    243:        fs = ip->i_lfs;
                    244:        ino = ip->i_number;
                    245:        if (ip->i_flag & IN_MODIFIED) {
                    246:                --fs->lfs_uinodes;
                    247:                ip->i_flag &=
                    248:                    ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
                    249:        }
                    250:        /*
                    251:         * Set the ifile's inode entry to unused, increment its version number
                    252:         * and link it into the free chain.
                    253:         */
                    254:        LFS_IENTRY(ifp, fs, ino, bp);
                    255:        old_iaddr = ifp->if_daddr;
                    256:        ifp->if_daddr = LFS_UNUSED_DADDR;
                    257:        ++ifp->if_version;
                    258:        ifp->if_nextfree = fs->lfs_free;
                    259:        fs->lfs_free = ino;
                    260:        (void) VOP_BWRITE(bp);
                    261: 
                    262:        if (old_iaddr != LFS_UNUSED_DADDR) {
                    263:                LFS_SEGENTRY(sup, fs, datosn(fs, old_iaddr), bp);
                    264: #if DIAGNOSTIC
                    265:                if (sup->su_nbytes < sizeof(struct dinode))
                    266:                        panic("lfs_vfree: negative byte count (segment %d)\n",
                    267:                            datosn(fs, old_iaddr));
                    268: #endif
                    269:                sup->su_nbytes -= sizeof(struct dinode);
                    270:                (void) VOP_BWRITE(bp);
                    271:        }
                    272: 
                    273:        /* Set superblock modified bit and decrement file count. */
                    274:        fs->lfs_fmod = 1;
                    275:        --fs->lfs_nfiles;
                    276:        return (0);
                    277: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.