vfs_file.c 16.9 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*
 *  linux/fs/9p/vfs_file.c
 *
 * This file contians vfs file ops for 9P2000.
 *
 *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
 *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
 *
 *  This program is free software; you can redistribute it and/or modify
10 11
 *  it under the terms of the GNU General Public License version 2
 *  as published by the Free Software Foundation.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to:
 *  Free Software Foundation
 *  51 Franklin Street, Fifth Floor
 *  Boston, MA  02111-1301  USA
 *
 */

#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
29
#include <linux/sched.h>
30 31 32 33 34
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/inet.h>
#include <linux/list.h>
35
#include <linux/pagemap.h>
M
M. Mohan Kumar 已提交
36
#include <linux/utsname.h>
37 38
#include <asm/uaccess.h>
#include <linux/idr.h>
39
#include <linux/uio.h>
40
#include <linux/slab.h>
41 42
#include <net/9p/9p.h>
#include <net/9p/client.h>
43 44 45 46

#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
47
#include "cache.h"
48

49
static const struct vm_operations_struct v9fs_file_vm_ops;
50
static const struct vm_operations_struct v9fs_mmap_file_vm_ops;
51

52 53 54 55 56 57 58 59 60
/**
 * v9fs_file_open - open a file (or directory)
 * @inode: inode to be opened
 * @file: file being opened
 *
 */

int v9fs_file_open(struct inode *inode, struct file *file)
{
61
	int err;
62
	struct v9fs_inode *v9inode;
63 64 65
	struct v9fs_session_info *v9ses;
	struct p9_fid *fid;
	int omode;
66

67
	p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file);
68
	v9inode = V9FS_I(inode);
69
	v9ses = v9fs_inode2v9ses(inode);
M
M. Mohan Kumar 已提交
70
	if (v9fs_proto_dotl(v9ses))
71
		omode = v9fs_open_to_dotl_flags(file->f_flags);
M
M. Mohan Kumar 已提交
72 73 74
	else
		omode = v9fs_uflags2omode(file->f_flags,
					v9fs_proto_dotu(v9ses));
75 76 77 78 79 80 81
	fid = file->private_data;
	if (!fid) {
		fid = v9fs_fid_clone(file->f_path.dentry);
		if (IS_ERR(fid))
			return PTR_ERR(fid);

		err = p9_client_open(fid, omode);
82
		if (err < 0) {
83 84 85
			p9_client_clunk(fid);
			return err;
		}
M
M. Mohan Kumar 已提交
86 87
		if ((file->f_flags & O_APPEND) &&
			(!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)))
88
			generic_file_llseek(file, 0, SEEK_END);
89
	}
90

91
	file->private_data = fid;
92
	mutex_lock(&v9inode->v_mutex);
93 94
	if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
	    !v9inode->writeback_fid &&
95
	    ((file->f_flags & O_ACCMODE) != O_RDONLY)) {
96
		/*
97
		 * clone a fid and add it to writeback_fid
98 99 100 101 102 103 104 105
		 * we do it during open time instead of
		 * page dirty time via write_begin/page_mkwrite
		 * because we want write after unlink usecase
		 * to work.
		 */
		fid = v9fs_writeback_fid(file->f_path.dentry);
		if (IS_ERR(fid)) {
			err = PTR_ERR(fid);
106
			mutex_unlock(&v9inode->v_mutex);
107 108
			goto out_error;
		}
109
		v9inode->writeback_fid = (void *) fid;
110
	}
111
	mutex_unlock(&v9inode->v_mutex);
112
	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
113
		v9fs_cache_inode_set_cookie(inode, file);
114
	return 0;
115 116 117 118
out_error:
	p9_client_clunk(file->private_data);
	file->private_data = NULL;
	return err;
119 120 121 122
}

/**
 * v9fs_file_lock - lock a file (or directory)
E
Eric Van Hensbergen 已提交
123 124 125
 * @filp: file to be locked
 * @cmd: lock command
 * @fl: file lock structure
126
 *
E
Eric Van Hensbergen 已提交
127
 * Bugs: this looks like a local only lock, we should extend into 9P
128 129 130 131 132 133
 *       by using open exclusive
 */

