Annotation of XNU/bsd/vm/dp_backing_file.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: #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.