Annotation of XNU/bsd/ufs/lfs/lfs_alloc.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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