static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
{
	int res = 0;
A
Al Viro 已提交
134
	struct inode *inode = file_inode(filp);
135

136
	p9_debug(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
137 138

	/* No mandatory locks */
139
	if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
140 141 142
		return -ENOLCK;

	if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
143
		filemap_write_and_wait(inode->i_mapping);
144
		invalidate_mapping_pages(&inode->i_data, 0, -1);
145 146 147 148 149
	}

	return res;
}

M
M. Mohan Kumar 已提交
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
{
	struct p9_flock flock;
	struct p9_fid *fid;
	uint8_t status;
	int res = 0;
	unsigned char fl_type;

	fid = filp->private_data;
	BUG_ON(fid == NULL);

	if ((fl->fl_flags & FL_POSIX) != FL_POSIX)
		BUG();

	res = posix_lock_file_wait(filp, fl);
	if (res < 0)
		goto out;

	/* convert posix lock to p9 tlock args */
	memset(&flock, 0, sizeof(flock));
170 171 172 173 174 175 176 177 178 179 180 181
	/* map the lock type */
	switch (fl->fl_type) {
	case F_RDLCK:
		flock.type = P9_LOCK_TYPE_RDLCK;
		break;
	case F_WRLCK:
		flock.type = P9_LOCK_TYPE_WRLCK;
		break;
	case F_UNLCK:
		flock.type = P9_LOCK_TYPE_UNLCK;
		break;
	}
M
M. Mohan Kumar 已提交
182 183 184 185 186 187
	flock.start = fl->fl_start;
	if (fl->fl_end == OFFSET_MAX)
		flock.length = 0;
	else
		flock.length = fl->fl_end - fl->fl_start + 1;
	flock.proc_id = fl->fl_pid;
188
	flock.client_id = fid->clnt->name;
M
M. Mohan Kumar 已提交
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
	if (IS_SETLKW(cmd))
		flock.flags = P9_LOCK_FLAGS_BLOCK;

	/*
	 * if its a blocked request and we get P9_LOCK_BLOCKED as the status
	 * for lock request, keep on trying
	 */
	for (;;) {
		res = p9_client_lock_dotl(fid, &flock, &status);
		if (res < 0)
			break;

		if (status != P9_LOCK_BLOCKED)
			break;
		if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd))
			break;
205 206
		if (schedule_timeout_interruptible(P9_LOCK_TIMEOUT) != 0)
			break;
M
M. Mohan Kumar 已提交
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
	}

	/* map 9p status to VFS status */
	switch (status) {
	case P9_LOCK_SUCCESS:
		res = 0;
		break;
	case P9_LOCK_BLOCKED:
		res = -EAGAIN;
		break;
	case P9_LOCK_ERROR:
	case P9_LOCK_GRACE:
		res = -ENOLCK;
		break;
	default:
		BUG();
	}

	/*
	 * incase server returned error for lock request, revert
	 * it locally
	 */
	if (res < 0 && fl->fl_type != F_UNLCK) {
		fl_type = fl->fl_type;
		fl->fl_type = F_UNLCK;
		res = posix_lock_file_wait(filp, fl);
		fl->fl_type = fl_type;
	}
out:
	return res;
}

