vfs_file.c 16.6 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 408
	ssize_t retval;
	loff_t origin;
409
	int err = 0;
410

411 412
	retval = generic_write_checks(iocb, from);
	if (retval <= 0)
413 414
		return retval;

415 416
	origin = iocb->ki_pos;
	retval = p9_client_write(file->private_data, iocb->ki_pos, from, &err);
417
	if (retval > 0) {
A
Al Viro 已提交
418
		struct inode *inode = file_inode(file);
419 420 421 422 423 424 425
		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);
426
		iocb->ki_pos += retval;
427
		i_size = i_size_read(inode);
428 429 430
		if (iocb->ki_pos > i_size) {
			inode_add_bytes(inode, iocb->ki_pos - i_size);
			i_size_write(inode, iocb->ki_pos);
431 432 433 434
		}
		return retval;
	}
	return err;
435 436
}

437 438
static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end,
			   int datasync)
439 440
{
	struct p9_fid *fid;
441
	struct inode *inode = filp->f_mapping->host;
442 443 444
	struct p9_wstat wstat;
	int retval;

445 446 447 448 449
	retval = filemap_write_and_wait_range(inode->i_mapping, start, end);
	if (retval)
		return retval;

	mutex_lock(&inode->i_mutex);
450
	p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
451 452 453 454 455

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

	retval = p9_client_wstat(fid, &wstat);
456 457
	mutex_unlock(&inode->i_mutex);

458 459 460
	return retval;
}

461 462
int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
			 int datasync)
463 464
{
	struct p9_fid *fid;
465
	struct inode *inode = filp->f_mapping->host;
466 467
	int retval;

468 469 470 471 472
	retval = filemap_write_and_wait_range(inode->i_mapping, start, end);
	if (retval)
		return retval;

	mutex_lock(&inode->i_mutex);
473
	p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
474 475 476

	fid = filp->private_data;

477
	retval = p9_client_fsync(fid, datasync);
478 479
	mutex_unlock(&inode->i_mutex);

480 481 482
	return retval;
}

483
static int
484
v9fs_file_mmap(struct file *filp, struct vm_area_struct *vma)
485 486 487
{
	int retval;

488 489

	retval = generic_file_mmap(filp, vma);
490 491 492 493 494 495
	if (!retval)
		vma->vm_ops = &v9fs_file_vm_ops;

	return retval;
}

496 497 498 499 500 501 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
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;
}

533 534 535
static int
v9fs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
{
536
	struct v9fs_inode *v9inode;
537 538
	struct page *page = vmf->page;
	struct file *filp = vma->vm_file;
A
Al Viro 已提交
539
	struct inode *inode = file_inode(filp);
540 541


542 543
	p9_debug(P9_DEBUG_VFS, "page %p fid %lx\n",
		 page, (unsigned long)filp->private_data);
544

545 546 547
	/* Update file times before taking page lock */
	file_update_time(filp);

548
	v9inode = V9FS_I(inode);
549 550
	/* make sure the cache has finished storing the page */
	v9fs_fscache_wait_on_page_write(inode, page);
551
	BUG_ON(!v9inode->writeback_fid);
552 553 554
	lock_page(page);
	if (page->mapping != inode->i_mapping)
		goto out_unlock;
555
	wait_for_stable_page(page);
556 557 558 559 560 561 562

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

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

/**
 * 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 已提交
587
v9fs_mmap_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
588 589 590 591 592
{
	/*
	 * TODO: invalidate mmaps on filp's inode between
	 * offset and offset+count
	 */
A
Al Viro 已提交
593
	return v9fs_file_write_iter(iocb, from);
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
}

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


622 623
static const struct vm_operations_struct v9fs_file_vm_ops = {
	.fault = filemap_fault,
624
	.map_pages = filemap_map_pages,
625 626 627
	.page_mkwrite = v9fs_vm_page_mkwrite,
};

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

635

636
const struct file_operations v9fs_cached_file_operations = {
637
	.llseek = generic_file_llseek,
638
	.read_iter = generic_file_read_iter,
639
	.write_iter = generic_file_write_iter,
640 641 642
	.open = v9fs_file_open,
	.release = v9fs_dir_release,
	.lock = v9fs_file_lock,
643
	.mmap = v9fs_file_mmap,
644
	.fsync = v9fs_file_fsync,
645 646
};

647
const struct file_operations v9fs_cached_file_operations_dotl = {
648
	.llseek = generic_file_llseek,
649
	.read_iter = generic_file_read_iter,
650
	.write_iter = generic_file_write_iter,
651 652
	.open = v9fs_file_open,
	.release = v9fs_dir_release,
M
M. Mohan Kumar 已提交
653 654
	.lock = v9fs_file_lock_dotl,
	.flock = v9fs_file_flock_dotl,
655
	.mmap = v9fs_file_mmap,
656
	.fsync = v9fs_file_fsync_dotl,
657 658
};

659
const struct file_operations v9fs_file_operations = {
660
	.llseek = generic_file_llseek,
A
Al Viro 已提交
661 662
	.read_iter = v9fs_file_read_iter,
	.write_iter = v9fs_file_write_iter,
663 664 665
	.open = v9fs_file_open,
	.release = v9fs_dir_release,
	.lock = v9fs_file_lock,
666
	.mmap = generic_file_readonly_mmap,
667
	.fsync = v9fs_file_fsync,
668
};
669 670 671

const struct file_operations v9fs_file_operations_dotl = {
	.llseek = generic_file_llseek,
A
Al Viro 已提交
672 673
	.read_iter = v9fs_file_read_iter,
	.write_iter = v9fs_file_write_iter,
674 675
	.open = v9fs_file_open,
	.release = v9fs_dir_release,
M
M. Mohan Kumar 已提交
676 677
	.lock = v9fs_file_lock_dotl,
	.flock = v9fs_file_flock_dotl,
678
	.mmap = generic_file_readonly_mmap,
679
	.fsync = v9fs_file_fsync_dotl,
680
};
681 682 683

const struct file_operations v9fs_mmap_file_operations = {
	.llseek = generic_file_llseek,
A
Al Viro 已提交
684 685
	.read_iter = v9fs_mmap_file_read_iter,
	.write_iter = v9fs_mmap_file_write_iter,
686 687 688 689 690 691 692 693 694
	.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 已提交
695 696
	.read_iter = v9fs_mmap_file_read_iter,
	.write_iter = v9fs_mmap_file_write_iter,
697 698 699 700 701 702 703
	.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,
};