1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * This file contians vfs file ops for 9P2000. 4 * 5 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 6 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 7 */ 8 9 #include <linux/module.h> 10 #include <linux/errno.h> 11 #include <linux/fs.h> 12 #include <linux/filelock.h> 13 #include <linux/sched.h> 14 #include <linux/file.h> 15 #include <linux/stat.h> 16 #include <linux/string.h> 17 #include <linux/list.h> 18 #include <linux/pagemap.h> 19 #include <linux/utsname.h> 20 #include <linux/uaccess.h> 21 #include <linux/uio.h> 22 #include <linux/slab.h> 23 #include <net/9p/9p.h> 24 #include <net/9p/client.h> 25 26 #include "v9fs.h" 27 #include "v9fs_vfs.h" 28 #include "fid.h" 29 #include "cache.h" 30 31 static const struct vm_operations_struct v9fs_mmap_file_vm_ops; 32 33 /** 34 * v9fs_file_open - open a file (or directory) 35 * @inode: inode to be opened 36 * @file: file being opened 37 * 38 */ 39 40 int v9fs_file_open(struct inode *inode, struct file *file) 41 { 42 int err; 43 struct v9fs_session_info *v9ses; 44 struct p9_fid *fid; 45 int omode; 46 47 p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file); 48 v9ses = v9fs_inode2v9ses(inode); 49 if (v9fs_proto_dotl(v9ses)) 50 omode = v9fs_open_to_dotl_flags(file->f_flags); 51 else 52 omode = v9fs_uflags2omode(file->f_flags, 53 v9fs_proto_dotu(v9ses)); 54 fid = file->private_data; 55 if (!fid) { 56 fid = v9fs_fid_clone(file_dentry(file)); 57 if (IS_ERR(fid)) 58 return PTR_ERR(fid); 59 60 if ((v9ses->cache & CACHE_WRITEBACK) && (omode & P9_OWRITE)) { 61 int writeback_omode = (omode & ~P9_OWRITE) | P9_ORDWR; 62 63 p9_debug(P9_DEBUG_CACHE, "write-only file with writeback enabled, try opening O_RDWR\n"); 64 err = p9_client_open(fid, writeback_omode); 65 if (err < 0) { 66 p9_debug(P9_DEBUG_CACHE, "could not open O_RDWR, disabling caches\n"); 67 err = p9_client_open(fid, omode); 68 fid->mode |= P9L_DIRECT; 69 } 70 } else { 71 err = p9_client_open(fid, omode); 72 } 73 if (err < 0) { 74 p9_fid_put(fid); 75 return err; 76 } 77 if ((file->f_flags & O_APPEND) && 78 (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses))) 79 generic_file_llseek(file, 0, SEEK_END); 80 81 file->private_data = fid; 82 } 83 84 #ifdef CONFIG_9P_FSCACHE 85 if (v9ses->cache & CACHE_FSCACHE) 86 fscache_use_cookie(v9fs_inode_cookie(V9FS_I(inode)), 87 file->f_mode & FMODE_WRITE); 88 #endif 89 v9fs_fid_add_modes(fid, v9ses->flags, v9ses->cache, file->f_flags); 90 v9fs_open_fid_add(inode, &fid); 91 return 0; 92 } 93 94 /** 95 * v9fs_file_lock - lock a file (or directory) 96 * @filp: file to be locked 97 * @cmd: lock command 98 * @fl: file lock structure 99 * 100 * Bugs: this looks like a local only lock, we should extend into 9P 101 * by using open exclusive 102 */ 103 104 static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl) 105 { 106 struct inode *inode = file_inode(filp); 107 108 p9_debug(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl); 109 110 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { 111 filemap_write_and_wait(inode->i_mapping); 112 invalidate_mapping_pages(&inode->i_data, 0, -1); 113 } 114 115 return 0; 116 } 117 118 static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl) 119 { 120 struct p9_flock flock; 121 struct p9_fid *fid; 122 uint8_t status = P9_LOCK_ERROR; 123 int res = 0; 124 unsigned char fl_type; 125 struct v9fs_session_info *v9ses; 126 127 fid = filp->private_data; 128 BUG_ON(fid == NULL); 129 130 BUG_ON((fl->fl_flags & FL_POSIX) != FL_POSIX); 131 132 res = locks_lock_file_wait(filp, fl); 133 if (res < 0) 134 goto out; 135 136 /* convert posix lock to p9 tlock args */ 137 memset(&flock, 0, sizeof(flock)); 138 /* map the lock type */ 139 switch (fl->fl_type) { 140 case F_RDLCK: 141 flock.type = P9_LOCK_TYPE_RDLCK; 142 break; 143 case F_WRLCK: 144 flock.type = P9_LOCK_TYPE_WRLCK; 145 break; 146 case F_UNLCK: 147 flock.type = P9_LOCK_TYPE_UNLCK; 148 break; 149 } 150 flock.start = fl->fl_start; 151 if (fl->fl_end == OFFSET_MAX) 152 flock.length = 0; 153 else 154 flock.length = fl->fl_end - fl->fl_start + 1; 155 flock.proc_id = fl->fl_pid; 156 flock.client_id = fid->clnt->name; 157 if (IS_SETLKW(cmd)) 158 flock.flags = P9_LOCK_FLAGS_BLOCK; 159 160 v9ses = v9fs_inode2v9ses(file_inode(filp)); 161 162 /* 163 * if its a blocked request and we get P9_LOCK_BLOCKED as the status 164 * for lock request, keep on trying 165 */ 166 for (;;) { 167 res = p9_client_lock_dotl(fid, &flock, &status); 168 if (res < 0) 169 goto out_unlock; 170 171 if (status != P9_LOCK_BLOCKED) 172 break; 173 if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd)) 174 break; 175 if (schedule_timeout_interruptible(v9ses->session_lock_timeout) 176 != 0) 177 break; 178 /* 179 * p9_client_lock_dotl overwrites flock.client_id with the 180 * server message, free and reuse the client name 181 */ 182 if (flock.client_id != fid->clnt->name) { 183 kfree(flock.client_id); 184 flock.client_id = fid->clnt->name; 185 } 186 } 187 188 /* map 9p status to VFS status */ 189 switch (status) { 190 case P9_LOCK_SUCCESS: 191 res = 0; 192 break; 193 case P9_LOCK_BLOCKED: 194 res = -EAGAIN; 195 break; 196 default: 197 WARN_ONCE(1, "unknown lock status code: %d\n", status); 198 fallthrough; 199 case P9_LOCK_ERROR: 200 case P9_LOCK_GRACE: 201 res = -ENOLCK; 202 break; 203 } 204 205 out_unlock: 206 /* 207 * incase server returned error for lock request, revert 208 * it locally 209 */ 210 if (res < 0 && fl->fl_type != F_UNLCK) { 211 fl_type = fl->fl_type; 212 fl->fl_type = F_UNLCK; 213 /* Even if this fails we want to return the remote error */ 214 locks_lock_file_wait(filp, fl); 215 fl->fl_type = fl_type; 216 } 217 if (flock.client_id != fid->clnt->name) 218 kfree(flock.client_id); 219 out: 220 return res; 221 } 222 223 static int v9fs_file_getlock(struct file *filp, struct file_lock *fl) 224 { 225 struct p9_getlock glock; 226 struct p9_fid *fid; 227 int res = 0; 228 229 fid = filp->private_data; 230 BUG_ON(fid == NULL); 231 232 posix_test_lock(filp, fl); 233 /* 234 * if we have a conflicting lock locally, no need to validate 235 * with server 236 */ 237 if (fl->fl_type != F_UNLCK) 238 return res; 239 240 /* convert posix lock to p9 tgetlock args */ 241 memset(&glock, 0, sizeof(glock)); 242 glock.type = P9_LOCK_TYPE_UNLCK; 243 glock.start = fl->fl_start; 244 if (fl->fl_end == OFFSET_MAX) 245 glock.length = 0; 246 else 247 glock.length = fl->fl_end - fl->fl_start + 1; 248 glock.proc_id = fl->fl_pid; 249 glock.client_id = fid->clnt->name; 250 251 res = p9_client_getlock_dotl(fid, &glock); 252 if (res < 0) 253 goto out; 254 /* map 9p lock type to os lock type */ 255 switch (glock.type) { 256 case P9_LOCK_TYPE_RDLCK: 257 fl->fl_type = F_RDLCK; 258 break; 259 case P9_LOCK_TYPE_WRLCK: 260 fl->fl_type = F_WRLCK; 261 break; 262 case P9_LOCK_TYPE_UNLCK: 263 fl->fl_type = F_UNLCK; 264 break; 265 } 266 if (glock.type != P9_LOCK_TYPE_UNLCK) { 267 fl->fl_start = glock.start; 268 if (glock.length == 0) 269 fl->fl_end = OFFSET_MAX; 270 else 271 fl->fl_end = glock.start + glock.length - 1; 272 fl->fl_pid = -glock.proc_id; 273 } 274 out: 275 if (glock.client_id != fid->clnt->name) 276 kfree(glock.client_id); 277 return res; 278 } 279 280 /** 281 * v9fs_file_lock_dotl - lock a file (or directory) 282 * @filp: file to be locked 283 * @cmd: lock command 284 * @fl: file lock structure 285 * 286 */ 287 288 static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl) 289 { 290 struct inode *inode = file_inode(filp); 291 int ret = -ENOLCK; 292 293 p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n", 294 filp, cmd, fl, filp); 295 296 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { 297 filemap_write_and_wait(inode->i_mapping); 298 invalidate_mapping_pages(&inode->i_data, 0, -1); 299 } 300 301 if (IS_SETLK(cmd) || IS_SETLKW(cmd)) 302 ret = v9fs_file_do_lock(filp, cmd, fl); 303 else if (IS_GETLK(cmd)) 304 ret = v9fs_file_getlock(filp, fl); 305 else 306 ret = -EINVAL; 307 return ret; 308 } 309 310 /** 311 * v9fs_file_flock_dotl - lock a file 312 * @filp: file to be locked 313 * @cmd: lock command 314 * @fl: file lock structure 315 * 316 */ 317 318 static int v9fs_file_flock_dotl(struct file *filp, int cmd, 319 struct file_lock *fl) 320 { 321 struct inode *inode = file_inode(filp); 322 int ret = -ENOLCK; 323 324 p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n", 325 filp, cmd, fl, filp); 326 327 if (!(fl->fl_flags & FL_FLOCK)) 328 goto out_err; 329 330 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) { 331 filemap_write_and_wait(inode->i_mapping); 332 invalidate_mapping_pages(&inode->i_data, 0, -1); 333 } 334 /* Convert flock to posix lock */ 335 fl->fl_flags |= FL_POSIX; 336 fl->fl_flags ^= FL_FLOCK; 337 338 if (IS_SETLK(cmd) | IS_SETLKW(cmd)) 339 ret = v9fs_file_do_lock(filp, cmd, fl); 340 else 341 ret = -EINVAL; 342 out_err: 343 return ret; 344 } 345 346 /** 347 * v9fs_file_read_iter - read from a file 348 * @iocb: The operation parameters 349 * @to: The buffer to read into 350 * 351 */ 352 static ssize_t 353 v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) 354 { 355 struct p9_fid *fid = iocb->ki_filp->private_data; 356 int ret, err = 0; 357 358 p9_debug(P9_DEBUG_VFS, "fid %d count %zu offset %lld\n", 359 fid->fid, iov_iter_count(to), iocb->ki_pos); 360 361 if (!(fid->mode & P9L_DIRECT)) { 362 p9_debug(P9_DEBUG_VFS, "(cached)\n"); 363 return generic_file_read_iter(iocb, to); 364 } 365 366 if (iocb->ki_filp->f_flags & O_NONBLOCK) 367 ret = p9_client_read_once(fid, iocb->ki_pos, to, &err); 368 else 369 ret = p9_client_read(fid, iocb->ki_pos, to, &err); 370 if (!ret) 371 return err; 372 373 iocb->ki_pos += ret; 374 return ret; 375 } 376 377 /** 378 * v9fs_file_write_iter - write to a file 379 * @iocb: The operation parameters 380 * @from: The data to write 381 * 382 */ 383 static ssize_t 384 v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) 385 { 386 struct file *file = iocb->ki_filp; 387 struct p9_fid *fid = file->private_data; 388 ssize_t retval; 389 loff_t origin; 390 int err = 0; 391 392 p9_debug(P9_DEBUG_VFS, "fid %d\n", fid->fid); 393 394 if (!(fid->mode & (P9L_DIRECT | P9L_NOWRITECACHE))) { 395 p9_debug(P9_DEBUG_CACHE, "(cached)\n"); 396 return generic_file_write_iter(iocb, from); 397 } 398 399 retval = generic_write_checks(iocb, from); 400 if (retval <= 0) 401 return retval; 402 403 origin = iocb->ki_pos; 404 retval = p9_client_write(file->private_data, iocb->ki_pos, from, &err); 405 if (retval > 0) { 406 struct inode *inode = file_inode(file); 407 loff_t i_size; 408 unsigned long pg_start, pg_end; 409 410 pg_start = origin >> PAGE_SHIFT; 411 pg_end = (origin + retval - 1) >> PAGE_SHIFT; 412 if (inode->i_mapping && inode->i_mapping->nrpages) 413 invalidate_inode_pages2_range(inode->i_mapping, 414 pg_start, pg_end); 415 iocb->ki_pos += retval; 416 i_size = i_size_read(inode); 417 if (iocb->ki_pos > i_size) { 418 inode_add_bytes(inode, iocb->ki_pos - i_size); 419 /* 420 * Need to serialize against i_size_write() in 421 * v9fs_stat2inode() 422 */ 423 v9fs_i_size_write(inode, iocb->ki_pos); 424 } 425 return retval; 426 } 427 return err; 428 } 429 430 static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end, 431 int datasync) 432 { 433 struct p9_fid *fid; 434 struct inode *inode = filp->f_mapping->host; 435 struct p9_wstat wstat; 436 int retval; 437 438 retval = file_write_and_wait_range(filp, start, end); 439 if (retval) 440 return retval; 441 442 inode_lock(inode); 443 p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync); 444 445 fid = filp->private_data; 446 v9fs_blank_wstat(&wstat); 447 448 retval = p9_client_wstat(fid, &wstat); 449 inode_unlock(inode); 450 451 return retval; 452 } 453 454 int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end, 455 int datasync) 456 { 457 struct p9_fid *fid; 458 struct inode *inode = filp->f_mapping->host; 459 int retval; 460 461 retval = file_write_and_wait_range(filp, start, end); 462 if (retval) 463 return retval; 464 465 inode_lock(inode); 466 p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync); 467 468 fid = filp->private_data; 469 470 retval = p9_client_fsync(fid, datasync); 471 inode_unlock(inode); 472 473 return retval; 474 } 475 476 static int 477 v9fs_file_mmap(struct file *filp, struct vm_area_struct *vma) 478 { 479 int retval; 480 struct inode *inode = file_inode(filp); 481 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); 482 483 p9_debug(P9_DEBUG_MMAP, "filp :%p\n", filp); 484 485 if (!(v9ses->cache & CACHE_WRITEBACK)) { 486 p9_debug(P9_DEBUG_CACHE, "(no mmap mode)"); 487 if (vma->vm_flags & VM_MAYSHARE) 488 return -ENODEV; 489 invalidate_inode_pages2(filp->f_mapping); 490 return generic_file_readonly_mmap(filp, vma); 491 } 492 493 retval = generic_file_mmap(filp, vma); 494 if (!retval) 495 vma->vm_ops = &v9fs_mmap_file_vm_ops; 496 497 return retval; 498 } 499 500 static vm_fault_t 501 v9fs_vm_page_mkwrite(struct vm_fault *vmf) 502 { 503 struct folio *folio = page_folio(vmf->page); 504 struct file *filp = vmf->vma->vm_file; 505 struct inode *inode = file_inode(filp); 506 507 508 p9_debug(P9_DEBUG_VFS, "folio %p fid %lx\n", 509 folio, (unsigned long)filp->private_data); 510 511 /* Wait for the page to be written to the cache before we allow it to 512 * be modified. We then assume the entire page will need writing back. 513 */ 514 #ifdef CONFIG_9P_FSCACHE 515 if (folio_test_fscache(folio) && 516 folio_wait_fscache_killable(folio) < 0) 517 return VM_FAULT_NOPAGE; 518 #endif 519 520 /* Update file times before taking page lock */ 521 file_update_time(filp); 522 523 if (folio_lock_killable(folio) < 0) 524 return VM_FAULT_RETRY; 525 if (folio_mapping(folio) != inode->i_mapping) 526 goto out_unlock; 527 folio_wait_stable(folio); 528 529 return VM_FAULT_LOCKED; 530 out_unlock: 531 folio_unlock(folio); 532 return VM_FAULT_NOPAGE; 533 } 534 535 static void v9fs_mmap_vm_close(struct vm_area_struct *vma) 536 { 537 struct inode *inode; 538 539 struct writeback_control wbc = { 540 .nr_to_write = LONG_MAX, 541 .sync_mode = WB_SYNC_ALL, 542 .range_start = (loff_t)vma->vm_pgoff * PAGE_SIZE, 543 /* absolute end, byte at end included */ 544 .range_end = (loff_t)vma->vm_pgoff * PAGE_SIZE + 545 (vma->vm_end - vma->vm_start - 1), 546 }; 547 548 if (!(vma->vm_flags & VM_SHARED)) 549 return; 550 551 p9_debug(P9_DEBUG_VFS, "9p VMA close, %p, flushing", vma); 552 553 inode = file_inode(vma->vm_file); 554 filemap_fdatawrite_wbc(inode->i_mapping, &wbc); 555 } 556 557 static const struct vm_operations_struct v9fs_mmap_file_vm_ops = { 558 .close = v9fs_mmap_vm_close, 559 .fault = filemap_fault, 560 .map_pages = filemap_map_pages, 561 .page_mkwrite = v9fs_vm_page_mkwrite, 562 }; 563 564 const struct file_operations v9fs_file_operations = { 565 .llseek = generic_file_llseek, 566 .read_iter = v9fs_file_read_iter, 567 .write_iter = v9fs_file_write_iter, 568 .open = v9fs_file_open, 569 .release = v9fs_dir_release, 570 .lock = v9fs_file_lock, 571 .mmap = generic_file_readonly_mmap, 572 .splice_read = generic_file_splice_read, 573 .splice_write = iter_file_splice_write, 574 .fsync = v9fs_file_fsync, 575 }; 576 577 const struct file_operations v9fs_file_operations_dotl = { 578 .llseek = generic_file_llseek, 579 .read_iter = v9fs_file_read_iter, 580 .write_iter = v9fs_file_write_iter, 581 .open = v9fs_file_open, 582 .release = v9fs_dir_release, 583 .lock = v9fs_file_lock_dotl, 584 .flock = v9fs_file_flock_dotl, 585 .mmap = v9fs_file_mmap, 586 .splice_read = generic_file_splice_read, 587 .splice_write = iter_file_splice_write, 588 .fsync = v9fs_file_fsync_dotl, 589 }; 590