M
M. Mohan Kumar 已提交
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
{
	struct p9_getlock glock;
	struct p9_fid *fid;
	int res = 0;

	fid = filp->private_data;
	BUG_ON(fid == NULL);

	posix_test_lock(filp, fl);
	/*
	 * if we have a conflicting lock locally, no need to validate
	 * with server
	 */
	if (fl->fl_type != F_UNLCK)
		return res;

	/* convert posix lock to p9 tgetlock args */
	memset(&glock, 0, sizeof(glock));
258
	glock.type  = P9_LOCK_TYPE_UNLCK;
M
M. Mohan Kumar 已提交
259 260 261 262 263 264
	glock.start = fl->fl_start;
	if (fl->fl_end == OFFSET_MAX)
		glock.length = 0;
	else
		glock.length = fl->fl_end - fl->fl_start + 1;
	glock.proc_id = fl->fl_pid;
265
	glock.client_id = fid->clnt->name;
M
M. Mohan Kumar 已提交
266 267 268 269

	res = p9_client_getlock_dotl(fid, &glock);
	if (res < 0)
		return res;
270 271 272 273 274 275 276 277 278 279 280 281 282
	/* map 9p lock type to os lock type */
	switch (glock.type) {
	case P9_LOCK_TYPE_RDLCK:
		fl->fl_type = F_RDLCK;
		break;
	case P9_LOCK_TYPE_WRLCK:
		fl->fl_type = F_WRLCK;
		break;
	case P9_LOCK_TYPE_UNLCK:
		fl->fl_type = F_UNLCK;
		break;
	}
	if (glock.type != P9_LOCK_TYPE_UNLCK) {
M
M. Mohan Kumar 已提交
283 284 285 286 287 288
		fl->fl_start = glock.start;
		if (glock.length == 0)
			fl->fl_end = OFFSET_MAX;
		else
			fl->fl_end = glock.start + glock.length - 1;
		fl->fl_pid = glock.proc_id;
289
	}
290
	kfree(glock.client_id);
M
M. Mohan Kumar 已提交
291 292 293
	return res;
}

M
M. Mohan Kumar 已提交
294 295 296 297 298 299 300 301 302 303
/**
 * v9fs_file_lock_dotl - lock a file (or directory)
 * @filp: file to be locked
 * @cmd: lock command
 * @fl: file lock structure
 *
 */

static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl)
{
A
Al Viro 已提交
304
	struct inode *inode = file_inode(filp);
M
M. Mohan Kumar 已提交
305 306
	int ret = -ENOLCK;

A
Al Viro 已提交
307 308
	p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n",
		 filp, cmd, fl, filp);
M
M. Mohan Kumar 已提交
309 310 311 312 313 314 315 316 317 318 319 320

	/* No mandatory locks */
	if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
		goto out_err;

	if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
		filemap_write_and_wait(inode->i_mapping);
		invalidate_mapping_pages(&inode->i_data, 0, -1);
	}

	if (IS_SETLK(cmd) || IS_SETLKW(cmd))
		ret = v9fs_file_do_lock(filp, cmd, fl);
M
M. Mohan Kumar 已提交
321 322
	else if (IS_GETLK(cmd))
		ret = v9fs_file_getlock(filp, fl);
M
M. Mohan Kumar 已提交
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
	else
		ret = -EINVAL;
out_err:
	return ret;
}

/**
 * v9fs_file_flock_dotl - lock a file
 * @filp: file to be locked
 * @cmd: lock command
 * @fl: file lock structure
 *
 */

static int v9fs_file_flock_dotl(struct file *filp, int cmd,
	struct file_lock *fl)
{
A
Al Viro 已提交
340
	struct inode *inode = file_inode(filp);
M
M. Mohan Kumar 已提交
341 342
	int ret = -ENOLCK;

A
Al Viro 已提交
343 344
	p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n",
		 filp, cmd, fl, filp);
M
M. Mohan Kumar 已提交
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368

	/* No mandatory locks */
	if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
		goto out_err;

	if (!(fl->fl_flags & FL_FLOCK))
		goto out_err;

	if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
		filemap_write_and_wait(inode->i_mapping);
		invalidate_mapping_pages(&inode->i_data, 0, -1);
	}
	/* Convert flock to posix lock */
	fl->fl_flags |= FL_POSIX;
	fl->fl_flags ^= FL_FLOCK;

	if (IS_SETLK(cmd) | IS_SETLKW(cmd))
		ret = v9fs_file_do_lock(filp, cmd, fl);
	else
		ret = -EINVAL;
out_err:
	return ret;
}

369 370 371 372 373 374 375 376 377
/**
 * v9fs_file_read - read from a file
 * @filp: file pointer to read
 * @udata: user data buffer to read data into
 * @count: size of buffer
 * @offset: offset at which to read data
 *
 */

