Annotation of XNU/bsd/vm/dp_backing_file.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: #include <mach_nbc.h>
        !            23: #include <mach/boolean.h>
        !            24: #include <sys/param.h>
        !            25: #include <sys/systm.h>
        !            26: #include <sys/lock.h>
        !            27: #include <sys/proc.h>
        !            28: #include <sys/buf.h>
        !            29: #include <sys/uio.h>
        !            30: #include <sys/vnode.h>
        !            31: #include <ufs/ufs/quota.h>
        !            32: #include <ufs/ufs/inode.h>
        !            33: #include <sys/namei.h>
        !            34: #include <sys/mach_swapon.h>
        !            35: #include <ufs/ffs/fs.h>
        !            36: #include <sys/mount.h>
        !            37: #include <net/if.h>
        !            38: #include <netinet/in.h>
        !            39: #include <nfs/rpcv2.h>
        !            40: #include <nfs/nfsproto.h>
        !            41: #include <nfs/nfs.h>
        !            42: #undef fs_fsok
        !            43: #undef fs_tsize
        !            44: #undef fs_bsize
        !            45: #undef fs_blocks
        !            46: #undef fs_bfree
        !            47: #undef fs_bavail
        !            48: 
        !            49: #include <mach/mach_types.h>
        !            50: #include <vm/vm_map.h>
        !            51: #include <vm/vm_kern.h>
        !            52: #include <kern/parallel.h>
        !            53: #include <kern/zalloc.h>
        !            54: #include <kern/kalloc.h>
        !            55: #include <libkern/libkern.h>
        !            56: #include <sys/malloc.h>
        !            57: #include <sys/resourcevar.h>
        !            58: #include <sys/signalvar.h>
        !            59: 
        !            60: #include <vm/vnode_pager.h>
        !            61: #include <kern/mapfs.h>
        !            62: 
        !            63: default_pager_init_flag = 0;  /* temporary support for delayed instantiation */
        !            64:                              /* of default_pager */
        !            65: 
        !            66: 
        !            67: 
        !            68: 
        !            69: /*  Get rid of this when component interface is in place */
        !            70: struct  host {
        !            71:         void *host_self;
        !            72:         void *host_priv_self;
        !            73:         void *host_security_self;
        !            74: };      
        !            75: typedef struct host     host_data_t;
        !            76:  
        !            77: extern host_data_t      realhost;
        !            78: struct vnode           *default_pager_vnode = 0;
        !            79: 
        !            80: struct bs_map          bs_port_table[MAX_BACKING_STORE] = { 
        !            81:        {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
        !            82:        {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
        !            83:        {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
        !            84:        {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
        !            85:        {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
        !            86:        {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
        !            87:        {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
        !            88:        {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
        !            89:        {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},
        !            90:        {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}};
        !            91: 
        !            92: /* ###################################################### */
        !            93: 
        !            94: 
        !            95: #include <kern/assert.h>
        !            96: 
        !            97: /*
        !            98:  *     Routine:        macx_swapon
        !            99:  *     Function:
        !           100:  *             Syscall interface to add a file to backing store
        !           101:  */
        !           102: int
        !           103: macx_swapon(
        !           104:        char    *filename,
        !           105:        int     flags,
        !           106:        long    size,
        !           107:        long    priority)
        !           108: {
        !           109:        struct vnode            *vp = 0; 
        !           110:        struct nameidata        nd, *ndp;
        !           111:        struct proc             *p =  current_proc();
        !           112:        pager_file_t            pf;
        !           113:        register int            error;
        !           114:        kern_return_t           kr;
        !           115:        mach_port_t             backing_store;
        !           116:        mach_port_t             default_pager_port = MACH_PORT_NULL;
        !           117:        int                     i;
        !           118: 
        !           119:        struct vattr    vattr;
        !           120: 
        !           121: /*
        !           122: printf("macx_swapon: function called\n");
        !           123: */
        !           124:        ndp = &nd;
        !           125: 
        !           126: 
        !           127:        if ((error = suser(p->p_ucred, &p->p_acflag)))
        !           128:                goto swapon_bailout;
        !           129: 
        !           130:        unix_master();
        !           131: 
        !           132:        if(default_pager_init_flag == 0) {
        !           133:                start_def_pager(NULL);
        !           134:                default_pager_init_flag = 1;
        !           135:        }
        !           136: 
        !           137:        /*
        !           138:         * Get a vnode for the paging area.
        !           139:         */
        !           140:        NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
        !           141:            filename, p);
        !           142: 
        !           143:        if ((error = namei(ndp)))
        !           144:                goto swapon_bailout;
        !           145:        vp = ndp->ni_vp;
        !           146: 
        !           147:        if (vp->v_type != VREG) {
        !           148:                error = EINVAL;
        !           149:                VOP_UNLOCK(vp, 0, p);
        !           150:                goto swapon_bailout;
        !           151:        }
        !           152: 
        !           153:        if (!vp->v_vm_info) {
        !           154:                vm_info_init(vp);
        !           155:        }
        !           156: 
        !           157:        if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) {
        !           158:                VOP_UNLOCK(vp, 0, p);
        !           159:                goto swapon_bailout;
        !           160:        }
        !           161: 
        !           162: /*
        !           163: printf("macx_swapon: check size va_size = 0x%x, lowat = 0x%x\n", (int)vattr.va_size, size);
        !           164: */
        !           165:         if (vattr.va_size < (u_quad_t)size) {
        !           166:                 vattr_null(&vattr);
        !           167:                 vattr.va_size = (u_quad_t)size;
        !           168:                 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
        !           169:                 if (error) {
        !           170:                        VOP_UNLOCK(vp, 0, p);
        !           171:                         goto swapon_bailout;
        !           172:                 }
        !           173:         }
        !           174: 
        !           175: 
        !           176:        vp->v_vm_info->vnode_size = vattr.va_size;
        !           177: 
        !           178:        /* add new backing store to list */
        !           179:        i = 0;
        !           180:        while(bs_port_table[i].vp != 0) {
        !           181:                if(i == MAX_BACKING_STORE)
        !           182:                        break;
        !           183:                i++;
        !           184:        }
        !           185:        if(i == MAX_BACKING_STORE) {
        !           186:                error = ENOMEM;
        !           187:                VOP_UNLOCK(vp, 0, p);
        !           188:                goto swapon_bailout;
        !           189:        }
        !           190:        bs_port_table[i].vp = vp;
        !           191:        
        !           192: 
        !           193:        /*
        !           194:         * Look to see if we are already paging to this file.
        !           195:         */
        !           196:        /* make certain the copy send of kernel call will work */
        !           197: /*
        !           198: put this back in when component interfaces are available
        !           199:        kr = host_default_memory_manager(mach_host_self(),
        !           200:                                        &default_pager_port, 0);
        !           201: */
        !           202:        kr = host_default_memory_manager(realhost.host_priv_self, &default_pager_port, 0);
        !           203:        if(kr != KERN_SUCCESS) {
        !           204:           error = EAGAIN;
        !           205:           VOP_UNLOCK(vp, 0, p);
        !           206:           bs_port_table[i].vp = 0;
        !           207:           goto swapon_bailout;
        !           208:        }
        !           209: 
        !           210:        kr = default_pager_backing_store_create(default_pager_port, 
        !           211:                                        -1, /* default priority */
        !           212:                                        0, /* default cluster size */
        !           213:                                        &backing_store);
        !           214:        if(kr != KERN_SUCCESS) {
        !           215:           error = ENOMEM;
        !           216:           VOP_UNLOCK(vp, 0, p);
        !           217:           bs_port_table[i].vp = 0;
        !           218:           goto swapon_bailout;
        !           219:        }
        !           220: 
        !           221: 
        !           222: /* NOTE: we are able to supply PAGE_SIZE here instead of an actual */
        !           223: /* record size or block number because:  a: we do not support offsets */
        !           224: /* from the beginning of the file (allowing for non page size/record */
        !           225: /* modulo offsets.  b: because allow paging will be done modulo page size */
        !           226: 
        !           227: /*
        !           228: printf("macx_swapon: calling default_pager_add_file, bs port 0x%x, vnode 0x%x, record_size 0x%x, size 0x%x\n",backing_store, vp, PAGE_SIZE, (int)vattr.va_size);
        !           229: */
        !           230:        VOP_UNLOCK(vp, 0, p);
        !           231:        kr = default_pager_add_file(backing_store, vp, PAGE_SIZE, 
        !           232:                        ((int)vattr.va_size)/PAGE_SIZE);
        !           233:        if(kr != KERN_SUCCESS) {
        !           234:           bs_port_table[i].vp = 0;
        !           235:           if(kr == KERN_INVALID_ARGUMENT)
        !           236:                error = EINVAL;
        !           237:           else 
        !           238:                error = ENOMEM;
        !           239:           goto swapon_bailout;
        !           240:        }
        !           241:        bs_port_table[i].bs = (void *)backing_store;
        !           242:        /* grab a reference to hold on to the paging file vnode */
        !           243:        VREF(vp);
        !           244:        VREF(vp);
        !           245:        VREF(vp);
        !           246:        VREF(vp);
        !           247:        error = 0;
        !           248: 
        !           249: swapon_bailout:
        !           250:        if (vp) {
        !           251:                vrele(vp);
        !           252:        }
        !           253:        unix_release();
        !           254:        return(error);
        !           255: }
        !           256: 
        !           257: /*
        !           258:  *     Routine:        macx_swapoff
        !           259:  *     Function:
        !           260:  *             Syscall interface to remove a file from backing store
        !           261:  */
        !           262: int
        !           263: macx_swapoff(
        !           264:        char    *filename,
        !           265:        int     flags)
        !           266: {
        !           267:        kern_return_t   kr;
        !           268:        mach_port_t     backing_store;
        !           269: 
        !           270:        struct vnode            *vp = 0; 
        !           271:        struct nameidata        nd, *ndp;
        !           272:        struct proc             *p =  current_proc();
        !           273:        int                     i;
        !           274:        int                     error;
        !           275: 
        !           276: /*
        !           277: printf("macx_swapoff: function called\n");
        !           278: */
        !           279:        backing_store = NULL;
        !           280:        ndp = &nd;
        !           281: 
        !           282: 
        !           283:        if ((error = suser(p->p_ucred, &p->p_acflag)))
        !           284:                goto swapoff_bailout;
        !           285: 
        !           286:        unix_master();
        !           287: 
        !           288:        /*
        !           289:         * Get the vnode for the paging area.
        !           290:         */
        !           291:        NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
        !           292:            filename, p);
        !           293: 
        !           294:        if ((error = namei(ndp)))
        !           295:                goto swapoff_bailout;
        !           296:        vp = ndp->ni_vp;
        !           297: 
        !           298:        if (vp->v_type != VREG) {
        !           299:                error = EINVAL;
        !           300:                VOP_UNLOCK(vp, 0, p);
        !           301:                goto swapoff_bailout;
        !           302:        }
        !           303: 
        !           304:        for(i = 0; i < MAX_BACKING_STORE; i++) {
        !           305:                if(bs_port_table[i].vp == vp) {
        !           306:                        backing_store; 
        !           307:                        break;
        !           308:                }
        !           309:        }
        !           310:        if (i == MAX_BACKING_STORE) {
        !           311:                error = EINVAL;
        !           312:                VOP_UNLOCK(vp, 0, p);
        !           313:                goto swapoff_bailout;
        !           314:        }
        !           315:        backing_store = (mach_port_t)bs_port_table[i].bs;
        !           316:        
        !           317: 
        !           318:        VOP_UNLOCK(vp, 0, p);
        !           319:        kr = default_pager_backing_store_delete(backing_store);
        !           320:        switch (kr) {
        !           321:                case KERN_SUCCESS:
        !           322:                        error = 0;
        !           323:                        bs_port_table[i].vp = 0;
        !           324:                        vrele(vp);
        !           325:                        vrele(vp);
        !           326:                        vrele(vp);
        !           327:                        vrele(vp);
        !           328:                        break;
        !           329:                case KERN_FAILURE:
        !           330:                        error = EAGAIN;
        !           331:                        break;
        !           332:                default:
        !           333:                        error = EAGAIN;
        !           334:                        break;
        !           335:        }
        !           336: swapoff_bailout:
        !           337:        if (vp) {
        !           338:                vrele(vp);
        !           339:        }
        !           340:        unix_release();
        !           341:        return(error);
        !           342: }
        !           343: 
        !           344: /*
        !           345:  *     Routine:        mach_swapon
        !           346:  *     Function:
        !           347:  *             Syscall interface to add a file to backing store
        !           348:  */
        !           349: int
        !           350: mach_swapon(
        !           351:        char    *filename,
        !           352:        int     flags,
        !           353:        long    lowat,
        !           354:        long    hiwat)
        !           355: {
        !           356:        struct vnode            *vp = 0; 
        !           357:        struct nameidata        nd, *ndp;
        !           358:        struct proc             *p =  current_proc();
        !           359:        pager_file_t            pf;
        !           360:        register int            error;
        !           361:        kern_return_t           kr;
        !           362:        mach_port_t             backing_store;
        !           363:        mach_port_t             default_pager_port = MACH_PORT_NULL;
        !           364: 
        !           365:        struct vattr    vattr;
        !           366: 
        !           367:        ndp = &nd;
        !           368: 
        !           369:        if ((error = suser(p->p_ucred, &p->p_acflag)))
        !           370:                goto bailout;
        !           371: 
        !           372:        unix_master();
        !           373: 
        !           374:        if(default_pager_init_flag == 0) {
        !           375:                start_def_pager(NULL);
        !           376:                default_pager_init_flag = 1;
        !           377:        }
        !           378: 
        !           379:        /*
        !           380:         * Get a vnode for the paging area.
        !           381:         */
        !           382:        NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
        !           383:            filename, p);
        !           384: 
        !           385:        if ((error = namei(ndp)))
        !           386:                goto bailout;
        !           387:        vp = ndp->ni_vp;
        !           388: 
        !           389:        if (vp->v_type != VREG) {
        !           390:                error = EINVAL;
        !           391:                goto bailout;
        !           392:        }
        !           393: 
        !           394:        if (!vp->v_vm_info) {
        !           395:                vm_info_init(vp);
        !           396:        }
        !           397: 
        !           398:        if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) {
        !           399:                goto bailout;
        !           400:        }
        !           401: 
        !           402: /*
        !           403: printf("mach_swapon: check lowat va_size = 0x%x, lowat = 0x%x\n", (int)vattr.va_size, lowat);
        !           404: */
        !           405:         if (vattr.va_size < (u_quad_t)lowat) {
        !           406:                 vattr_null(&vattr);
        !           407:                 vattr.va_size = (u_quad_t)lowat;
        !           408:                 error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
        !           409:                 if (error) {
        !           410:                         goto bailout;
        !           411:                 }
        !           412:         }
        !           413: 
        !           414: 
        !           415:        vp->v_vm_info->vnode_size = vattr.va_size;
        !           416: 
        !           417:        /*
        !           418:         * Look to see if we are already paging to this file.
        !           419:         */
        !           420:        /* make certain the copy send of kernel call will work */
        !           421: /*
        !           422: put this back in when component interfaces are available
        !           423:        kr = host_default_memory_manager(mach_host_self(),
        !           424:                                        &default_pager_port, 0);
        !           425: */
        !           426:        kr = host_default_memory_manager(realhost.host_priv_self, &default_pager_port, 0);
        !           427:        if(kr != KERN_SUCCESS) {
        !           428:           error = kr;
        !           429:           goto bailout;
        !           430:        }
        !           431: 
        !           432:        kr = default_pager_backing_store_create(default_pager_port, 
        !           433:                                        -1, /* default priority */
        !           434:                                        0, /* default cluster size */
        !           435:                                        &backing_store);
        !           436:        if(kr != KERN_SUCCESS) {
        !           437:           error = kr;
        !           438:           goto bailout;
        !           439:        }
        !           440: 
        !           441: 
        !           442: /* NOTE: we are able to supply PAGE_SIZE here instead of an actual */
        !           443: /* record size or block number because:  a: we do not support offsets */
        !           444: /* from the beginning of the file (allowing for non page size/record */
        !           445: /* modulo offsets.  b: because allow paging will be done modulo page size */
        !           446: 
        !           447: /*
        !           448: printf("mach_swapon: calling default_pager_add_file, bs port 0x%x, vnode 0x%x, record_size 0x%x, size 0x%x\n",backing_store, vp, PAGE_SIZE, (int)vattr.va_size);
        !           449: */
        !           450:        kr = default_pager_add_file(backing_store, vp, PAGE_SIZE, 
        !           451:                        ((int)vattr.va_size)/PAGE_SIZE);
        !           452:        if(kr != KERN_SUCCESS) {
        !           453:           error = kr;
        !           454:           goto bailout;
        !           455:        }
        !           456:        /* grab a reference to hold on to the paging file vnode */
        !           457:        VREF(vp);
        !           458:        default_pager_vnode = vp;
        !           459: 
        !           460:        error = 0;
        !           461: 
        !           462: bailout:
        !           463:        if (vp) {
        !           464:                VOP_UNLOCK(vp, 0, p);
        !           465:                vrele(vp);
        !           466:        }
        !           467:        unix_release();
        !           468:        return(error);
        !           469: }

unix.superglobalmegacorp.com

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