Annotation of XNU/bsd/ufs/ffs/ffs_vnops.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: /* 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.