378
static ssize_t
A
Al Viro 已提交
379
v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
380
{
A
Al Viro 已提交
381
	struct p9_fid *fid = iocb->ki_filp->private_data;
382
	int ret, err;
383

A
Al Viro 已提交
384 385
	p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n",
		 iov_iter_count(to), iocb->ki_pos);
386

A
Al Viro 已提交
387
	ret = p9_client_read(fid, iocb->ki_pos, to, &err);
388 389
	if (!ret)
		return err;
390

A
Al Viro 已提交
391
	iocb->ki_pos += ret;
392
	return ret;
393 394
}

395 396 397 398 399 400 401 402 403
/**
 * v9fs_file_write - write to a file
 * @filp: file pointer to write
 * @data: data buffer to write data from
 * @count: size of buffer
 * @offset: offset at which to write data
 *
 */
static ssize_t
A
Al Viro 已提交
404
v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
405
{
A
Al Viro 已提交
406
	struct file *file = iocb->ki_filp;
407
	ssize_t retval = 0;
A
Al Viro 已提交
408 409
	loff_t origin = iocb->ki_pos;
	size_t count = iov_iter_count(from);
410
	int err = 0;
411

A
Al Viro 已提交
412
	retval = generic_write_checks(file, &origin, &count, 0);
413
	if (retval)
414 415
		return retval;

A
Al Viro 已提交
416
	iov_iter_truncate(from, count);
417 418

	if (!count)
419
		return 0;
420

A
Al Viro 已提交
421
	retval = p9_client_write(file->private_data, origin, from, &err);
422
	if (retval > 0) {
A
Al Viro 已提交
423
		struct inode *inode = file_inode(file);
424 425 426 427 428 429 430
		loff_t i_size;
		unsigned long pg_start, pg_end;
		pg_start = origin >> PAGE_CACHE_SHIFT;
		pg_end = (origin + retval - 1) >> PAGE_CACHE_SHIFT;
		if (inode->i_mapping && inode->i_mapping->nrpages)
			invalidate_inode_pages2_range(inode->i_mapping,
						      pg_start, pg_end);
A
Al Viro 已提交
431
		origin += retval;
432
		i_size = i_size_read(inode);
A
Al Viro 已提交
433 434 435 436
		iocb->ki_pos = origin;
		if (origin > i_size) {
			inode_add_bytes(inode, origin - i_size);
			i_size_write(inode, origin);
437 438 439 440
		}
		return retval;
	}
	return err;
441 442
}

443 444
static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end,
			   int datasync)
445 446
{
	struct p9_fid *fid;
447
	struct inode *inode = filp->f_mapping->host;
448 449 450
	struct p9_wstat wstat;
	int retval;

451 452 453 454 455
	retval = filemap_write_and_wait_range(inode->i_mapping, start, end);
	if (retval)
		return retval;

	mutex_lock(&inode->i_mutex);
456
	p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
457 458 459 460 461

	fid = filp->private_data;
	v9fs_blank_wstat(&wstat);

	retval = p9_client_wstat(fid, &wstat);
462 463
	mutex_unlock(&inode->i_mutex);

464 465 466
	return retval;
}

467 468
int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
			 int datasync)
469 470
{
	struct p9_fid *fid;
471
	struct inode *inode = filp->f_mapping->host;
472 473
	int retval;

474 475 476 477 478
	retval = filemap_write_and_wait_range(inode->i_mapping, start, end);
	if (retval)
		return retval;

	mutex_lock(&inode->i_mutex);
479
	p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
480 481 482

	fid = filp->private_data;

483
	retval = p9_client_fsync(fid, datasync);
484 485
	mutex_unlock(&inode->i_mutex);

486 487 488
	return retval;
}

489
static int
490
v9fs_file_mmap(struct file *filp, struct vm_area_struct *vma)
491 492 493
{
	int retval;

494 495

	retval = generic_file_mmap(filp, vma);
496 497 498 499 500 501
	if (!retval)
		vma->vm_ops = &v9fs_file_vm_ops;

	return retval;
}

