⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aux.c

📁 Solaris操作系统下的过滤驱动程序, C源码程序.
💻 C
字号:
/* * Copyright (c) 1997-2003 Erez Zadok * Copyright (c) 2001-2003 Stony Brook University * Copyright (c) 1997-2000 Columbia University * * For specific licensing information, see the COPYING file distributed with * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. * * This Copyright notice must be kept intact and distributed with all * fistgen sources INCLUDING sources generated by fistgen. *//* *  $Id: aux.c,v 1.12 2002/12/27 20:19:04 ezk Exp $ */#ifdef HAVE_CONFIG_H# include <config.h>#endif /* HAVE_CONFIG_H */#ifdef FISTGEN# include "fist_wrapfs.h"#endif /* FISTGEN */#include "fist.h"#include "wrapfs.h"#ifdef FIST_USE_AUX_SRC/* * Read "len" bytes from "filename" into "buf". * "buf" is in kernel space. */intwrapfs_read_file(const char *filename, void *buf, int len){    file_t *filp;    mm_segment_t oldfs;    int bytes;    				/* Chroot? Maybe NULL isn't right here */    filp = filp_open(filename, O_RDONLY, 0);    if (!filp || IS_ERR(filp)) {	printk("wrapfs_read_file err %d\n", (int) PTR_ERR(filp));	return -1;  /* or do something else */    }    if (!filp->f_op->read)	return -2;  /* file(system) doesn't allow reads */    /* now read len bytes from offset 0 */    filp->f_pos = 0;		/* start offset */    oldfs = get_fs();    set_fs(KERNEL_DS);    bytes = filp->f_op->read(filp, buf, len, &filp->f_pos);    set_fs(oldfs);    /* close the file */    fput(filp);    return bytes;}/* * Write "len" bytes from "buf" to "filename" * "buf" is in kernel space. */intwrapfs_write_file(const char *filename, void *buf, int len){    file_t *filp;    mm_segment_t oldfs;    int bytes;				/* Chroot? Maybe NULL isn't right here */    filp = filp_open(filename, O_RDWR|O_CREAT, 0640);    if (!filp || IS_ERR(filp)) {	printk("wrapfs_write_file err %d\n", (int) PTR_ERR(filp));	return -1;  /* or do something else */    }    if (!filp->f_op->write)	return -2;  /* file(system) doesn't allow writes */    /* now write len bytes from offset 0 */    filp->f_pos = 0;		/* start offset */    oldfs = get_fs();    set_fs(KERNEL_DS);    bytes = filp->f_op->write(filp, buf, len, &filp->f_pos);    set_fs(oldfs);    /* close the file */    fput(filp);    return bytes;}/* * perform a special lookup with special permissions */dentry_t *fist_lookup(dentry_t *dir, const char *name, vnode_t **out, uid_t uid, gid_t gid){    uid_t saved_uid;    gid_t saved_gid;    dentry_t *new_dentry;    saved_uid = dir->d_inode->i_uid;    saved_gid = dir->d_inode->i_gid;    dir->d_inode->i_uid = uid;    dir->d_inode->i_gid = gid;    new_dentry = lookup_one_len(name, dir, strlen(name));    dir->d_inode->i_uid = saved_uid;    dir->d_inode->i_gid = saved_gid;    return new_dentry;}#endif /* FIST_USE_AUX_SRC */#ifdef FIST_FILTER_SCA/* lookup an index file, given a hidden dentry */dentry_t *wrapfs_idx_lookup(dentry_t *hidden_dentry){    unsigned int namelen;    dentry_t *idx_dentry = NULL, *dir_dentry;    char *name;    int err = 0;    print_entry_location();    namelen = hidden_dentry->d_name.len;    name = kmalloc(namelen + INDEX_EXTENSION_LEN, GFP_KERNEL);    if (!name) {	err = -ENOMEM;	goto out;    }    memcpy(name, hidden_dentry->d_name.name, namelen);    memcpy(name + namelen, INDEX_EXTENSION, INDEX_EXTENSION_LEN);    dir_dentry = dget(hidden_dentry->d_parent);    idx_dentry = lookup_one_len(name, dir_dentry, namelen + INDEX_EXTENSION_LEN - 1);    if (IS_ERR(idx_dentry)) {	printk("ERR from lookup_dentry on idx_dentry!\n");	err = PTR_ERR(idx_dentry);	goto out;    }    /* note that returned idx_dentry may be a negative dentry */ out:    if (err)	idx_dentry = ERR_PTR(err);    print_exit_status(err);    return idx_dentry;}/* create a new index inode */intwrapfs_idx_create(inode_t *hidden_dir, dentry_t *dentry, int mode){    int err;    print_entry_location();    /* we don't have to lock hidden_dir. already locked in wrapfs_create */    err = vfs_create(hidden_dir, dtopd(dentry)->idx_dentry, mode);    print_exit_status(err);    return err;}/* open an index file (that should exist) given a regular file dentry */intwrapfs_idx_open(dentry_t *dentry, unsigned int flags){    int err = 0;    file_t *idx_file;    dentry_t *idx_dentry;    print_entry_location();    /* don't reopen an existing idx file */    if (itopd(dentry->d_inode)->idx_file)	goto out;    idx_dentry = dtopd(dentry)->idx_dentry;    dget(idx_dentry);    /*     * dentry_open will decrement mnt refcnt if err.     * otherwise fput() will do an mntput() for us upon file close.     */    mntget(stopd(dentry->d_sb)->hidden_mnt);    idx_file = dentry_open(idx_dentry, stopd(dentry->d_sb)->hidden_mnt, flags);    if (IS_ERR(idx_file)) {	printk("Error opening (flags %d) index file %s\n", flags, idx_dentry->d_name.name);	err = PTR_ERR(idx_file);	goto out;    }    itopd(dentry->d_inode)->idx_file = idx_file;    /* all is ok */out:    print_exit_status(err);    return err;}/* XXX this is inefficient, for stat() it really doesn't need the entire index table *//* This function return 0 on success, negative on error */intwrapfs_idx_read(inode_t *inode){    mm_segment_t oldfs;    int len, err = 0, i;    struct scafs_header *hdr = NULL;    file_t *idx_file;    print_entry_location();    idx_file = itopd(inode)->idx_file;    ASSERT(idx_file != NULL);    if (!idx_file->f_op->read) {	/* This is highly unlikely, but... */	err = -ENOSYS;	goto out;    }    len = idx_file->f_dentry->d_inode->i_size;    /* Special case for empty file */    if (len == 0 && itohi(inode)->i_size == 0) {	inode->i_size = inode->i_blocks = 0;	goto out;    }    /* small (corrupted) index? */    if (len < (3 * sizeof(off_t))) {	err = -EIO;	goto out;    }    oldfs = get_fs();    set_fs(KERNEL_DS);    hdr = &(itopd(inode)->hdr);    /* Read in the number of pages and the real size */    err = idx_file->f_op->read(idx_file, (void *) &hdr->num_chunks,			       sizeof(off_t) << 1, &idx_file->f_pos);    if (err < 0) {	printk("Error in read\n");	goto out_setfs;    }    /* XXX check to see that we got all 2 * sizeof(off_t) bytes */    /* separate flags from num_chunks */    hdr->flags = hdr->num_chunks & SCA_FLAG_MASK;    hdr->num_chunks &= ~SCA_FLAG_MASK;    hdr->num_pageslots = (hdr->num_chunks + OFFSET_MASK) >> OFFSET_SHIFT;    /* allocate page pointers array */    hdr->offsets = (off_t **)kmalloc(sizeof(off_t *) * hdr->num_pageslots, GFP_KERNEL);    if (hdr->offsets == NULL) {	err = -ENOMEM;	goto out;    }    hdr->num_alloc = hdr->num_pageslots << OFFSET_SHIFT;    for (i = 0; i < hdr->num_pageslots; i++) {	hdr->offsets[i] = (off_t *)__get_free_page(GFP_KERNEL);	if (hdr->offsets[i] == NULL) {	    err = -ENOMEM;	    goto out;	}	/* Read in the offsets into an array */	err = idx_file->f_op->read(idx_file, (void *) hdr->offsets[i],				   PAGE_CACHE_SIZE, &idx_file->f_pos);	if (err < 0) {	    printk("Error in read\n");	    goto out_setfs;	}	/* XXX check to see that we got all needed bytes */    }    /* Sanity checking: Make sure underlying file size matches index table */    /* XXX These checks need to be fixed for fast_append! XXX */    if (hdr->num_chunks > 0) {	if(SCA_OFFSET(hdr, hdr->num_chunks - 1) != itohi(inode)->i_size) {	    printk("Final offset does not equal file size\n");	    err = -EIO;	    goto out_setfs;	}    } else {	if (itohi(inode)->i_size > 0) {	    printk("No offsets, but index file is not empty\n");	    err = -EIO;	    goto out_setfs;	}    }    /* All is well */    err = 0;    fist_print_scafs_header("idx_read", hdr);    copy_inode_size(inode, itohi(inode)); out_setfs:    set_fs(oldfs); out:    print_exit_status(err);    return(err);}/* This function return 0 on success, negative on error */intwrapfs_idx_write(inode_t *inode){    int err = 0;    mm_segment_t oldfs;    int i, bytes;    unsigned int chunks_left;    struct scafs_header *hdr = &(itopd(inode)->hdr);    file_t *idx_file = itopd(inode)->idx_file;    struct iattr attr;    print_entry_location();    ASSERT(hdr != NULL);    /* don't write header if not modified */    if ((hdr->flags & SCA_FLAG_MODIFIED) == 0) {	fist_dprint(8, "idx_write: not writing unmodified header\n");	goto out;    }    if (idx_file == NULL) {	printk("idx_file is NULL, cannot write\n");	goto out;    }    /* truncate index file to length 0 */    attr.ia_size = 0;    attr.ia_valid = ATTR_SIZE;    err = notify_change(idx_file->f_dentry, &attr);    if (err < 0)	goto out;    if (hdr->num_chunks == 0)	/* don't write anything */	goto out;    /* combine num_chunks and flags */    hdr->num_chunks |= hdr->flags & SCA_FLAG_MASK;    oldfs = get_fs();    set_fs(KERNEL_DS);    idx_file->f_pos = 0;    err = idx_file->f_op->write(idx_file,				(void *) hdr,				sizeof(off_t) << 1,				&idx_file->f_pos);    /* remove flags from num_chunks */    hdr->num_chunks &= ~SCA_FLAG_MASK;    if (err < 0) { // XXX: check that err==num_bytes2write	printk("error %d in write idx file hdr\n", err);	goto out_setfs;    }    chunks_left = hdr->num_chunks;    for (i = 0; 1; i++) {	bytes = MIN(chunks_left, INDEX_ENTRIES_PER_PAGE) * sizeof(off_t);	fist_dprint(8, "%s: %d bytes for page %d\n", __FUNCTION__, bytes, i);	err = idx_file->f_op->write(idx_file,				    (void *) hdr->offsets[i],				    bytes,				    &idx_file->f_pos);	if (err < 0) { // XXX: check that err==bytes	    printk("error %d in write idx file entries\n", err);	    goto out_setfs;	}	if (chunks_left <= INDEX_ENTRIES_PER_PAGE)	    break;	chunks_left -= INDEX_ENTRIES_PER_PAGE;    }    /* reset modified counter */    hdr->flags &= ~SCA_FLAG_MODIFIED; out_setfs:    set_fs(oldfs); out:    print_exit_status(err);    return err;}/* * Sets the value for an "entry" into an existing SCA header structure, * potentially allocating space for it and any preceding entries * * chunk_idx starts from 0. encoded_chunk_offset is what * this chunk will encode to. * * Note that holes are supported: they are defined in the index table * as a page that encodes to 0 bytes (i.e. the entry for that page will * be equal to the previous one) * * Returns 0 on success, or -errno on failure. */intwrapfs_idx_set_entry(struct scafs_header *hdr,		     int chunk_idx,		     off_t encoded_chunk_offset){    int err = 0, i;    off_t offset;    unsigned long pageslots;    print_entry_location();	/* XXX: remove this after debugging */    fist_dprint(8, "%s: chunk_idx=%d encoded_chunk_offset=%d\n",		__FUNCTION__, chunk_idx, encoded_chunk_offset);    /* sanity checks */    ASSERT(hdr != NULL);    ASSERT(chunk_idx >= 0);    ASSERT(hdr->num_chunks <= hdr->num_alloc);    /* check if we need to (re)allocate new space */    if (chunk_idx >= hdr->num_alloc) {	pageslots = (chunk_idx + 1 + OFFSET_MASK) >> OFFSET_SHIFT;	fist_dprint(8, "Allocating space for %d pages\n", pageslots);	hdr->offsets = (off_t **) wrapfs_krealloc(hdr->offsets,						  sizeof(off_t *) * hdr->num_pageslots,						  sizeof(off_t *) * pageslots);	if (hdr->offsets == NULL) {	    err = -ENOMEM;	    goto out;	}	for (i = hdr->num_pageslots; i < pageslots; i++) {	    hdr->offsets[i] = (off_t *)__get_free_page(GFP_KERNEL);	    if (hdr->offsets[i] == NULL) {		err = -ENOMEM;		goto out;	    }	}	hdr->num_pageslots = pageslots;	hdr->num_alloc = pageslots << OFFSET_SHIFT;    }    /* support holes */    if (hdr->num_chunks > 0)	offset = SCA_OFFSET(hdr, hdr->num_chunks - 1);    else	offset = 0;    for (i = hdr->num_chunks; i < chunk_idx; i++)	SCA_OFFSET(hdr, i) = offset;    if (hdr->num_chunks > 0 &&	chunk_idx > 0 &&	encoded_chunk_offset < SCA_OFFSET(hdr, chunk_idx - 1)) {	printk("idx_set_entry: lower offset %ld < %ld for chunk_idx %d\n",	       encoded_chunk_offset, SCA_OFFSET(hdr, chunk_idx-1), chunk_idx);    }    /* now insert new entry */    SCA_OFFSET(hdr, chunk_idx) = encoded_chunk_offset;    hdr->num_chunks = MAX(hdr->num_chunks, chunk_idx + 1);    hdr->flags |= SCA_FLAG_MODIFIED;out:    fist_print_scafs_header("SAE", hdr);    print_exit_status(err);	/* XXX: remove this after debugging */    return err;}/* update index table entries by delta, starting at entry */voidwrapfs_idx_update(struct scafs_header *hdr, unsigned long entry, int delta){    unsigned long l;    if (delta == 0)	return;    for (l = entry; l < hdr->num_chunks; l++)	SCA_OFFSET(hdr, l) += delta;    hdr->flags |= SCA_FLAG_MODIFIED;}/* * Given a page_index of our layer, find out the range of pages of the lower * layer that we need to read to satisfy the encoding request for our page. * The range of pages is from hidden_page_index and goes for the number of * pages being returned from this function. */intwrapfs_count_hidden_pages(unsigned long page_index,			  inode_t *inode,			  int *hidden_page_index,			  void **opaque){    struct scafs_header *hdr;    int start,end,cnt=0;    unsigned int start_page, end_page;    print_entry_location();    hdr = &(itopd(inode)->hdr);    if (page_index >= hdr->num_chunks) {  /* XXX: fix page/chunk confusion */	//printk("count_hidden_pages: request for page %ld, file only has %ld chunks\n",	//       page_index, hdr->num_chunks);	goto out;    }    start = HIDDEN_PAGE_STARTING_OFFSET(page_index, inode);    end = HIDDEN_PAGE_STARTING_OFFSET(page_index + 1, inode);    if (start == end)	goto out;		/* Hole, return 0 */    *hidden_page_index = start_page = start >> PAGE_CACHE_SHIFT;    end_page = end >> PAGE_CACHE_SHIFT;    *((int *)opaque) = start & ~PAGE_CACHE_MASK;    cnt = end_page - start_page;    if ((end & ~PAGE_CACHE_MASK) != 0)	cnt++; out:    print_exit_status(cnt);    return cnt;}/* * A kernel based realloc(3). * * Oldsize must be original allocated size of oldptr. * Returns new pointer, or the old pointer if any error occured. */void *wrapfs_krealloc(void *oldptr, size_t oldsize, size_t newsize){    void *newptr = NULL;    /* check if given sizes were valid */    if (newsize <= 0) {	printk("error: krealloc was called with newsize %d\n", newsize);	goto out;    }    if (oldsize < 0) {	printk("error: krealloc was called with oldsize %d\n", oldsize);	goto out;    }    if (newsize <= oldsize)	printk("warning: wrapfs_krealloc newsize %d <= oldsize %d\n", newsize, oldsize);    /* allocate and copy bytes */    newptr = kmalloc(newsize, GFP_KERNEL);    if (newptr == NULL) {	printk("krealloc: no more memory\n");	goto out;    }    if (oldsize > 0) {	if (newsize > oldsize) {	/* extending size */	    memcpy(newptr, oldptr, oldsize);	    memset(newptr + oldsize, 0, newsize - oldsize);	/* be safe */	} else {	    memcpy(newptr, oldptr, newsize);	}	/* free old allocation */	/* XXX: be safe and zero out oldptr's bytes first? */	kfree(oldptr);    } out:    return newptr;}#endif /* FIST_FILTER_SCA *//* * Local variables: * c-basic-offset: 4 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -