Annotation of XNU/bsd/ufs/ffs/ffs_vnops.c, revision 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: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
        !            23: /*
        !            24:  * Copyright (c) 1982, 1986, 1989, 1993
        !            25:  *     The Regents of the University of California.  All rights reserved.
        !            26:  *
        !            27:  * Redistribution and use in source and binary forms, with or without
        !            28:  * modification, are permitted provided that the following conditions
        !            29:  * are met:
        !            30:  * 1. Redistributions of source code must retain the above copyright
        !            31:  *    notice, this list of conditions and the following disclaimer.
        !            32:  * 2. Redistributions in binary form must reproduce the above copyright
        !            33:  *    notice, this list of conditions and the following disclaimer in the
        !            34:  *    documentation and/or other materials provided with the distribution.
        !            35:  * 3. All advertising materials mentioning features or use of this software
        !            36:  *    must display the following acknowledgement:
        !            37:  *     This product includes software developed by the University of
        !            38:  *     California, Berkeley and its contributors.
        !            39:  * 4. Neither the name of the University nor the names of its contributors
        !            40:  *    may be used to endorse or promote products derived from this software
        !            41:  *    without specific prior written permission.
        !            42:  *
        !            43:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            44:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            45:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            46:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            47:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            48:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            49:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            50:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            51:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            52:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            53:  * SUCH DAMAGE.
        !            54:  *
        !            55:  *     @(#)ffs_vnops.c 8.15 (Berkeley) 5/14/95
        !            56:  */
        !            57: 
        !            58: #include <rev_endian_fs.h>
        !            59: #include <sys/param.h>
        !            60: #include <sys/systm.h>
        !            61: #include <sys/resourcevar.h>
        !            62: #include <sys/kernel.h>
        !            63: #include <sys/file.h>
        !            64: #include <sys/stat.h>
        !            65: #include <sys/buf.h>
        !            66: #include <sys/proc.h>
        !            67: #include <sys/conf.h>
        !            68: #include <sys/mount.h>
        !            69: #include <sys/vnode.h>
        !            70: #include <sys/malloc.h>
        !            71: 
        !            72: #include <sys/vm.h>
        !            73: #include <vfs/vfs_support.h>
        !            74: 
        !            75: #include <miscfs/specfs/specdev.h>
        !            76: #include <miscfs/fifofs/fifo.h>
        !            77: 
        !            78: #include <ufs/ufs/lockf.h>
        !            79: #include <ufs/ufs/quota.h>
        !            80: #include <ufs/ufs/inode.h>
        !            81: #include <ufs/ufs/dir.h>
        !            82: #include <ufs/ufs/ufsmount.h>
        !            83: #include <ufs/ufs/ufs_extern.h>
        !            84: 
        !            85: #include <ufs/ffs/fs.h>
        !            86: #include <ufs/ffs/ffs_extern.h>
        !            87: #if REV_ENDIAN_FS
        !            88: #include <ufs/ufs/ufs_byte_order.h>
        !            89: #include <architecture/byte_order.h>
        !            90: #endif /* REV_ENDIAN_FS */
        !            91: 
        !            92: /* Global vfs data structures for ufs. */
        !            93: int (**ffs_vnodeop_p)();
        !            94: struct vnodeopv_entry_desc ffs_vnodeop_entries[] = {
        !            95:        { &vop_default_desc, vn_default_error },
        !            96:        { &vop_lookup_desc, ufs_lookup },               /* lookup */
        !            97:        { &vop_create_desc, ufs_create },               /* create */
        !            98:        { &vop_whiteout_desc, ufs_whiteout },           /* whiteout */
        !            99:        { &vop_mknod_desc, ufs_mknod },                 /* mknod */
        !           100:        { &vop_open_desc, ufs_open },                   /* open */
        !           101:        { &vop_close_desc, ufs_close },                 /* close */
        !           102:        { &vop_access_desc, ufs_access },               /* access */
        !           103:        { &vop_getattr_desc, ufs_getattr },             /* getattr */
        !           104:        { &vop_setattr_desc, ufs_setattr },             /* setattr */
        !           105:        { &vop_read_desc, ffs_read },                   /* read */
        !           106:        { &vop_write_desc, ffs_write },                 /* write */
        !           107:        { &vop_lease_desc, ufs_lease_check },           /* lease */
        !           108:        { &vop_ioctl_desc, ufs_ioctl },                 /* ioctl */
        !           109:        { &vop_select_desc, ufs_select },               /* select */
        !           110:        { &vop_revoke_desc, ufs_revoke },               /* revoke */
        !           111:        { &vop_mmap_desc, ufs_mmap },                   /* mmap */
        !           112:        { &vop_fsync_desc, ffs_fsync },                 /* fsync */
        !           113:        { &vop_seek_desc, ufs_seek },                   /* seek */
        !           114:        { &vop_remove_desc, ufs_remove },               /* remove */
        !           115:        { &vop_link_desc, ufs_link },                   /* link */
        !           116:        { &vop_rename_desc, ufs_rename },               /* rename */
        !           117:        { &vop_mkdir_desc, ufs_mkdir },                 /* mkdir */
        !           118:        { &vop_rmdir_desc, ufs_rmdir },                 /* rmdir */
        !           119:        { &vop_symlink_desc, ufs_symlink },             /* symlink */
        !           120:        { &vop_readdir_desc, ufs_readdir },             /* readdir */
        !           121:        { &vop_readlink_desc, ufs_readlink },           /* readlink */
        !           122:        { &vop_abortop_desc, ufs_abortop },             /* abortop */
        !           123:        { &vop_inactive_desc, ufs_inactive },           /* inactive */
        !           124:        { &vop_reclaim_desc, ffs_reclaim },             /* reclaim */
        !           125:        { &vop_lock_desc, ufs_lock },                   /* lock */
        !           126:        { &vop_unlock_desc, ufs_unlock },               /* unlock */
        !           127:        { &vop_bmap_desc, ufs_bmap },                   /* bmap */
        !           128:        { &vop_strategy_desc, ufs_strategy },           /* strategy */
        !           129:        { &vop_print_desc, ufs_print },                 /* print */
        !           130:        { &vop_islocked_desc, ufs_islocked },           /* islocked */
        !           131:        { &vop_pathconf_desc, ufs_pathconf },           /* pathconf */
        !           132:        { &vop_advlock_desc, ufs_advlock },             /* advlock */
        !           133:        { &vop_blkatoff_desc, ffs_blkatoff },           /* blkatoff */
        !           134:        { &vop_valloc_desc, ffs_valloc },               /* valloc */
        !           135:        { &vop_reallocblks_desc, ffs_reallocblks },     /* reallocblks */
        !           136:        { &vop_vfree_desc, ffs_vfree },                 /* vfree */
        !           137:        { &vop_truncate_desc, ffs_truncate },           /* truncate */
        !           138:        { &vop_update_desc, ffs_update },               /* update */
        !           139:        { &vop_bwrite_desc, vn_bwrite },
        !           140:        { &vop_pagein_desc, ufs_pagein },               /* Pagein */
        !           141:        { &vop_pageout_desc, ufs_pageout },             /* Pageout */
        !           142:        { &vop_copyfile_desc, err_copyfile },           /*  Copy File */
        !           143:        { (struct vnodeop_desc*)NULL, (int(*)())NULL }
        !           144: };
        !           145: struct vnodeopv_desc ffs_vnodeop_opv_desc =
        !           146:        { &ffs_vnodeop_p, ffs_vnodeop_entries };
        !           147: 
        !           148: int (**ffs_specop_p)();
        !           149: struct vnodeopv_entry_desc ffs_specop_entries[] = {
        !           150:        { &vop_default_desc, vn_default_error },
        !           151:        { &vop_lookup_desc, spec_lookup },              /* lookup */
        !           152:        { &vop_create_desc, spec_create },              /* create */
        !           153:        { &vop_mknod_desc, spec_mknod },                /* mknod */
        !           154:        { &vop_open_desc, spec_open },                  /* open */
        !           155:        { &vop_close_desc, ufsspec_close },             /* close */
        !           156:        { &vop_access_desc, ufs_access },               /* access */
        !           157:        { &vop_getattr_desc, ufs_getattr },             /* getattr */
        !           158:        { &vop_setattr_desc, ufs_setattr },             /* setattr */
        !           159:        { &vop_read_desc, ufsspec_read },               /* read */
        !           160:        { &vop_write_desc, ufsspec_write },             /* write */
        !           161:        { &vop_lease_desc, spec_lease_check },          /* lease */
        !           162:        { &vop_ioctl_desc, spec_ioctl },                /* ioctl */
        !           163:        { &vop_select_desc, spec_select },              /* select */
        !           164:        { &vop_revoke_desc, spec_revoke },              /* revoke */
        !           165:        { &vop_mmap_desc, spec_mmap },                  /* mmap */
        !           166:        { &vop_fsync_desc, ffs_fsync },                 /* fsync */
        !           167:        { &vop_seek_desc, spec_seek },                  /* seek */
        !           168:        { &vop_remove_desc, spec_remove },              /* remove */
        !           169:        { &vop_link_desc, spec_link },                  /* link */
        !           170:        { &vop_rename_desc, spec_rename },              /* rename */
        !           171:        { &vop_mkdir_desc, spec_mkdir },                /* mkdir */
        !           172:        { &vop_rmdir_desc, spec_rmdir },                /* rmdir */
        !           173:        { &vop_symlink_desc, spec_symlink },            /* symlink */
        !           174:        { &vop_readdir_desc, spec_readdir },            /* readdir */
        !           175:        { &vop_readlink_desc, spec_readlink },          /* readlink */
        !           176:        { &vop_abortop_desc, spec_abortop },            /* abortop */
        !           177:        { &vop_inactive_desc, ufs_inactive },           /* inactive */
        !           178:        { &vop_reclaim_desc, ffs_reclaim },             /* reclaim */
        !           179:        { &vop_lock_desc, ufs_lock },                   /* lock */
        !           180:        { &vop_unlock_desc, ufs_unlock },               /* unlock */
        !           181:        { &vop_bmap_desc, spec_bmap },                  /* bmap */
        !           182:        { &vop_strategy_desc, spec_strategy },          /* strategy */
        !           183:        { &vop_print_desc, ufs_print },                 /* print */
        !           184:        { &vop_islocked_desc, ufs_islocked },           /* islocked */
        !           185:        { &vop_pathconf_desc, spec_pathconf },          /* pathconf */
        !           186:        { &vop_advlock_desc, spec_advlock },            /* advlock */
        !           187:        { &vop_blkatoff_desc, spec_blkatoff },          /* blkatoff */
        !           188:        { &vop_valloc_desc, spec_valloc },              /* valloc */
        !           189:        { &vop_reallocblks_desc, spec_reallocblks },    /* reallocblks */
        !           190:        { &vop_vfree_desc, ffs_vfree },                 /* vfree */
        !           191:        { &vop_truncate_desc, spec_truncate },          /* truncate */
        !           192:        { &vop_update_desc, ffs_update },               /* update */
        !           193:        { &vop_bwrite_desc, vn_bwrite },
        !           194: #ifdef NeXT
        !           195:        { &vop_devblocksize_desc, spec_devblocksize },  /* devblocksize */
        !           196: #endif /* NeXT */
        !           197:        { &vop_pagein_desc, ufs_pagein },               /* Pagein */
        !           198:        { &vop_pageout_desc, ufs_pageout },             /* Pageout */
        !           199:        { &vop_copyfile_desc, err_copyfile },           /*  Copy File */
        !           200:        { (struct vnodeop_desc*)NULL, (int(*)())NULL }
        !           201: };
        !           202: struct vnodeopv_desc ffs_specop_opv_desc =
        !           203:        { &ffs_specop_p, ffs_specop_entries };
        !           204: 
        !           205: #if FIFO
        !           206: int (**ffs_fifoop_p)();
        !           207: struct vnodeopv_entry_desc ffs_fifoop_entries[] = {
        !           208:        { &vop_default_desc, vn_default_error },
        !           209:        { &vop_lookup_desc, fifo_lookup },              /* lookup */
        !           210:        { &vop_create_desc, fifo_create },              /* create */
        !           211:        { &vop_mknod_desc, fifo_mknod },                /* mknod */
        !           212:        { &vop_open_desc, fifo_open },                  /* open */
        !           213:        { &vop_close_desc, ufsfifo_close },             /* close */
        !           214:        { &vop_access_desc, ufs_access },               /* access */
        !           215:        { &vop_getattr_desc, ufs_getattr },             /* getattr */
        !           216:        { &vop_setattr_desc, ufs_setattr },             /* setattr */
        !           217:        { &vop_read_desc, ufsfifo_read },               /* read */
        !           218:        { &vop_write_desc, ufsfifo_write },             /* write */
        !           219:        { &vop_lease_desc, fifo_lease_check },          /* lease */
        !           220:        { &vop_ioctl_desc, fifo_ioctl },                /* ioctl */
        !           221:        { &vop_select_desc, fifo_select },              /* select */
        !           222:        { &vop_revoke_desc, fifo_revoke },              /* revoke */
        !           223:        { &vop_mmap_desc, fifo_mmap },                  /* mmap */
        !           224:        { &vop_fsync_desc, ffs_fsync },                 /* fsync */
        !           225:        { &vop_seek_desc, fifo_seek },                  /* seek */
        !           226:        { &vop_remove_desc, fifo_remove },              /* remove */
        !           227:        { &vop_link_desc, fifo_link },                  /* link */
        !           228:        { &vop_rename_desc, fifo_rename },              /* rename */
        !           229:        { &vop_mkdir_desc, fifo_mkdir },                /* mkdir */
        !           230:        { &vop_rmdir_desc, fifo_rmdir },                /* rmdir */
        !           231:        { &vop_symlink_desc, fifo_symlink },            /* symlink */
        !           232:        { &vop_readdir_desc, fifo_readdir },            /* readdir */
        !           233:        { &vop_readlink_desc, fifo_readlink },          /* readlink */
        !           234:        { &vop_abortop_desc, fifo_abortop },            /* abortop */
        !           235:        { &vop_inactive_desc, ufs_inactive },           /* inactive */
        !           236:        { &vop_reclaim_desc, ffs_reclaim },             /* reclaim */
        !           237:        { &vop_lock_desc, ufs_lock },                   /* lock */
        !           238:        { &vop_unlock_desc, ufs_unlock },               /* unlock */
        !           239:        { &vop_bmap_desc, fifo_bmap },                  /* bmap */
        !           240:        { &vop_strategy_desc, fifo_strategy },          /* strategy */
        !           241:        { &vop_print_desc, ufs_print },                 /* print */
        !           242:        { &vop_islocked_desc, ufs_islocked },           /* islocked */
        !           243:        { &vop_pathconf_desc, fifo_pathconf },          /* pathconf */
        !           244:        { &vop_advlock_desc, fifo_advlock },            /* advlock */
        !           245:        { &vop_blkatoff_desc, fifo_blkatoff },          /* blkatoff */
        !           246:        { &vop_valloc_desc, fifo_valloc },              /* valloc */
        !           247:        { &vop_reallocblks_desc, fifo_reallocblks },    /* reallocblks */
        !           248:        { &vop_vfree_desc, ffs_vfree },                 /* vfree */
        !           249:        { &vop_truncate_desc, fifo_truncate },          /* truncate */
        !           250:        { &vop_update_desc, ffs_update },               /* update */
        !           251:        { &vop_bwrite_desc, vn_bwrite },
        !           252:        { &vop_pagein_desc, ufs_pagein },               /* Pagein */
        !           253:        { &vop_pageout_desc, ufs_pageout },             /* Pageout */
        !           254:        { &vop_copyfile_desc, err_copyfile },           /*  Copy File */
        !           255:        { (struct vnodeop_desc*)NULL, (int(*)())NULL }
        !           256: };
        !           257: struct vnodeopv_desc ffs_fifoop_opv_desc =
        !           258:        { &ffs_fifoop_p, ffs_fifoop_entries };
        !           259: #endif /* FIFO */
        !           260: 
        !           261: /*
        !           262:  * Enabling cluster read/write operations.
        !           263:  */
        !           264: int doclusterread = 1;
        !           265: int doclusterwrite = 1;
        !           266: 
        !           267: #include <ufs/ufs/ufs_readwrite.c>
        !           268: 
        !           269: /*
        !           270:  * Synch an open file.
        !           271:  */
        !           272: /* ARGSUSED */
        !           273: int
        !           274: ffs_fsync(ap)
        !           275:        struct vop_fsync_args /* {
        !           276:                struct vnode *a_vp;
        !           277:                struct ucred *a_cred;
        !           278:                int a_waitfor;
        !           279:                struct proc *a_p;
        !           280:        } */ *ap;
        !           281: {
        !           282:        register struct vnode *vp = ap->a_vp;
        !           283:        register struct buf *bp;
        !           284:        struct timeval tv;
        !           285:        struct buf *nbp;
        !           286:        int s;
        !           287: 
        !           288:     /*
        !           289:      * Write out any clusters.
        !           290:      */
        !           291:        if (doclusterwrite) {
        !           292:                struct inode *ip = VTOI(vp);
        !           293:                int devBlockSize = 0;
        !           294: 
        !           295:                VOP_DEVBLOCKSIZE(ip->i_devvp, &devBlockSize);
        !           296:                cluster_close(vp, ip->i_fs->fs_bsize, devBlockSize);
        !           297:        }
        !           298: 
        !           299:        /*
        !           300:         * Flush all dirty buffers associated with a vnode.
        !           301:         */
        !           302: loop:
        !           303:        s = splbio();
        !           304:        for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) {
        !           305:                nbp = bp->b_vnbufs.le_next;
        !           306:                if ((bp->b_flags & B_BUSY))
        !           307:                        continue;
        !           308:                if ((bp->b_flags & B_DELWRI) == 0)
        !           309:                        panic("ffs_fsync: not dirty");
        !           310:                bremfree(bp);
        !           311:                bp->b_flags |= B_BUSY;
        !           312:                splx(s);
        !           313:                /*
        !           314:                 * Wait for I/O associated with indirect blocks to complete,
        !           315:                 * since there is no way to quickly wait for them below.
        !           316:                 */
        !           317:                if (bp->b_vp == vp || ap->a_waitfor == MNT_NOWAIT)
        !           318:                        (void) bawrite(bp);
        !           319:                else
        !           320:                        (void) bwrite(bp);
        !           321:                goto loop;
        !           322:        }
        !           323:        if (ap->a_waitfor == MNT_WAIT) {
        !           324:                while (vp->v_numoutput) {
        !           325:                        vp->v_flag |= VBWAIT;
        !           326:                        tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "ffs_fsync", 0);
        !           327:                }
        !           328: 
        !           329:                /* I have seen this happen for swapfile. So it is safer to
        !           330:                 * check for dirty buffers again.  --Umesh
        !           331:                 */
        !           332:                if (vp->v_dirtyblkhd.lh_first) {
        !           333:                        vprint("ffs_fsync: dirty", vp);
        !           334:                        splx(s);
        !           335:                        goto loop;
        !           336:                }
        !           337:        }
        !           338:        splx(s);
        !           339:        tv = time;
        !           340:        return (VOP_UPDATE(ap->a_vp, &tv, &tv, ap->a_waitfor == MNT_WAIT));
        !           341: }
        !           342: 
        !           343: /*
        !           344:  * Reclaim an inode so that it can be used for other purposes.
        !           345:  */
        !           346: int
        !           347: ffs_reclaim(ap)
        !           348:        struct vop_reclaim_args /* {
        !           349:                struct vnode *a_vp;
        !           350:                struct proc *a_p;
        !           351:        } */ *ap;
        !           352: {
        !           353:        register struct vnode *vp = ap->a_vp;
        !           354:        int error;
        !           355: 
        !           356:        if (error = ufs_reclaim(vp, ap->a_p))
        !           357:                return (error);
        !           358:        FREE_ZONE(vp->v_data, sizeof (struct inode),
        !           359:                        VFSTOUFS(vp->v_mount)->um_devvp->v_tag == VT_MFS ?
        !           360:                                        M_MFSNODE : M_FFSNODE);
        !           361:        vp->v_data = NULL;
        !           362:        return (0);
        !           363: }

unix.superglobalmegacorp.com

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