502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
static int
v9fs_mmap_file_mmap(struct file *filp, struct vm_area_struct *vma)
{
	int retval;
	struct inode *inode;
	struct v9fs_inode *v9inode;
	struct p9_fid *fid;

	inode = file_inode(filp);
	v9inode = V9FS_I(inode);
	mutex_lock(&v9inode->v_mutex);
	if (!v9inode->writeback_fid &&
	    (vma->vm_flags & VM_WRITE)) {
		/*
		 * clone a fid and add it to writeback_fid
		 * we do it during mmap instead of
		 * page dirty time via write_begin/page_mkwrite
		 * because we want write after unlink usecase
		 * to work.
		 */
		fid = v9fs_writeback_fid(filp->f_path.dentry);
		if (IS_ERR(fid)) {
			retval = PTR_ERR(fid);
			mutex_unlock(&v9inode->v_mutex);
			return retval;
		}
		v9inode->writeback_fid = (void *) fid;
	}
	mutex_unlock(&v9inode->v_mutex);

	retval = generic_file_mmap(filp, vma);
	if (!retval)
		vma->vm_ops = &v9fs_mmap_file_vm_ops;

	return retval;
}

539 540 541
static int
v9fs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
{
542
	struct v9fs_inode *v9inode;
543 544
	struct page *page = vmf->page;
	struct file *filp = vma->vm_file;
A
Al Viro 已提交
545
	struct inode *inode = file_inode(filp);
546 547


548 549
	p9_debug(P9_DEBUG_VFS, "page %p fid %lx\n",
		 page, (unsigned long)filp->private_data);
550

551 552 553
	/* Update file times before taking page lock */
	file_update_time(filp);

554
	v9inode = V9FS_I(inode);
555 556
	/* make sure the cache has finished storing the page */
	v9fs_fscache_wait_on_page_write(inode, page);
557
	BUG_ON(!v9inode->writeback_fid);
558 559 560
	lock_page(page);
	if (page->mapping != inode->i_mapping)
		goto out_unlock;
561
	wait_for_stable_page(page);
562 563 564 565 566 567 568

	return VM_FAULT_LOCKED;
out_unlock:
	unlock_page(page);
	return VM_FAULT_NOPAGE;
}

569 570 571
/**
 * v9fs_mmap_file_read - read from a file
 * @filp: file pointer to read
F
Fabian Frederick 已提交
572
 * @data: user data buffer to read data into
573 574 575 576 577
 * @count: size of buffer
 * @offset: offset at which to read data
 *
 */
static ssize_t
A
Al Viro 已提交
578
v9fs_mmap_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
579 580
{
	/* TODO: Check if there are dirty pages */
A
Al Viro 已提交
581
	return v9fs_file_read_iter(iocb, to);
582 583 584 585 586 587 588 589 590 591 592
}

/**
 * v9fs_mmap_file_write - write to a file
 * @filp: file pointer to write
 * @data: data buffer to write data from
 * @count: size of buffer
 * @offset: offset at which to write data
 *
 */
static ssize_t
A
Al Viro 已提交
593
v9fs_mmap_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
594 595 596 597 598
{
	/*
	 * TODO: invalidate mmaps on filp's inode between
	 * offset and offset+count
	 */
A
Al Viro 已提交
599
	return v9fs_file_write_iter(iocb, from);
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
}

static void v9fs_mmap_vm_close(struct vm_area_struct *vma)
{
	struct inode *inode;

	struct writeback_control wbc = {
		.nr_to_write = LONG_MAX,
		.sync_mode = WB_SYNC_ALL,
		.range_start = vma->vm_pgoff * PAGE_SIZE,
		 /* absolute end, byte at end included */
		.range_end = vma->vm_pgoff * PAGE_SIZE +
			(vma->vm_end - vma->vm_start - 1),
	};


	p9_debug(P9_DEBUG_VFS, "9p VMA close, %p, flushing", vma);

	inode = file_inode(vma->vm_file);

	if (!mapping_cap_writeback_dirty(inode->i_mapping))
		wbc.nr_to_write = 0;

	might_sleep();
	sync_inode(inode, &wbc);
}


628 629
static const struct vm_operations_struct v9fs_file_vm_ops = {
	.fault = filemap_fault,
630
	.map_pages = filemap_map_pages,
631 632 633
	.page_mkwrite = v9fs_vm_page_mkwrite,
};

