dc_vnops.c revision 53eed1cb389966d2dd60e74de0933f3b3277dbbd
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 2N/A/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 2N/A/* All Rights Reserved */ 2N/A * University Copyright- Copyright (c) 1982, 1986, 1988 2N/A * The Regents of the University of California 2N/A * All Rights Reserved 2N/A * University Acknowledgment- Portions of this document are derived from 2N/A * software developed by the University of California, Berkeley, and its 2N/A * dcfs - A filesystem for automatic decompressing of fiocompressed files 2N/A * This filesystem is a layered filesystem that sits on top of a normal 2N/A * persistent filesystem and provides automatic decompression of files 2N/A * that have been previously compressed and stored on the host file system. 2N/A * This is a pseudo filesystem in that it does not persist data, rather it 2N/A * intercepts file lookup requests on the host filesystem and provides 2N/A * transparent decompression of those files. Currently the only supported 2N/A * host filesystem is ufs. 2N/A * and marked by fiocompress as a compressed file via a flag in the on-disk 2N/A * inode (set via a ufs ioctl() - see `ufs_vnops.c`ufs_ioctl()`_FIO_COMPRESSED 2N/A * ufs_lookup checks for this flag and if set, passes control to decompvp 2N/A * a function defined in this (dcfs) filesystem. decomvp uncompresses the file 2N/A * and returns a dcfs vnode to the VFS layer. 2N/A * dcfs is layered on top of ufs and passes requests involving persistence 2N/A * to the underlying ufs filesystem. The compressed files currently cannot be 2N/A * Define data structures within this file. 2N/A * This is the loadable module wrapper. 2N/A * Module linkage information for the kernel. 2N/A * Loop through file with segmap, decompression will occur 2N/A * read to end of block or file 2N/A return (0);
/* at EOF */ /* substitute uncompressed size */ * Somebody accessed the dcnode before we got a chance to * remove it. They will remove it when they do a vn_rele. * If file is being mapped, disallow frlock. * Get destination pages and make them addressable * read compressed data from subordinate vnode * pvn_read_kluster() doesn't quite do what we want, since it * thinks sub block reads are ok. Here we always decompress return (0);
/* all pages in cache */ * Undo any locks so getblock_miss has an open field /* does not support write */ panic(
"write attempt on compressed file");
* We don't support asynchronous operation at the moment, so * just pretend we did it. If the pages are ever actually * needed, they'll get brought in then. * Calc block start and end offsets * This function should never be called. We need to have it to pass * it as an argument to other functions. /* should never happen */ * The only flags we support are B_INVAL, B_FREE and B_DONTNEED. * 1) the MC_SYNC command of memcntl(2) to support the MS_INVALIDATE flag. * 2) the MC_ADVISE command of memcntl(2) with the MADV_DONTNEED advice * which translates to an MC_SYNC with the MS_INVALIDATE flag. * The B_FREE (as well as the B_DONTNEED) flag is set when the * MADV_SEQUENTIAL advice has been used. VOP_PUTPAGE is invoked * from SEGVN to release pages behind a pagefault. panic(
"dcfs_putpage: bad v_count");
if (
len == 0)
/* from 'off' to EOF */ * We insist on getting the page only if we are * about to invalidate, free or write it and * the B_ASYNC flag is not set. * Normally pvn_getdirty() should return 0, which * impies that it has done the job for us. * The shouldn't-happen scenario is when it returns 1. * This means that the page has been modified and * Since we can't write to a dcfs compressed file, * we fake a failed I/O and force pvn_write_done() * If file is being locked, disallow mapping. * User specified address - blow away any previous mappings * If the free list is above DCLRUSIZE * If no cached pages, no need to put it on lru * Add to lru, if it's over the limit, free from head * Return shadow vnode with the given vp as its subordinate * See if we have an existing shadow * If none, we have to manufacture one * Make sure it's a valid compressed file /* get underlying file size */ * add extra blkmap entry to make dc_getblock()'s * Allocate kmem cache if none there already * Recheck table in case someone else created shadow * while we were blocked above. * These routines maintain a table of dcnodes hashed by their * subordinate vnode so that they can be found if they already * exist in the vnode cache * Put a dcnode in the table. * Remove a dcnode from the hash table. * Find a shadow vnode in the dctable hash list. * Add to dclru as double-link chain