|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.