1 /* 2 * linux/fs/9p/vfs_file.c 3 * 4 * This file contians vfs file ops for 9P2000. 5 * 6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 11 * as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to: 20 * Free Software Foundation 21 * 51 Franklin Street, Fifth Floor 22 * Boston, MA 02111-1301 USA 23 * 24 */ 25 26 #include <linux/module.h> 27 #include <linux/errno.h> 28 #include <linux/fs.h> 29 #include <linux/sched.h> 30 #include <linux/file.h> 31 #include <linux/stat.h> 32 #include <linux/string.h> 33 #include <linux/inet.h> 34 #include <linux/list.h> 35 #include <linux/pagemap.h> 36 #include <linux/utsname.h> 37 #include <asm/uaccess.h> 38 #include <linux/idr.h> 39 #include <linux/uio.h> 40 #include <linux/slab.h> 41 #include <net/9p/9p.h> 42 #include <net/9p/client.h> 43 44 #include "v9fs.h" 45 #include "v9fs_vfs.h" 46 #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 * v9fs_file_open - open a file (or directory) 54 * @inode: inode to be opened 55 * @file: file being opened 56 * 57 */ 58 59 int v9fs_file_open(struct inode *inode, struct file *file) 60 { 61 int err; 62 struct v9fs_inode *v9inode; 63 struct v9fs_session_info *v9ses; 64 struct p9_fid *fid; 65 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); 70 if (v9fs_proto_dotl(v9ses)) 71 omode = v9fs_open_to_dotl_flags(file->f_flags); 72 else 73 omode = v9fs_uflags2omode(file->f_flags, 74 v9fs_proto_dotu(v9ses)); 75 fid = file->private_data; 76 if (!fid) { 77 fid = v9fs_fid_clone(file->f_path.dentry); 78 if (IS_ERR(fid)) 79 return PTR_ERR(fid); 80 81 err = p9_client_open(fid, omode); 82 if (err < 0) { 83 p9_client_clunk(fid); 84 return err; 85 } 86 if ((file->f_flags & O_APPEND) && 87 (!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 if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) && 94 !v9inode->writeback_fid && 95 ((file->f_flags & O_ACCMODE) != O_RDONLY)) { 96 /* 97 * clone a fid and add it to writeback_fid 98 * we do it during open time instead of 99 * page dirty time via write_begin/page_mkwrite 100 * because we want write after unlink usecase 101 * to work. 102 */ 103 fid = v9fs_writeback_fid(file->f_path.dentry); 104 if (IS_ERR(fid)) { 105 err = PTR_ERR(fid); 106 mutex_unlock(&v9inode->v_mutex); 107 goto out_error; 108 } 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 out_error: 116 p9_client_clunk(file->private_data); 117 file->private_data = NULL; 118 return err; 119 } 120 121 /** 122 * v9fs_file_lock - lock a file (or directory) 123 * @filp: file to be locked 124 * @cmd: lock command 125 * @fl: file lock structure 126 * 127 * Bugs: this looks like a local only lock, we should extend into 9P 128 * by using open exclusive 129 */ 130 131 static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) 132 { 133 int res = 0; 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 return -ENOLCK; 141 142 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 return res; 148 } 149 150 static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl) 151 { 152 struct p9_flock flock; 153 struct p9_fid *fid; 154 uint8_t status; 155 int res = 0; 156 unsigned char fl_type; 157 158 fid = filp->private_data; 159 BUG_ON(fid == NULL); 160 161 if ((fl->fl_flags & FL_POSIX) != FL_POSIX) 162 BUG(); 163 164 res = posix_lock_file_wait(filp, fl); 165 if (res < 0) 166 goto out; 167 168 /* convert posix lock to p9 tlock args */ 169 memset(&flock, 0, sizeof(flock)); 170 /* map the lock type */ 171 switch (fl->fl_type) { 172 case F_RDLCK: 173 flock.type = P9_LOCK_TYPE_RDLCK; 174 break; 175 case F_WRLCK: 176 flock.type = P9_LOCK_TYPE_WRLCK; 177 break; 178 case F_UNLCK: 179 flock.type = P9_LOCK_TYPE_UNLCK; 180 break; 181 } 182 flock.start = fl->fl_start; 183 if (fl->fl_end == OFFSET_MAX) 184 flock.length = 0; 185 else 186 flock.length = fl->fl_end - fl->fl_start + 1; 187 flock.proc_id = fl->fl_pid; 188 flock.client_id = fid->clnt->name; 189 if (IS_SETLKW(cmd)) 190 flock.flags = P9_LOCK_FLAGS_BLOCK; 191 192 /* 193 * if its a blocked request and we get P9_LOCK_BLOCKED as the status 194 * for lock request, keep on trying 195 */ 196 for (;;) { 197 res = p9_client_lock_dotl(fid, &flock, &status); 198 if (res < 0) 199 break; 200 201 if (status != P9_LOCK_BLOCKED) 202 break; 203 if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd)) 204 break; 205 if (schedule_timeout_interruptible(P9_LOCK_TIMEOUT) != 0) 206 break; 207 } 208 209 /* map 9p status to VFS status */ 210 switch (status) { 211 case P9_LOCK_SUCCESS: 212 res = 0; 213 break; 214 case P9_LOCK_BLOCKED: 215 res = -EAGAIN; 216 break; 217 case P9_LOCK_ERROR: 218 case P9_LOCK_GRACE: 219 res = -ENOLCK; 220 break; 221 default: 222 BUG(); 223 } 224 225 /* 226 * incase server returned error for lock request, revert 227 * it locally 228 */ 229 if (res < 0 && fl->fl_type != F_UNLCK) { 230 fl_type = fl->fl_type; 231 fl->fl_type = F_UNLCK; 232 res = posix_lock_file_wait(filp, fl); 233 fl->fl_type = fl_type; 234 } 235 out: 236 return res; 237 } 238 239 static int v9fs_file_getlock(struct file *filp, struct file_lock *fl) 240 { 241 struct p9_getlock glock; 242 struct p9_fid *fid; 243 int res = 0; 244 245 fid = filp->private_data; 246 BUG_ON(fid == NULL); 247 248 posix_test_lock(filp, fl); 249 /* 250 * if we have a conflicting lock locally, no need to validate 251 * with server 252 */ 253 if (fl->fl_type != F_UNLCK) 254 return res; 255 256 /* convert posix lock to p9 tgetlock args */ 257 memset(&glock, 0, sizeof(glock)); 258 glock.type = P9_LOCK_TYPE_UNLCK; 259 glock.start = fl->fl_start; 260 if (fl->fl_end == OFFSET_MAX) 261 glock.length = 0; 262 else 263 glock.length = fl->fl_end - fl->fl_start + 1; 264 glock.proc_id = fl->fl_pid; 265 glock.client_id = fid->clnt->name; 266 267 res = p9_client_getlock_dotl(fid, &glock); 268 if (res < 0) 269 return res; 270 /* map 9p lock type to os lock type */ 271 switch (glock.type) { 272 case P9_LOCK_TYPE_RDLCK: 273 fl->fl_type = F_RDLCK; 274 break; 275 case P9_LOCK_TYPE_WRLCK: 276 fl->fl_type = F_WRLCK; 277 break; 278 case P9_LOCK_TYPE_UNLCK: 279 fl->fl_type = F_UNLCK; 280 break; 281 } 282 if (glock.type != P9_LOCK_TYPE_UNLCK) { 283 fl->fl_start = glock.start; 284 if (glock.length == 0) 285 fl->fl_end = OFFSET_MAX; 286 else 287 fl->fl_end = glock.start + glock.length - 1; 288 fl->fl_pid = glock.proc_id; 289 } 290 kfree(glock.client_id); 291 return res; 292 } 293 294 /** 295 * v9fs_file_lock_dotl - lock a file (or directory) 296 * @filp: file to be locked 297 * @cmd: lock command 298 * @fl: file lock structure 299 * 300 */ 301 302 static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl) 303 { 304 struct inode *inode = file_inode(filp); 305 int ret = -ENOLCK; 306 307 p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n", 308 filp, cmd, fl, filp); 309 310 /* No mandatory locks */ 311 if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) 312 goto out_err; 313 314 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { 315 filemap_write_and_wait(inode->i_mapping); 316 invalidate_mapping_pages(&inode->i_data, 0, -1); 317 } 318 319 if (IS_SETLK(cmd) || IS_SETLKW(cmd)) 320 ret = v9fs_file_do_lock(filp, cmd, fl); 321 else if (IS_GETLK(cmd)) 322 ret = v9fs_file_getlock(filp, fl); 323 else 324 ret = -EINVAL; 325 out_err: 326 return ret; 327 } 328 329 /** 330 * v9fs_file_flock_dotl - lock a file 331 * @filp: file to be locked 332 * @cmd: lock command 333 * @fl: file lock structure 334 * 335 */ 336 337 static int v9fs_file_flock_dotl(struct file *filp, int cmd, 338 struct file_lock *fl) 339 { 340 struct inode *inode = file_inode(filp); 341 int ret = -ENOLCK; 342 343 p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n", 344 filp, cmd, fl, filp); 345 346 /* No mandatory locks */ 347 if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK) 348 goto out_err; 349 350 if (!(fl->fl_flags & FL_FLOCK)) 351 goto out_err; 352 353 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { 354 filemap_write_and_wait(inode->i_mapping); 355 invalidate_mapping_pages(&inode->i_data, 0, -1); 356 } 357 /* Convert flock to posix lock */ 358 fl->fl_flags |= FL_POSIX; 359 fl->fl_flags ^= FL_FLOCK; 360 361 if (IS_SETLK(cmd) | IS_SETLKW(cmd)) 362 ret = v9fs_file_do_lock(filp, cmd, fl); 363 else 364 ret = -EINVAL; 365 out_err: 366 return ret; 367 } 368 369 /** 370 * v9fs_file_read - read from a file 371 * @filp: file pointer to read 372 * @udata: user data buffer to read data into 373 * @count: size of buffer 374 * @offset: offset at which to read data 375 * 376 */ 377 378 static ssize_t 379 v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) 380 { 381 struct p9_fid *fid = iocb->ki_filp->private_data; 382 int ret, err; 383 384 p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n", 385 iov_iter_count(to), iocb->ki_pos); 386 387 ret = p9_client_read(fid, iocb->ki_pos, to, &err); 388 if (!ret) 389 return err; 390 391 iocb->ki_pos += ret; 392 return ret; 393 } 394 395 /** 396 * v9fs_file_write - write to a file 397 * @filp: file pointer to write 398 * @data: data buffer to write data from 399 * @count: size of buffer 400 * @offset: offset at which to write data 401 * 402 */ 403 static ssize_t 404 v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) 405 { 406 struct file *file = iocb->ki_filp; 407 ssize_t retval = 0; 408 loff_t origin = iocb->ki_pos; 409 size_t count = iov_iter_count(from); 410 int err = 0; 411 412 retval = generic_write_checks(file, &origin, &count, 0); 413 if (retval) 414 return retval; 415 416 iov_iter_truncate(from, count); 417 418 if (!count) 419 return 0; 420 421 retval = p9_client_write(file->private_data, origin, from, &err); 422 if (retval > 0) { 423 struct inode *inode = file_inode(file); 424 loff_t i_size; 425 unsigned long pg_start, pg_end; 426 pg_start = origin >> PAGE_CACHE_SHIFT; 427 pg_end = (origin + retval - 1) >> PAGE_CACHE_SHIFT; 428 if (inode->i_mapping && inode->i_mapping->nrpages) 429 invalidate_inode_pages2_range(inode->i_mapping, 430 pg_start, pg_end); 431 origin += retval; 432 i_size = i_size_read(inode); 433 iocb->ki_pos = origin; 434 if (origin > i_size) { 435 inode_add_bytes(inode, origin - i_size); 436 i_size_write(inode, origin); 437 } 438 return retval; 439 } 440 return err; 441 } 442 443 static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end, 444 int datasync) 445 { 446 struct p9_fid *fid; 447 struct inode *inode = filp->f_mapping->host; 448 struct p9_wstat wstat; 449 int retval; 450 451 retval = filemap_write_and_wait_range(inode->i_mapping, start, end); 452 if (retval) 453 return retval; 454 455 mutex_lock(&inode->i_mutex); 456 p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync); 457 458 fid = filp->private_data; 459 v9fs_blank_wstat(&wstat); 460 461 retval = p9_client_wstat(fid, &wstat); 462 mutex_unlock(&inode->i_mutex); 463 464 return retval; 465 } 466 467 int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end, 468 int datasync) 469 { 470 struct p9_fid *fid; 471 struct inode *inode = filp->f_mapping->host; 472 int retval; 473 474 retval = filemap_write_and_wait_range(inode->i_mapping, start, end); 475 if (retval) 476 return retval; 477 478 mutex_lock(&inode->i_mutex); 479 p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync); 480 481 fid = filp->private_data; 482 483 retval = p9_client_fsync(fid, datasync); 484 mutex_unlock(&inode->i_mutex); 485 486 return retval; 487 } 488 489 static int 490 v9fs_file_mmap(struct file *filp, struct vm_area_struct *vma) 491 { 492 int retval; 493 494 495 retval = generic_file_mmap(filp, vma); 496 if (!retval) 497 vma->vm_ops = &v9fs_file_vm_ops; 498 499 return retval; 500 } 501 502 static int 503 v9fs_mmap_file_mmap(struct file *filp, struct vm_area_struct *vma) 504 { 505 int retval; 506 struct inode *inode; 507 struct v9fs_inode *v9inode; 508 struct p9_fid *fid; 509 510 inode = file_inode(filp); 511 v9inode = V9FS_I(inode); 512 mutex_lock(&v9inode->v_mutex); 513 if (!v9inode->writeback_fid && 514 (vma->vm_flags & VM_WRITE)) { 515 /* 516 * clone a fid and add it to writeback_fid 517 * we do it during mmap instead of 518 * page dirty time via write_begin/page_mkwrite 519 * because we want write after unlink usecase 520 * to work. 521 */ 522 fid = v9fs_writeback_fid(filp->f_path.dentry); 523 if (IS_ERR(fid)) { 524 retval = PTR_ERR(fid); 525 mutex_unlock(&v9inode->v_mutex); 526 return retval; 527 } 528 v9inode->writeback_fid = (void *) fid; 529 } 530 mutex_unlock(&v9inode->v_mutex); 531 532 retval = generic_file_mmap(filp, vma); 533 if (!retval) 534 vma->vm_ops = &v9fs_mmap_file_vm_ops; 535 536 return retval; 537 } 538 539 static int 540 v9fs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) 541 { 542 struct v9fs_inode *v9inode; 543 struct page *page = vmf->page; 544 struct file *filp = vma->vm_file; 545 struct inode *inode = file_inode(filp); 546 547 548 p9_debug(P9_DEBUG_VFS, "page %p fid %lx\n", 549 page, (unsigned long)filp->private_data); 550 551 /* Update file times before taking page lock */ 552 file_update_time(filp); 553 554 v9inode = V9FS_I(inode); 555 /* make sure the cache has finished storing the page */ 556 v9fs_fscache_wait_on_page_write(inode, page); 557 BUG_ON(!v9inode->writeback_fid); 558 lock_page(page); 559 if (page->mapping != inode->i_mapping) 560 goto out_unlock; 561 wait_for_stable_page(page); 562 563 return VM_FAULT_LOCKED; 564 out_unlock: 565 unlock_page(page); 566 return VM_FAULT_NOPAGE; 567 } 568 569 /** 570 * v9fs_mmap_file_read - read from a file 571 * @filp: file pointer to read 572 * @data: user data buffer to read data into 573 * @count: size of buffer 574 * @offset: offset at which to read data 575 * 576 */ 577 static ssize_t 578 v9fs_mmap_file_read_iter(struct kiocb *iocb, struct iov_iter *to) 579 { 580 /* TODO: Check if there are dirty pages */ 581 return v9fs_file_read_iter(iocb, to); 582 } 583 584 /** 585 * v9fs_mmap_file_write - write to a file 586 * @filp: file pointer to write 587 * @data: data buffer to write data from 588 * @count: size of buffer 589 * @offset: offset at which to write data 590 * 591 */ 592 static ssize_t 593 v9fs_mmap_file_write_iter(struct kiocb *iocb, struct iov_iter *from) 594 { 595 /* 596 * TODO: invalidate mmaps on filp's inode between 597 * offset and offset+count 598 */ 599 return v9fs_file_write_iter(iocb, from); 600 } 601 602 static void v9fs_mmap_vm_close(struct vm_area_struct *vma) 603 { 604 struct inode *inode; 605 606 struct writeback_control wbc = { 607 .nr_to_write = LONG_MAX, 608 .sync_mode = WB_SYNC_ALL, 609 .range_start = vma->vm_pgoff * PAGE_SIZE, 610 /* absolute end, byte at end included */ 611 .range_end = vma->vm_pgoff * PAGE_SIZE + 612 (vma->vm_end - vma->vm_start - 1), 613 }; 614 615 616 p9_debug(P9_DEBUG_VFS, "9p VMA close, %p, flushing", vma); 617 618 inode = file_inode(vma->vm_file); 619 620 if (!mapping_cap_writeback_dirty(inode->i_mapping)) 621 wbc.nr_to_write = 0; 622 623 might_sleep(); 624 sync_inode(inode, &wbc); 625 } 626 627 628 static const struct vm_operations_struct v9fs_file_vm_ops = { 629 .fault = filemap_fault, 630 .map_pages = filemap_map_pages, 631 .page_mkwrite = v9fs_vm_page_mkwrite, 632 }; 633 634 static const struct vm_operations_struct v9fs_mmap_file_vm_ops = { 635 .close = v9fs_mmap_vm_close, 636 .fault = filemap_fault, 637 .map_pages = filemap_map_pages, 638 .page_mkwrite = v9fs_vm_page_mkwrite, 639 }; 640 641 642 const struct file_operations v9fs_cached_file_operations = { 643 .llseek = generic_file_llseek, 644 .read_iter = generic_file_read_iter, 645 .write_iter = generic_file_write_iter, 646 .open = v9fs_file_open, 647 .release = v9fs_dir_release, 648 .lock = v9fs_file_lock, 649 .mmap = v9fs_file_mmap, 650 .fsync = v9fs_file_fsync, 651 }; 652 653 const struct file_operations v9fs_cached_file_operations_dotl = { 654 .llseek = generic_file_llseek, 655 .read_iter = generic_file_read_iter, 656 .write_iter = generic_file_write_iter, 657 .open = v9fs_file_open, 658 .release = v9fs_dir_release, 659 .lock = v9fs_file_lock_dotl, 660 .flock = v9fs_file_flock_dotl, 661 .mmap = v9fs_file_mmap, 662 .fsync = v9fs_file_fsync_dotl, 663 }; 664 665 const struct file_operations v9fs_file_operations = { 666 .llseek = generic_file_llseek, 667 .read_iter = v9fs_file_read_iter, 668 .write_iter = v9fs_file_write_iter, 669 .open = v9fs_file_open, 670 .release = v9fs_dir_release, 671 .lock = v9fs_file_lock, 672 .mmap = generic_file_readonly_mmap, 673 .fsync = v9fs_file_fsync, 674 }; 675 676 const struct file_operations v9fs_file_operations_dotl = { 677 .llseek = generic_file_llseek, 678 .read_iter = v9fs_file_read_iter, 679 .write_iter = v9fs_file_write_iter, 680 .open = v9fs_file_open, 681 .release = v9fs_dir_release, 682 .lock = v9fs_file_lock_dotl, 683 .flock = v9fs_file_flock_dotl, 684 .mmap = generic_file_readonly_mmap, 685 .fsync = v9fs_file_fsync_dotl, 686 }; 687 688 const struct file_operations v9fs_mmap_file_operations = { 689 .llseek = generic_file_llseek, 690 .read_iter = v9fs_mmap_file_read_iter, 691 .write_iter = v9fs_mmap_file_write_iter, 692 .open = v9fs_file_open, 693 .release = v9fs_dir_release, 694 .lock = v9fs_file_lock, 695 .mmap = v9fs_mmap_file_mmap, 696 .fsync = v9fs_file_fsync, 697 }; 698 699 const struct file_operations v9fs_mmap_file_operations_dotl = { 700 .llseek = generic_file_llseek, 701 .read_iter = v9fs_mmap_file_read_iter, 702 .write_iter = v9fs_mmap_file_write_iter, 703 .open = v9fs_file_open, 704 .release = v9fs_dir_release, 705 .lock = v9fs_file_lock_dotl, 706 .flock = v9fs_file_flock_dotl, 707 .mmap = v9fs_mmap_file_mmap, 708 .fsync = v9fs_file_fsync_dotl, 709 }; 710