Exemple #1
0
/* Copy the given number of bytes from one file to another.
 * Uses provided src_ppos for src_file (or src_file->f_pos if NULL).
 * "zerocopy" reads are used when the source has a readpage method.
 */
loff_t
cr_sendfile(cr_errbuf_t *eb, struct file *dst_filp, struct file *src_filp, loff_t *src_ppos, loff_t count)
{
#ifdef cr_generic_file_read
    struct address_space *mapping;
#endif

    if (!count) return 0;
    if (!src_ppos) src_ppos = &src_filp->f_pos;

#ifdef HPAGE_SIZE
    /* The generic methods don't work on hugetlbfs files */
    if (is_file_hugepages(src_filp)) {
	return cr_sendfile_hugesrc(eb, dst_filp, src_filp, src_ppos, count);
    }
    if (is_file_hugepages(dst_filp)) {
	return cr_sendfile_hugedst(eb, dst_filp, src_filp, src_ppos, count);
    }
#endif

#if HAVE_SPLICE_DIRECT_TO_ACTOR
    /* Our 1st choice is splice_direct_to_actor(), when available and allowed.  */
    if (src_filp->f_op && src_filp->f_op->splice_read &&
        dst_filp->f_op && dst_filp->f_op->splice_write) {
	return cr_splice_direct(src_filp, src_ppos, dst_filp, count);
    }
#endif
#ifdef cr_generic_file_read
    /* Our 2nd choice algorithm is do_generic_file_read() + vfs_write()
     * But this is not available w/ kernel >= 2.6.25 (hence the ifdef)
     * nor is it available when the source is not mmap()able.
     */
    mapping = src_filp->f_dentry->d_inode->i_mapping;
    if (mapping && mapping->a_ops && mapping->a_ops->readpage) {
	return cr_sendfile_generic_read(dst_filp, src_filp, src_ppos, count);
    }
#endif

    /* Final option is vfs_read() + vfs_write() */
    return cr_sendfile_buffered(eb, dst_filp, src_filp, src_ppos, count);
}
Exemple #2
0
/*
 * shm_destroy - free the struct shmid_kernel
 *
 * @ns: namespace
 * @shp: struct to free
 *
 * It has to be called with shp and shm_ids.rwsem (writer) locked,
 * but returns with shp unlocked and freed.
 */
static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
{
	struct file *shm_file;

	shm_file = shp->shm_file;
	shp->shm_file = NULL;
	ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
	shm_rmid(ns, shp);
	shm_unlock(shp);
	if (!is_file_hugepages(shm_file))
		shmem_lock(shm_file, 0, shp->mlock_user);
	else if (shp->mlock_user)
		user_shm_unlock(file_inode(shm_file)->i_size, shp->mlock_user);
	fput(shm_file);
	ipc_rcu_putref(shp, shm_rcu_free);
}