634 635 636
static const struct vm_operations_struct v9fs_mmap_file_vm_ops = {
	.close = v9fs_mmap_vm_close,
	.fault = filemap_fault,
637
	.map_pages = filemap_map_pages,
638 639 640
	.page_mkwrite = v9fs_vm_page_mkwrite,
};

641

642
const struct file_operations v9fs_cached_file_operations = {
643
	.llseek = generic_file_llseek,
A
Al Viro 已提交
644
	.read = new_sync_read,
645
	.write = new_sync_write,
646
	.read_iter = generic_file_read_iter,
647
	.write_iter = generic_file_write_iter,
648 649 650
	.open = v9fs_file_open,
	.release = v9fs_dir_release,
	.lock = v9fs_file_lock,
651
	.mmap = v9fs_file_mmap,
652
	.fsync = v9fs_file_fsync,
653 654
};

655
const struct file_operations v9fs_cached_file_operations_dotl = {
656
	.llseek = generic_file_llseek,
A
Al Viro 已提交
657
	.read = new_sync_read,
658
	.write = new_sync_write,
659
	.read_iter = generic_file_read_iter,
660
	.write_iter = generic_file_write_iter,
661 662
	.open = v9fs_file_open,
	.release = v9fs_dir_release,
M
M. Mohan Kumar 已提交
663 664
	.lock = v9fs_file_lock_dotl,
	.flock = v9fs_file_flock_dotl,
665
	.mmap = v9fs_file_mmap,
666
	.fsync = v9fs_file_fsync_dotl,
667 668
};

669
const struct file_operations v9fs_file_operations = {
670
	.llseek = generic_file_llseek,
A
Al Viro 已提交
671 672 673 674
	.read = new_sync_read,
	.write = new_sync_write,
	.read_iter = v9fs_file_read_iter,
	.write_iter = v9fs_file_write_iter,
675 676 677
	.open = v9fs_file_open,
	.release = v9fs_dir_release,
	.lock = v9fs_file_lock,
678
	.mmap = generic_file_readonly_mmap,
679
	.fsync = v9fs_file_fsync,
680
};
681 682 683

const struct file_operations v9fs_file_operations_dotl = {
	.llseek = generic_file_llseek,
A
Al Viro 已提交
684 685 686 687
	.read = new_sync_read,
	.write = new_sync_write,
	.read_iter = v9fs_file_read_iter,
	.write_iter = v9fs_file_write_iter,
688 689
	.open = v9fs_file_open,
	.release = v9fs_dir_release,
M
M. Mohan Kumar 已提交
690 691
	.lock = v9fs_file_lock_dotl,
	.flock = v9fs_file_flock_dotl,
692
	.mmap = generic_file_readonly_mmap,
693
	.fsync = v9fs_file_fsync_dotl,
694
};
695 696 697

const struct file_operations v9fs_mmap_file_operations = {
	.llseek = generic_file_llseek,
A
Al Viro 已提交
698 699 700 701
	.read = new_sync_read,
	.write = new_sync_write,
	.read_iter = v9fs_mmap_file_read_iter,
	.write_iter = v9fs_mmap_file_write_iter,
702 703 704 705 706 707 708 709 710
	.open = v9fs_file_open,
	.release = v9fs_dir_release,
	.lock = v9fs_file_lock,
	.mmap = v9fs_mmap_file_mmap,
	.fsync = v9fs_file_fsync,
};

const struct file_operations v9fs_mmap_file_operations_dotl = {
	.llseek = generic_file_llseek,
A
Al Viro 已提交
711 712 713 714
	.read = new_sync_read,
	.write = new_sync_write,
	.read_iter = v9fs_mmap_file_read_iter,
	.write_iter = v9fs_mmap_file_write_iter,
715 716 717 718 719 720 721
	.open = v9fs_file_open,
	.release = v9fs_dir_release,
	.lock = v9fs_file_lock_dotl,
	.flock = v9fs_file_flock_dotl,
	.mmap = v9fs_mmap_file_mmap,
	.fsync = v9fs_file_fsync_dotl,
};