Пример #1
0
static int nfs_file_read(struct inode *inode, struct file *file, char *buf,
			 int count)
{
	int result;
	int hunk;
	int i;
	int n;
	struct nfs_fattr fattr;
	char *data;
	off_t pos;

	if (!inode) {
		printk("nfs_file_read: inode = NULL\n");
		return -EINVAL;
	}
	if (!S_ISREG(inode->i_mode)) {
		printk("nfs_file_read: read from non-file, mode %07o\n",
			inode->i_mode);
		return -EINVAL;
	}
	pos = file->f_pos;
	if (file->f_pos + count > inode->i_size)
		count = inode->i_size - pos;
	if (count <= 0)
		return 0;
	n = NFS_SERVER(inode)->rsize;
	data = (char *) kmalloc(n, GFP_KERNEL);
	for (i = 0; i < count; i += n) {
		hunk = count - i;
		if (hunk > n)
			hunk = n;
		result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode), 
			pos, hunk, data, &fattr);
		if (result < 0) {
			kfree_s(data, n);
			return result;
		}
		memcpy_tofs(buf, data, result);
		pos += result;
		buf += result;
		if (result < n) {
			i += result;
			break;
		}
	}
	file->f_pos = pos;
	kfree_s(data, n);
	nfs_refresh_inode(inode, &fattr);
	return i;
}
Пример #2
0
static inline int
do_read_nfs_sync(struct inode * inode, struct page * page)
{
	struct nfs_fattr fattr;
	int		result, refresh = 0;
	int		count = PAGE_SIZE;
	int		rsize = NFS_SERVER(inode)->rsize;
	char		*buf = (char *) page_address(page);
	unsigned long	pos = page->offset;

	dprintk("NFS: do_read_nfs_sync(%p)\n", page);

	set_bit(PG_locked, &page->flags);
	clear_bit(PG_error, &page->flags);

	do {
		if (count < rsize)
			rsize = count;
		result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode), 
			pos, rsize, buf, &fattr);
		dprintk("nfs_proc_read(%s, (%x,%lx), %ld, %d, %p) = %d\n",
				NFS_SERVER(inode)->hostname,
				inode->i_dev, inode->i_ino,
				pos, rsize, buf, result);
		/*
		 * Even if we had a partial success we can't mark the page
		 * cache valid.
		 */
		if (result < 0)
			goto io_error;
		refresh = 1;
		count -= result;
		pos += result;
		buf += result;
		if (result < rsize)
			break;
	} while (count);

	memset(buf, 0, count);
	set_bit(PG_uptodate, &page->flags);
	result = 0;

io_error:
	if (refresh)
		nfs_refresh_inode(inode, &fattr);
	clear_bit(PG_locked, &page->flags);
	wake_up(&page->wait);
	return result;
}
Пример #3
0
/*
 * Fill in the supplied page for mmap
 */
static unsigned long nfs_file_mmap_nopage(struct vm_area_struct * area,
	unsigned long address, unsigned long page, int no_share)
{
	struct inode * inode = area->vm_inode;
	unsigned int clear;
	unsigned long tmp;
	int n;
	int i;
	int pos;
	struct nfs_fattr fattr;

	address &= PAGE_MASK;
	pos = address - area->vm_start + area->vm_offset;

	clear = 0;
	if (address + PAGE_SIZE > area->vm_end) {
		clear = address + PAGE_SIZE - area->vm_end;
	}

	n = NFS_SERVER(inode)->rsize; /* what we can read in one go */

	for (i = 0; i < (PAGE_SIZE - clear); i += n) {
		int hunk, result;

		hunk = PAGE_SIZE - i;
		if (hunk > n)
			hunk = n;
		result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode),
			pos, hunk, (char *) (page + i), &fattr, 0);
		if (result < 0)
			break;
		pos += result;
		if (result < n) {
			i += result;
			break;
		}
	}

#ifdef doweneedthishere
	nfs_refresh_inode(inode, &fattr);
#endif

	tmp = page + PAGE_SIZE;
	while (clear--) {
		*(char *)--tmp = 0;
	}
	return page;
}
Пример #4
0
static int nfs_file_read(struct inode *inode, struct file *file, char *buf,
			 int count)
{
	int result, hunk, i, n, fs;
	struct nfs_fattr fattr;
	char *data;
	off_t pos;

	if (!inode) {
		printk("nfs_file_read: inode = NULL\n");
		return -EINVAL;
	}
	if (!S_ISREG(inode->i_mode)) {
		printk("nfs_file_read: read from non-file, mode %07o\n",
			inode->i_mode);
		return -EINVAL;
	}
	pos = file->f_pos;
	if (pos + count > inode->i_size)
		count = inode->i_size - pos;
	if (count <= 0)
		return 0;
	++num_requests;
	cli();
	for (i = 0; i < READ_CACHE_SIZE; i++)
		if ((cache[i].inode_num == inode->i_ino)
			&& (cache[i].file_pos <= pos)
			&& (cache[i].file_pos + cache[i].len >= pos + count)
			&& (abs(jiffies - cache[i].time) <= EXPIRE_CACHE))
			break;
	if (i < READ_CACHE_SIZE) {
		++cache[i].in_use;
		sti();
		++num_cache_hits;
		memcpy_tofs(buf, cache[i].buf + pos - cache[i].file_pos, count);
		--cache[i].in_use;
		file->f_pos += count;
		return count;
	}
	sti();
	n = NFS_SERVER(inode)->rsize;
	for (i = 0; i < count - n; i += n) {
		result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode), 
			pos, n, buf, &fattr, 1);
		if (result < 0)
			return result;
		pos += result;
		buf += result;
		if (result < n) {
			file->f_pos = pos;
			nfs_refresh_inode(inode, &fattr);
			return i + result;
		}
	}
	fs = 0;
	if (!(data = (char *)kmalloc(n, GFP_KERNEL))) {
		data = buf;
		fs = 1;
	}
	result = nfs_proc_read(NFS_SERVER(inode), NFS_FH(inode),
		pos, n, data, &fattr, fs);
	if (result < 0) {
		if (!fs)
			kfree_s(data, n);
		return result;
	}
	hunk = count - i;
	if (result < hunk)
		hunk = result;
	if (fs) {
		file->f_pos = pos + hunk;
		nfs_refresh_inode(inode, &fattr);
		return i + hunk;
	}
	memcpy_tofs(buf, data, hunk);
	file->f_pos = pos + hunk;
	nfs_refresh_inode(inode, &fattr);
	cli();
	if (cache[tail].in_use == 0) {
		if (cache[tail].buf)
			kfree_s(cache[tail].buf, cache[tail].buf_size);
		cache[tail].buf = data;
		cache[tail].buf_size = n;
		cache[tail].inode_num = inode->i_ino;
		cache[tail].file_pos = pos;
		cache[tail].len = result;
		cache[tail].time = jiffies;
		if (++tail >= READ_CACHE_SIZE)
			tail = 0;
	} else
		kfree_s(data, n);
	sti();
	return i + hunk;
}