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

📄 read.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 2 页
字号:
	offset = 0;	nbytes = req->wb_bytes;	do {		data = list_entry(list.next, struct nfs_read_data, pages);		list_del_init(&data->pages);		data->pagevec[0] = page;		data->complete = nfs_readpage_result_partial;		if (nbytes > rsize) {			nfs_read_rpcsetup(req, data, rsize, offset);			offset += rsize;			nbytes -= rsize;		} else {			nfs_read_rpcsetup(req, data, nbytes, offset);			nbytes = 0;		}		nfs_execute_read(data);	} while (nbytes != 0);	return 0;out_bad:	while (!list_empty(&list)) {		data = list_entry(list.next, struct nfs_read_data, pages);		list_del(&data->pages);		nfs_readdata_free(data);	}	SetPageError(page);	nfs_readpage_release(req);	return -ENOMEM;}static int nfs_pagein_one(struct list_head *head, struct inode *inode){	struct nfs_page		*req;	struct page		**pages;	struct nfs_read_data	*data;	unsigned int		count;	if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE)		return nfs_pagein_multi(head, inode);	data = nfs_readdata_alloc();	if (!data)		goto out_bad;	INIT_LIST_HEAD(&data->pages);	pages = data->pagevec;	count = 0;	while (!list_empty(head)) {		req = nfs_list_entry(head->next);		nfs_list_remove_request(req);		nfs_list_add_request(req, &data->pages);		ClearPageError(req->wb_page);		*pages++ = req->wb_page;		count += req->wb_bytes;	}	req = nfs_list_entry(data->pages.next);	data->complete = nfs_readpage_result_full;	nfs_read_rpcsetup(req, data, count, 0);	nfs_execute_read(data);	return 0;out_bad:	nfs_async_read_error(head);	return -ENOMEM;}intnfs_pagein_list(struct list_head *head, int rpages){	LIST_HEAD(one_request);	struct nfs_page		*req;	int			error = 0;	unsigned int		pages = 0;	while (!list_empty(head)) {		pages += nfs_coalesce_requests(head, &one_request, rpages);		req = nfs_list_entry(one_request.next);		error = nfs_pagein_one(&one_request, req->wb_context->dentry->d_inode);		if (error < 0)			break;	}	if (error >= 0)		return pages;	nfs_async_read_error(head);	return error;}/* * Handle a read reply that fills part of a page. */static void nfs_readpage_result_partial(struct nfs_read_data *data, int status){	struct nfs_page *req = data->req;	struct page *page = req->wb_page; 	if (status >= 0) {		unsigned int request = data->args.count;		unsigned int result = data->res.count;		if (result < request) {			memclear_highpage_flush(page,						data->args.pgbase + result,						request - result);		}	} else		SetPageError(page);	if (atomic_dec_and_test(&req->wb_complete)) {		if (!PageError(page))			SetPageUptodate(page);		nfs_readpage_release(req);	}}/* * This is the callback from RPC telling us whether a reply was * received or some error occurred (timeout or socket shutdown). */static void nfs_readpage_result_full(struct nfs_read_data *data, int status){	unsigned int count = data->res.count;	while (!list_empty(&data->pages)) {		struct nfs_page *req = nfs_list_entry(data->pages.next);		struct page *page = req->wb_page;		nfs_list_remove_request(req);		if (status >= 0) {			if (count < PAGE_CACHE_SIZE) {				if (count < req->wb_bytes)					memclear_highpage_flush(page,							req->wb_pgbase + count,							req->wb_bytes - count);				count = 0;			} else				count -= PAGE_CACHE_SIZE;			SetPageUptodate(page);		} else			SetPageError(page);		nfs_readpage_release(req);	}}/* * This is the callback from RPC telling us whether a reply was * received or some error occurred (timeout or socket shutdown). */void nfs_readpage_result(struct rpc_task *task){	struct nfs_read_data *data = (struct nfs_read_data *)task->tk_calldata;	struct nfs_readargs *argp = &data->args;	struct nfs_readres *resp = &data->res;	int status = task->tk_status;	dprintk("NFS: %4d nfs_readpage_result, (status %d)\n",		task->tk_pid, status);	/* Is this a short read? */	if (task->tk_status >= 0 && resp->count < argp->count && !resp->eof) {		/* Has the server at least made some progress? */		if (resp->count != 0) {			/* Yes, so retry the read at the end of the data */			argp->offset += resp->count;			argp->pgbase += resp->count;			argp->count -= resp->count;			rpc_restart_call(task);			return;		}		task->tk_status = -EIO;	}	NFS_FLAGS(data->inode) |= NFS_INO_INVALID_ATIME;	data->complete(data, status);}/* * Read a page over NFS. * We read the page synchronously in the following case: *  -	The error flag is set for this page. This happens only when a *	previous async read operation failed. */int nfs_readpage(struct file *file, struct page *page){	struct nfs_open_context *ctx;	struct inode *inode = page->mapping->host;	int		error;	dprintk("NFS: nfs_readpage (%p %ld@%lu)\n",		page, PAGE_CACHE_SIZE, page->index);	/*	 * Try to flush any pending writes to the file..	 *	 * NOTE! Because we own the page lock, there cannot	 * be any new pending writes generated at this point	 * for this page (other pages can be written to).	 */	error = nfs_wb_page(inode, page);	if (error)		goto out_error;	if (file == NULL) {		ctx = nfs_find_open_context(inode, FMODE_READ);		if (ctx == NULL)			return -EBADF;	} else		ctx = get_nfs_open_context((struct nfs_open_context *)				file->private_data);	if (!IS_SYNC(inode)) {		error = nfs_readpage_async(ctx, inode, page);		goto out;	}	error = nfs_readpage_sync(ctx, inode, page);	if (error < 0 && IS_SWAPFILE(inode))		printk("Aiee.. nfs swap-in of page failed!\n");out:	put_nfs_open_context(ctx);	return error;out_error:	unlock_page(page);	return error;}struct nfs_readdesc {	struct list_head *head;	struct nfs_open_context *ctx;};static intreadpage_async_filler(void *data, struct page *page){	struct nfs_readdesc *desc = (struct nfs_readdesc *)data;	struct inode *inode = page->mapping->host;	struct nfs_page *new;	unsigned int len;	nfs_wb_page(inode, page);	len = nfs_page_length(inode, page);	if (len == 0)		return nfs_return_empty_page(page);	new = nfs_create_request(desc->ctx, inode, page, 0, len);	if (IS_ERR(new)) {			SetPageError(page);			unlock_page(page);			return PTR_ERR(new);	}	if (len < PAGE_CACHE_SIZE)		memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len);	nfs_lock_request(new);	nfs_list_add_request(new, desc->head);	return 0;}int nfs_readpages(struct file *filp, struct address_space *mapping,		struct list_head *pages, unsigned nr_pages){	LIST_HEAD(head);	struct nfs_readdesc desc = {		.head		= &head,	};	struct inode *inode = mapping->host;	struct nfs_server *server = NFS_SERVER(inode);	int ret;	dprintk("NFS: nfs_readpages (%s/%Ld %d)\n",			inode->i_sb->s_id,			(long long)NFS_FILEID(inode),			nr_pages);	if (filp == NULL) {		desc.ctx = nfs_find_open_context(inode, FMODE_READ);		if (desc.ctx == NULL)			return -EBADF;	} else		desc.ctx = get_nfs_open_context((struct nfs_open_context *)				filp->private_data);	ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc);	if (!list_empty(&head)) {		int err = nfs_pagein_list(&head, server->rpages);		if (!ret)			ret = err;	}	put_nfs_open_context(desc.ctx);	return ret;}int nfs_init_readpagecache(void){	nfs_rdata_cachep = kmem_cache_create("nfs_read_data",					     sizeof(struct nfs_read_data),					     0, SLAB_HWCACHE_ALIGN,					     NULL, NULL);	if (nfs_rdata_cachep == NULL)		return -ENOMEM;	nfs_rdata_mempool = mempool_create(MIN_POOL_READ,					   mempool_alloc_slab,					   mempool_free_slab,					   nfs_rdata_cachep);	if (nfs_rdata_mempool == NULL)		return -ENOMEM;	return 0;}void nfs_destroy_readpagecache(void){	mempool_destroy(nfs_rdata_mempool);	if (kmem_cache_destroy(nfs_rdata_cachep))		printk(KERN_INFO "nfs_read_data: not all structures were freed\n");}

⌨️ 快捷键说明

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