/* 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); }
/* * 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); }