0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/errno.h>
0011 #include <linux/fs.h>
0012 #include <linux/sched.h>
0013 #include <linux/file.h>
0014 #include <linux/stat.h>
0015 #include <linux/string.h>
0016 #include <linux/inet.h>
0017 #include <linux/list.h>
0018 #include <linux/pagemap.h>
0019 #include <linux/utsname.h>
0020 #include <linux/uaccess.h>
0021 #include <linux/idr.h>
0022 #include <linux/uio.h>
0023 #include <linux/slab.h>
0024 #include <net/9p/9p.h>
0025 #include <net/9p/client.h>
0026
0027 #include "v9fs.h"
0028 #include "v9fs_vfs.h"
0029 #include "fid.h"
0030 #include "cache.h"
0031
0032 static const struct vm_operations_struct v9fs_file_vm_ops;
0033 static const struct vm_operations_struct v9fs_mmap_file_vm_ops;
0034
0035
0036
0037
0038
0039
0040
0041
0042 int v9fs_file_open(struct inode *inode, struct file *file)
0043 {
0044 int err;
0045 struct v9fs_inode *v9inode;
0046 struct v9fs_session_info *v9ses;
0047 struct p9_fid *fid, *writeback_fid;
0048 int omode;
0049
0050 p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file);
0051 v9inode = V9FS_I(inode);
0052 v9ses = v9fs_inode2v9ses(inode);
0053 if (v9fs_proto_dotl(v9ses))
0054 omode = v9fs_open_to_dotl_flags(file->f_flags);
0055 else
0056 omode = v9fs_uflags2omode(file->f_flags,
0057 v9fs_proto_dotu(v9ses));
0058 fid = file->private_data;
0059 if (!fid) {
0060 fid = v9fs_fid_clone(file_dentry(file));
0061 if (IS_ERR(fid))
0062 return PTR_ERR(fid);
0063
0064 err = p9_client_open(fid, omode);
0065 if (err < 0) {
0066 p9_fid_put(fid);
0067 return err;
0068 }
0069 if ((file->f_flags & O_APPEND) &&
0070 (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)))
0071 generic_file_llseek(file, 0, SEEK_END);
0072
0073 file->private_data = fid;
0074 }
0075
0076 mutex_lock(&v9inode->v_mutex);
0077 if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
0078 !v9inode->writeback_fid &&
0079 ((file->f_flags & O_ACCMODE) != O_RDONLY)) {
0080
0081
0082
0083
0084
0085
0086
0087 writeback_fid = v9fs_writeback_fid(file_dentry(file));
0088 if (IS_ERR(writeback_fid)) {
0089 err = PTR_ERR(writeback_fid);
0090 mutex_unlock(&v9inode->v_mutex);
0091 goto out_error;
0092 }
0093 v9inode->writeback_fid = (void *) writeback_fid;
0094 }
0095 mutex_unlock(&v9inode->v_mutex);
0096 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
0097 fscache_use_cookie(v9fs_inode_cookie(v9inode),
0098 file->f_mode & FMODE_WRITE);
0099 v9fs_open_fid_add(inode, &fid);
0100 return 0;
0101 out_error:
0102 p9_fid_put(file->private_data);
0103 file->private_data = NULL;
0104 return err;
0105 }
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
0118 {
0119 struct inode *inode = file_inode(filp);
0120
0121 p9_debug(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
0122
0123 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
0124 filemap_write_and_wait(inode->i_mapping);
0125 invalidate_mapping_pages(&inode->i_data, 0, -1);
0126 }
0127
0128 return 0;
0129 }
0130
0131 static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
0132 {
0133 struct p9_flock flock;
0134 struct p9_fid *fid;
0135 uint8_t status = P9_LOCK_ERROR;
0136 int res = 0;
0137 unsigned char fl_type;
0138 struct v9fs_session_info *v9ses;
0139
0140 fid = filp->private_data;
0141 BUG_ON(fid == NULL);
0142
0143 BUG_ON((fl->fl_flags & FL_POSIX) != FL_POSIX);
0144
0145 res = locks_lock_file_wait(filp, fl);
0146 if (res < 0)
0147 goto out;
0148
0149
0150 memset(&flock, 0, sizeof(flock));
0151
0152 switch (fl->fl_type) {
0153 case F_RDLCK:
0154 flock.type = P9_LOCK_TYPE_RDLCK;
0155 break;
0156 case F_WRLCK:
0157 flock.type = P9_LOCK_TYPE_WRLCK;
0158 break;
0159 case F_UNLCK:
0160 flock.type = P9_LOCK_TYPE_UNLCK;
0161 break;
0162 }
0163 flock.start = fl->fl_start;
0164 if (fl->fl_end == OFFSET_MAX)
0165 flock.length = 0;
0166 else
0167 flock.length = fl->fl_end - fl->fl_start + 1;
0168 flock.proc_id = fl->fl_pid;
0169 flock.client_id = fid->clnt->name;
0170 if (IS_SETLKW(cmd))
0171 flock.flags = P9_LOCK_FLAGS_BLOCK;
0172
0173 v9ses = v9fs_inode2v9ses(file_inode(filp));
0174
0175
0176
0177
0178
0179 for (;;) {
0180 res = p9_client_lock_dotl(fid, &flock, &status);
0181 if (res < 0)
0182 goto out_unlock;
0183
0184 if (status != P9_LOCK_BLOCKED)
0185 break;
0186 if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd))
0187 break;
0188 if (schedule_timeout_interruptible(v9ses->session_lock_timeout)
0189 != 0)
0190 break;
0191
0192
0193
0194
0195 if (flock.client_id != fid->clnt->name) {
0196 kfree(flock.client_id);
0197 flock.client_id = fid->clnt->name;
0198 }
0199 }
0200
0201
0202 switch (status) {
0203 case P9_LOCK_SUCCESS:
0204 res = 0;
0205 break;
0206 case P9_LOCK_BLOCKED:
0207 res = -EAGAIN;
0208 break;
0209 default:
0210 WARN_ONCE(1, "unknown lock status code: %d\n", status);
0211 fallthrough;
0212 case P9_LOCK_ERROR:
0213 case P9_LOCK_GRACE:
0214 res = -ENOLCK;
0215 break;
0216 }
0217
0218 out_unlock:
0219
0220
0221
0222
0223 if (res < 0 && fl->fl_type != F_UNLCK) {
0224 fl_type = fl->fl_type;
0225 fl->fl_type = F_UNLCK;
0226
0227 locks_lock_file_wait(filp, fl);
0228 fl->fl_type = fl_type;
0229 }
0230 if (flock.client_id != fid->clnt->name)
0231 kfree(flock.client_id);
0232 out:
0233 return res;
0234 }
0235
0236 static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
0237 {
0238 struct p9_getlock glock;
0239 struct p9_fid *fid;
0240 int res = 0;
0241
0242 fid = filp->private_data;
0243 BUG_ON(fid == NULL);
0244
0245 posix_test_lock(filp, fl);
0246
0247
0248
0249
0250 if (fl->fl_type != F_UNLCK)
0251 return res;
0252
0253
0254 memset(&glock, 0, sizeof(glock));
0255 glock.type = P9_LOCK_TYPE_UNLCK;
0256 glock.start = fl->fl_start;
0257 if (fl->fl_end == OFFSET_MAX)
0258 glock.length = 0;
0259 else
0260 glock.length = fl->fl_end - fl->fl_start + 1;
0261 glock.proc_id = fl->fl_pid;
0262 glock.client_id = fid->clnt->name;
0263
0264 res = p9_client_getlock_dotl(fid, &glock);
0265 if (res < 0)
0266 goto out;
0267
0268 switch (glock.type) {
0269 case P9_LOCK_TYPE_RDLCK:
0270 fl->fl_type = F_RDLCK;
0271 break;
0272 case P9_LOCK_TYPE_WRLCK:
0273 fl->fl_type = F_WRLCK;
0274 break;
0275 case P9_LOCK_TYPE_UNLCK:
0276 fl->fl_type = F_UNLCK;
0277 break;
0278 }
0279 if (glock.type != P9_LOCK_TYPE_UNLCK) {
0280 fl->fl_start = glock.start;
0281 if (glock.length == 0)
0282 fl->fl_end = OFFSET_MAX;
0283 else
0284 fl->fl_end = glock.start + glock.length - 1;
0285 fl->fl_pid = -glock.proc_id;
0286 }
0287 out:
0288 if (glock.client_id != fid->clnt->name)
0289 kfree(glock.client_id);
0290 return res;
0291 }
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl)
0302 {
0303 struct inode *inode = file_inode(filp);
0304 int ret = -ENOLCK;
0305
0306 p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n",
0307 filp, cmd, fl, filp);
0308
0309 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
0310 filemap_write_and_wait(inode->i_mapping);
0311 invalidate_mapping_pages(&inode->i_data, 0, -1);
0312 }
0313
0314 if (IS_SETLK(cmd) || IS_SETLKW(cmd))
0315 ret = v9fs_file_do_lock(filp, cmd, fl);
0316 else if (IS_GETLK(cmd))
0317 ret = v9fs_file_getlock(filp, fl);
0318 else
0319 ret = -EINVAL;
0320 return ret;
0321 }
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331 static int v9fs_file_flock_dotl(struct file *filp, int cmd,
0332 struct file_lock *fl)
0333 {
0334 struct inode *inode = file_inode(filp);
0335 int ret = -ENOLCK;
0336
0337 p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n",
0338 filp, cmd, fl, filp);
0339
0340 if (!(fl->fl_flags & FL_FLOCK))
0341 goto out_err;
0342
0343 if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
0344 filemap_write_and_wait(inode->i_mapping);
0345 invalidate_mapping_pages(&inode->i_data, 0, -1);
0346 }
0347
0348 fl->fl_flags |= FL_POSIX;
0349 fl->fl_flags ^= FL_FLOCK;
0350
0351 if (IS_SETLK(cmd) | IS_SETLKW(cmd))
0352 ret = v9fs_file_do_lock(filp, cmd, fl);
0353 else
0354 ret = -EINVAL;
0355 out_err:
0356 return ret;
0357 }
0358
0359
0360
0361
0362
0363
0364
0365 static ssize_t
0366 v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
0367 {
0368 struct p9_fid *fid = iocb->ki_filp->private_data;
0369 int ret, err = 0;
0370
0371 p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n",
0372 iov_iter_count(to), iocb->ki_pos);
0373
0374 if (iocb->ki_filp->f_flags & O_NONBLOCK)
0375 ret = p9_client_read_once(fid, iocb->ki_pos, to, &err);
0376 else
0377 ret = p9_client_read(fid, iocb->ki_pos, to, &err);
0378 if (!ret)
0379 return err;
0380
0381 iocb->ki_pos += ret;
0382 return ret;
0383 }
0384
0385
0386
0387
0388
0389
0390
0391 static ssize_t
0392 v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
0393 {
0394 struct file *file = iocb->ki_filp;
0395 ssize_t retval;
0396 loff_t origin;
0397 int err = 0;
0398
0399 retval = generic_write_checks(iocb, from);
0400 if (retval <= 0)
0401 return retval;
0402
0403 origin = iocb->ki_pos;
0404 retval = p9_client_write(file->private_data, iocb->ki_pos, from, &err);
0405 if (retval > 0) {
0406 struct inode *inode = file_inode(file);
0407 loff_t i_size;
0408 unsigned long pg_start, pg_end;
0409
0410 pg_start = origin >> PAGE_SHIFT;
0411 pg_end = (origin + retval - 1) >> PAGE_SHIFT;
0412 if (inode->i_mapping && inode->i_mapping->nrpages)
0413 invalidate_inode_pages2_range(inode->i_mapping,
0414 pg_start, pg_end);
0415 iocb->ki_pos += retval;
0416 i_size = i_size_read(inode);
0417 if (iocb->ki_pos > i_size) {
0418 inode_add_bytes(inode, iocb->ki_pos - i_size);
0419
0420
0421
0422
0423 v9fs_i_size_write(inode, iocb->ki_pos);
0424 }
0425 return retval;
0426 }
0427 return err;
0428 }
0429
0430 static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end,
0431 int datasync)
0432 {
0433 struct p9_fid *fid;
0434 struct inode *inode = filp->f_mapping->host;
0435 struct p9_wstat wstat;
0436 int retval;
0437
0438 retval = file_write_and_wait_range(filp, start, end);
0439 if (retval)
0440 return retval;
0441
0442 inode_lock(inode);
0443 p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
0444
0445 fid = filp->private_data;
0446 v9fs_blank_wstat(&wstat);
0447
0448 retval = p9_client_wstat(fid, &wstat);
0449 inode_unlock(inode);
0450
0451 return retval;
0452 }
0453
0454 int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
0455 int datasync)
0456 {
0457 struct p9_fid *fid;
0458 struct inode *inode = filp->f_mapping->host;
0459 int retval;
0460
0461 retval = file_write_and_wait_range(filp, start, end);
0462 if (retval)
0463 return retval;
0464
0465 inode_lock(inode);
0466 p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
0467
0468 fid = filp->private_data;
0469
0470 retval = p9_client_fsync(fid, datasync);
0471 inode_unlock(inode);
0472
0473 return retval;
0474 }
0475
0476 static int
0477 v9fs_file_mmap(struct file *filp, struct vm_area_struct *vma)
0478 {
0479 int retval;
0480
0481
0482 retval = generic_file_mmap(filp, vma);
0483 if (!retval)
0484 vma->vm_ops = &v9fs_file_vm_ops;
0485
0486 return retval;
0487 }
0488
0489 static int
0490 v9fs_mmap_file_mmap(struct file *filp, struct vm_area_struct *vma)
0491 {
0492 int retval;
0493 struct inode *inode;
0494 struct v9fs_inode *v9inode;
0495 struct p9_fid *fid;
0496
0497 inode = file_inode(filp);
0498 v9inode = V9FS_I(inode);
0499 mutex_lock(&v9inode->v_mutex);
0500 if (!v9inode->writeback_fid &&
0501 (vma->vm_flags & VM_SHARED) &&
0502 (vma->vm_flags & VM_WRITE)) {
0503
0504
0505
0506
0507
0508
0509
0510 fid = v9fs_writeback_fid(file_dentry(filp));
0511 if (IS_ERR(fid)) {
0512 retval = PTR_ERR(fid);
0513 mutex_unlock(&v9inode->v_mutex);
0514 return retval;
0515 }
0516 v9inode->writeback_fid = (void *) fid;
0517 }
0518 mutex_unlock(&v9inode->v_mutex);
0519
0520 retval = generic_file_mmap(filp, vma);
0521 if (!retval)
0522 vma->vm_ops = &v9fs_mmap_file_vm_ops;
0523
0524 return retval;
0525 }
0526
0527 static vm_fault_t
0528 v9fs_vm_page_mkwrite(struct vm_fault *vmf)
0529 {
0530 struct v9fs_inode *v9inode;
0531 struct folio *folio = page_folio(vmf->page);
0532 struct file *filp = vmf->vma->vm_file;
0533 struct inode *inode = file_inode(filp);
0534
0535
0536 p9_debug(P9_DEBUG_VFS, "folio %p fid %lx\n",
0537 folio, (unsigned long)filp->private_data);
0538
0539 v9inode = V9FS_I(inode);
0540
0541
0542
0543
0544 #ifdef CONFIG_9P_FSCACHE
0545 if (folio_test_fscache(folio) &&
0546 folio_wait_fscache_killable(folio) < 0)
0547 return VM_FAULT_NOPAGE;
0548 #endif
0549
0550
0551 file_update_time(filp);
0552
0553 BUG_ON(!v9inode->writeback_fid);
0554 if (folio_lock_killable(folio) < 0)
0555 return VM_FAULT_RETRY;
0556 if (folio_mapping(folio) != inode->i_mapping)
0557 goto out_unlock;
0558 folio_wait_stable(folio);
0559
0560 return VM_FAULT_LOCKED;
0561 out_unlock:
0562 folio_unlock(folio);
0563 return VM_FAULT_NOPAGE;
0564 }
0565
0566
0567
0568
0569
0570
0571
0572 static ssize_t
0573 v9fs_mmap_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
0574 {
0575
0576 return v9fs_file_read_iter(iocb, to);
0577 }
0578
0579
0580
0581
0582
0583
0584
0585 static ssize_t
0586 v9fs_mmap_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
0587 {
0588
0589
0590
0591
0592 return v9fs_file_write_iter(iocb, from);
0593 }
0594
0595 static void v9fs_mmap_vm_close(struct vm_area_struct *vma)
0596 {
0597 struct inode *inode;
0598
0599 struct writeback_control wbc = {
0600 .nr_to_write = LONG_MAX,
0601 .sync_mode = WB_SYNC_ALL,
0602 .range_start = (loff_t)vma->vm_pgoff * PAGE_SIZE,
0603
0604 .range_end = (loff_t)vma->vm_pgoff * PAGE_SIZE +
0605 (vma->vm_end - vma->vm_start - 1),
0606 };
0607
0608 if (!(vma->vm_flags & VM_SHARED))
0609 return;
0610
0611 p9_debug(P9_DEBUG_VFS, "9p VMA close, %p, flushing", vma);
0612
0613 inode = file_inode(vma->vm_file);
0614 filemap_fdatawrite_wbc(inode->i_mapping, &wbc);
0615 }
0616
0617
0618 static const struct vm_operations_struct v9fs_file_vm_ops = {
0619 .fault = filemap_fault,
0620 .map_pages = filemap_map_pages,
0621 .page_mkwrite = v9fs_vm_page_mkwrite,
0622 };
0623
0624 static const struct vm_operations_struct v9fs_mmap_file_vm_ops = {
0625 .close = v9fs_mmap_vm_close,
0626 .fault = filemap_fault,
0627 .map_pages = filemap_map_pages,
0628 .page_mkwrite = v9fs_vm_page_mkwrite,
0629 };
0630
0631
0632 const struct file_operations v9fs_cached_file_operations = {
0633 .llseek = generic_file_llseek,
0634 .read_iter = generic_file_read_iter,
0635 .write_iter = generic_file_write_iter,
0636 .open = v9fs_file_open,
0637 .release = v9fs_dir_release,
0638 .lock = v9fs_file_lock,
0639 .mmap = v9fs_file_mmap,
0640 .splice_read = generic_file_splice_read,
0641 .splice_write = iter_file_splice_write,
0642 .fsync = v9fs_file_fsync,
0643 };
0644
0645 const struct file_operations v9fs_cached_file_operations_dotl = {
0646 .llseek = generic_file_llseek,
0647 .read_iter = generic_file_read_iter,
0648 .write_iter = generic_file_write_iter,
0649 .open = v9fs_file_open,
0650 .release = v9fs_dir_release,
0651 .lock = v9fs_file_lock_dotl,
0652 .flock = v9fs_file_flock_dotl,
0653 .mmap = v9fs_file_mmap,
0654 .splice_read = generic_file_splice_read,
0655 .splice_write = iter_file_splice_write,
0656 .fsync = v9fs_file_fsync_dotl,
0657 };
0658
0659 const struct file_operations v9fs_file_operations = {
0660 .llseek = generic_file_llseek,
0661 .read_iter = v9fs_file_read_iter,
0662 .write_iter = v9fs_file_write_iter,
0663 .open = v9fs_file_open,
0664 .release = v9fs_dir_release,
0665 .lock = v9fs_file_lock,
0666 .mmap = generic_file_readonly_mmap,
0667 .splice_read = generic_file_splice_read,
0668 .splice_write = iter_file_splice_write,
0669 .fsync = v9fs_file_fsync,
0670 };
0671
0672 const struct file_operations v9fs_file_operations_dotl = {
0673 .llseek = generic_file_llseek,
0674 .read_iter = v9fs_file_read_iter,
0675 .write_iter = v9fs_file_write_iter,
0676 .open = v9fs_file_open,
0677 .release = v9fs_dir_release,
0678 .lock = v9fs_file_lock_dotl,
0679 .flock = v9fs_file_flock_dotl,
0680 .mmap = generic_file_readonly_mmap,
0681 .splice_read = generic_file_splice_read,
0682 .splice_write = iter_file_splice_write,
0683 .fsync = v9fs_file_fsync_dotl,
0684 };
0685
0686 const struct file_operations v9fs_mmap_file_operations = {
0687 .llseek = generic_file_llseek,
0688 .read_iter = v9fs_mmap_file_read_iter,
0689 .write_iter = v9fs_mmap_file_write_iter,
0690 .open = v9fs_file_open,
0691 .release = v9fs_dir_release,
0692 .lock = v9fs_file_lock,
0693 .mmap = v9fs_mmap_file_mmap,
0694 .splice_read = generic_file_splice_read,
0695 .splice_write = iter_file_splice_write,
0696 .fsync = v9fs_file_fsync,
0697 };
0698
0699 const struct file_operations v9fs_mmap_file_operations_dotl = {
0700 .llseek = generic_file_llseek,
0701 .read_iter = v9fs_mmap_file_read_iter,
0702 .write_iter = v9fs_mmap_file_write_iter,
0703 .open = v9fs_file_open,
0704 .release = v9fs_dir_release,
0705 .lock = v9fs_file_lock_dotl,
0706 .flock = v9fs_file_flock_dotl,
0707 .mmap = v9fs_mmap_file_mmap,
0708 .splice_read = generic_file_splice_read,
0709 .splice_write = iter_file_splice_write,
0710 .fsync = v9fs_file_fsync_dotl,
0711 };