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

📄 mmap.c

📁 Solaris操作系统下的过滤驱动程序, C源码程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
wrapfs_shift_inward(file_t *file,	/* hidden file we're shifting */		    off_t dst_offset,	/* where to shift to (abs offset) */		    off_t src_offset,	/* where to shift from (abs offset) */		    off_t total_bytes_to_shift){    int dst_page_index, src_page_index;    unsigned int dst_page_offset, src_page_offset;    page_t *dst_page, *src_page;    off_t bytes_to_copy;    int dst_page_bytes_left, src_page_bytes_left;    char *dst_kaddr, *src_kaddr;    int err = 0;    struct address_space_operations *a_ops;    print_entry_location();    if (total_bytes_to_shift <= 0) {	printk("wrapfs_shift_inward asked to shift %ld bytes\n", total_bytes_to_shift);	goto out;    }    /* compute page indices */    dst_page_index = dst_offset >> PAGE_CACHE_SHIFT;    src_page_index = src_offset >> PAGE_CACHE_SHIFT;    /* compute offsets within pages */    dst_page_offset = dst_offset & ~PAGE_CACHE_MASK;    src_page_offset = src_offset & ~PAGE_CACHE_MASK;    /* compute number of bytes left in pages */    dst_page_bytes_left = PAGE_CACHE_SIZE - dst_page_offset;    src_page_bytes_left = PAGE_CACHE_SIZE - src_page_offset;    /* get pages */    dst_page = wrapfs_get1page(file, dst_page_index);    if (IS_ERR(dst_page)) {	err = PTR_ERR(dst_page);	goto out;    }    src_page = wrapfs_get1page(file, src_page_index);    if (IS_ERR(src_page)) {	page_cache_release(dst_page);	err = PTR_ERR(src_page);	goto out;    }    src_kaddr = (char *) kmap(src_page);    a_ops = file->f_dentry->d_inode->i_mapping->a_ops;    while (1) {	src_page_bytes_left = MIN(src_page_bytes_left, total_bytes_to_shift);	bytes_to_copy = MIN(src_page_bytes_left, dst_page_bytes_left);	/* lock destination page */	lock_page(dst_page);	err = a_ops->prepare_write(file,				   dst_page,				   dst_page_offset,				   dst_page_offset+bytes_to_copy);	if (err < 0) {		/* XXX: what about partial writes */	    UnlockPage(dst_page);	    goto out_release;	}	dst_kaddr = (char *) page_address(dst_page);	/* actually copy some bytes */	memmove(dst_kaddr + dst_page_offset,		src_kaddr + src_page_offset,		bytes_to_copy);	err = a_ops->commit_write(file,				  dst_page,				  dst_page_offset,				  dst_page_offset+bytes_to_copy);	UnlockPage(dst_page);	if (err < 0)	    goto out_release;	total_bytes_to_shift -= bytes_to_copy;	if (total_bytes_to_shift == 0)	    break;	/* adjust destinations as needed */	dst_page_bytes_left -= bytes_to_copy;	if (dst_page_bytes_left == 0) { /* get new page */	    page_cache_release(dst_page);	    dst_page_index++;	    dst_page_offset = 0;	    dst_page_bytes_left = PAGE_CACHE_SIZE;	    dst_page = wrapfs_get1page(file, dst_page_index);	    if (IS_ERR(dst_page)) {		page_cache_release(src_page);		err = PTR_ERR(dst_page);		goto out;	    }	} else {	    dst_page_offset += bytes_to_copy;	}	/* adjust sources as needed */	src_page_bytes_left -= bytes_to_copy;	if (src_page_bytes_left == 0) { /* get new page */	    kunmap(src_page);	    page_cache_release(src_page);	    src_page_index++;	    src_page_offset = 0;	    src_page_bytes_left = PAGE_CACHE_SIZE;	    src_page = wrapfs_get1page(file, src_page_index);	    if (IS_ERR(src_page)) {		page_cache_release(dst_page);		err = PTR_ERR(src_page);		goto out;	    }	    src_kaddr = (char *) kmap(src_page);	} else {	    src_page_offset += bytes_to_copy;	}	if (current->need_resched)	    schedule();    } /* end of "while (1)" */ out_release:    page_cache_release(dst_page);    page_cache_release(src_page); out:    print_exit_status(err);    return err;}/* * shift data inwards; return 0 if ok or -errno */intwrapfs_shift_outward(file_t *file,	/* hidden file we're shifting */		     off_t dst_offset,	/* where to shift to (abs offset) */		     off_t src_offset,	/* where to shift from (abs offset) */		     off_t total_bytes_to_shift){    int dst_page_index, src_page_index;    unsigned int dst_page_offset, src_page_offset;    page_t *dst_page, *src_page;    off_t bytes_to_copy;    int dst_page_bytes_left, src_page_bytes_left;    char *dst_kaddr, *src_kaddr;    int err = 0;    struct address_space_operations *a_ops;    print_entry_location();    fist_dprint(8, "%s args: dst_off=%d, src_off=%d, bytes=%d\n",		__FUNCTION__, dst_offset, src_offset, total_bytes_to_shift);    if (total_bytes_to_shift <= 0) {	printk("wrapfs_shift_outward asked to shift %ld bytes\n", total_bytes_to_shift);	goto out;    }    /* compute page indices */    dst_page_index = (dst_offset + total_bytes_to_shift) >> PAGE_CACHE_SHIFT;    src_page_index = (src_offset + total_bytes_to_shift) >> PAGE_CACHE_SHIFT;    /* compute offsets within pages */    dst_page_offset = (dst_offset + total_bytes_to_shift) & ~PAGE_CACHE_MASK;    src_page_offset = (src_offset + total_bytes_to_shift) & ~PAGE_CACHE_MASK;    /* compute number of bytes left in pages */    dst_page_bytes_left = dst_page_offset;    src_page_bytes_left = src_page_offset;    fist_dprint(8, "%s dst: index=%d, offset=%d, bytesleft=%d\n",		__FUNCTION__, dst_page_index,		dst_page_offset, dst_page_bytes_left);    fist_dprint(8, "%s src: index=%d, offset=%d, bytesleft=%d\n",		__FUNCTION__, src_page_index,		src_page_offset, src_page_bytes_left);    /* get pages */    dst_page = wrapfs_get1page(file, dst_page_index);    if (IS_ERR(dst_page)) {	err = PTR_ERR(dst_page);	goto out;    }    src_page = wrapfs_get1page(file, src_page_index);    if (IS_ERR(src_page)) {	page_cache_release(dst_page);	err = PTR_ERR(src_page);	goto out;    }    src_kaddr = (char *) kmap(src_page);    a_ops = file->f_dentry->d_inode->i_mapping->a_ops;    while (1) {	src_page_bytes_left = MIN(src_page_bytes_left, total_bytes_to_shift);	bytes_to_copy = MIN(src_page_bytes_left, dst_page_bytes_left);	dst_page_offset -= bytes_to_copy;	src_page_offset -= bytes_to_copy;	/* lock destination page */	lock_page(dst_page);	err = a_ops->prepare_write(file,				   dst_page,				   dst_page_offset,				   dst_page_offset+bytes_to_copy);	if (err < 0) {		/* XXX: what about partial writes */	    UnlockPage(dst_page);	    goto out_release;	}	dst_kaddr = (char *) page_address(dst_page);	/* actually copy some bytes */	memmove(dst_kaddr + dst_page_offset,		src_kaddr + src_page_offset,		bytes_to_copy);	err = a_ops->commit_write(file,				  dst_page,				  dst_page_offset,				  dst_page_offset+bytes_to_copy);	UnlockPage(dst_page);	if (err < 0)	    goto out_release;	total_bytes_to_shift -= bytes_to_copy;	if (total_bytes_to_shift == 0)	    break;	/* adjust destinations as needed */	dst_page_bytes_left -= bytes_to_copy;	if (dst_page_bytes_left == 0) { /* get new page */	    page_cache_release(dst_page);	    dst_page_index--;	    dst_page_offset = PAGE_CACHE_SIZE;	    dst_page_bytes_left = PAGE_CACHE_SIZE;	    fist_dprint(8, "%s dst: index=%d, offset=%d, bytesleft=%d\n",			__FUNCTION__, dst_page_index,			dst_page_offset, dst_page_bytes_left);	    dst_page = wrapfs_get1page(file, dst_page_index);	    if (IS_ERR(dst_page)) {		page_cache_release(src_page);		err = PTR_ERR(dst_page);		goto out;	    }	}	/* adjust sources as needed */	src_page_bytes_left -= bytes_to_copy;	if (src_page_bytes_left == 0) { /* get new page */	    page_cache_release(src_page);	    src_page_index--;	    src_page_offset = PAGE_CACHE_SIZE;	    src_page_bytes_left = PAGE_CACHE_SIZE;	    fist_dprint(8, "%s src: index=%d, offset=%d, bytesleft=%d\n",			__FUNCTION__, src_page_index,			src_page_offset, src_page_bytes_left);	    src_page = wrapfs_get1page(file, src_page_index);	    if (IS_ERR(src_page)) {		page_cache_release(dst_page);		err = PTR_ERR(src_page);		goto out;	    }	    src_kaddr = (char *) kmap(src_page);	}	if (current->need_resched)	    schedule();    } /* end of "while (1)" */ out_release:    page_cache_release(dst_page);    page_cache_release(src_page); out:    print_exit_status(err);    return err;}/* * copy data bytes; return 0 if ok or -errno */intwrapfs_copy_encoded_data(file_t *file,	/* hidden file */			 off_t dst_offset, /* where to copy to (abs offset) */			 encoded_pages_t *encoded_pages,			 off_t total_bytes_to_copy){    int dst_page_index;    unsigned int dst_page_offset, src_page_offset;    page_t *dst_page;    off_t bytes_to_copy;    int dst_page_bytes_left, src_page_bytes_left;    char *dst_kaddr, *src_kaddr;    int err = 0;    struct address_space_operations *a_ops;    print_entry_location();    // XXX: check errors    //    printk("EZK0: total_bytes_to_copy 0x%x\n", (int) total_bytes_to_copy);    /* compute page indices */    dst_page_index = dst_offset >> PAGE_CACHE_SHIFT;    /* compute offsets within pages */    dst_page_offset = dst_offset & ~PAGE_CACHE_MASK;    src_page_offset = 0;    /* compute number of bytes left in pages */    dst_page_bytes_left = PAGE_CACHE_SIZE - dst_page_offset;    src_page_bytes_left = PAGE_CACHE_SIZE; /* adjusted below */    /* get pages */    dst_page = wrapfs_get1page(file, dst_page_index);    if (IS_ERR(dst_page)) {	err = PTR_ERR(dst_page);	goto out;    }    /* map pages into kernel addresses */    src_kaddr = encoded_pages->data;    a_ops = file->f_dentry->d_inode->i_mapping->a_ops;    while (1) {	src_page_bytes_left = MIN(src_page_bytes_left, total_bytes_to_copy);	bytes_to_copy = MIN(src_page_bytes_left, dst_page_bytes_left);	/* lock destination page */	lock_page(dst_page);	err = a_ops->prepare_write(file,				   dst_page,				   dst_page_offset,				   dst_page_offset + bytes_to_copy);	if (err < 0) {		/* XXX: what about partial writes */	    UnlockPage(dst_page);	    goto out_release;	}	dst_kaddr = (char *) page_address(dst_page);	/* actually copy some bytes */	memmove(dst_kaddr + dst_page_offset,		src_kaddr + src_page_offset,		bytes_to_copy);	err = a_ops->commit_write(file,				  dst_page,				  dst_page_offset,				  dst_page_offset + bytes_to_copy);	UnlockPage(dst_page);	if (err < 0)	    goto out_release;	total_bytes_to_copy -= bytes_to_copy;	//	printk("EZK1: total_bytes_to_copy 0x%x\n", (int) total_bytes_to_copy);	if (total_bytes_to_copy == 0)	    break;	/* adjust destinations as needed */	dst_page_bytes_left -= bytes_to_copy;	if (dst_page_bytes_left == 0) { /* get new page */	    page_cache_release(dst_page);	    dst_page_index++;	    dst_page_offset = 0;	    dst_page_bytes_left = PAGE_CACHE_SIZE;	    dst_page = wrapfs_get1page(file, dst_page_index);	    if (IS_ERR(dst_page)) {		err = PTR_ERR(dst_page);		goto out;	    }	} else {	    dst_page_offset += bytes_to_copy;	}	/* adjust sources as needed */	src_page_bytes_left -= bytes_to_copy;	if (src_page_bytes_left == 0) { /* get new page */	    src_page_offset = 0;	    src_page_bytes_left = PAGE_CACHE_SIZE;	    encoded_pages = encoded_pages->next;	    src_kaddr = encoded_pages->data;	} else {	    src_page_offset += bytes_to_copy;	}	if (current->need_resched)	    schedule();    } /* end of "while (1)" */ out_release:    page_cache_release(dst_page); out:    print_exit_status(err);    return err;}STATIC intwrapfs_commit_write(file_t *file, page_t *page, unsigned from, unsigned to){    int err;    inode_t *inode;    inode_t *hidden_inode;    file_t *hidden_file = NULL;    loff_t pos = 0;    struct encoded_page *ep = NULL, *next_ep, **cur_ep;    unsigned real_to, hidden_size, page_offset;    struct iattr attr;    void *opaque = NULL;    off_t old_hidden_size, hidden_offset, old_hidden_offset, delta;    dentry_t *hidden_dentry;    struct scafs_header *hdr;    int need_to_call = 1;    print_entry_location();    inode = page->mapping->host;/* CPW: Moved below print_entry_location */    hidden_inode = itohi(inode);    ASSERT(file != NULL);    hidden_file = ftohf(file);    hidden_dentry = hidden_file->f_dentry;    down(&hidden_inode->i_sem);    /*     * here we have a kmapped page, with data from the user copied     * into it.  we need to encode_block it, and then call the lower     * commit_write.  We also need to simulate same behavior of     * generic_file_write, and call prepare_write on the lower f/s first.     */# ifdef FIST_COUNT_WRITES    count_writes++;# endif /* FIST_COUNT_WRITES */    hdr = &itopd(inode)->hdr;    page_offset = page->index << PAGE_CACHE_SHIFT;    if (inode->i_size > page_offset + to)	if (inode->i_size > page_offset + PAGE_CACHE_SIZE)	    real_to = PAGE_CACHE_SIZE;	else	    real_to = inode->i_size - page_offset;    else	real_to = to;    hidden_size = 0;    cur_ep = &ep;    while (need_to_call) {	*cur_ep = kmalloc(sizeof(struct encoded_page), GFP_KERNEL);	if (!*cur_ep) {	    err = -ENOMEM;	    goto out_free;	}	(*cur_ep)->data = (char *) __get_free_page(GFP_KERNEL);#ifdef FIST_FAST_TAILS	if (CAN_BE_FASTTAIL_PAGE(real_to, inode) &&	    page->index + 1 >= hdr->num_chunks) {	    memcpy((*cur_ep)->data, (char *) page_address(page), real_to);	    need_to_call = 0;	    err = real_to;	    hdr->flags |= SCA_FLAG_FASTTAIL;	} else#endif /* FIST_FAST_TAILS */	{	    err = wrapfs_encode_buffers((*cur_ep)->data,					(char *) page_address(page),					&need_to_call,					real_to,					inode,					inode->i_sb,					&opaque);	    if (page->index + 1 >= hdr->num_chunks)		hdr->flags &= ~SCA_FLAG_FASTTAIL;	}

⌨️ 快捷键说明

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