Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vfs_file.c
Go to the documentation of this file.
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 <[email protected]>
7  * Copyright (C) 2002 by Ron Minnich <[email protected]>
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 <net/9p/9p.h>
40 #include <net/9p/client.h>
41 
42 #include "v9fs.h"
43 #include "v9fs_vfs.h"
44 #include "fid.h"
45 #include "cache.h"
46 
47 static const struct vm_operations_struct v9fs_file_vm_ops;
48 
56 int v9fs_file_open(struct inode *inode, struct file *file)
57 {
58  int err;
59  struct v9fs_inode *v9inode;
60  struct v9fs_session_info *v9ses;
61  struct p9_fid *fid;
62  int omode;
63 
64  p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file);
65  v9inode = V9FS_I(inode);
66  v9ses = v9fs_inode2v9ses(inode);
67  if (v9fs_proto_dotl(v9ses))
68  omode = v9fs_open_to_dotl_flags(file->f_flags);
69  else
70  omode = v9fs_uflags2omode(file->f_flags,
71  v9fs_proto_dotu(v9ses));
72  fid = file->private_data;
73  if (!fid) {
74  fid = v9fs_fid_clone(file->f_path.dentry);
75  if (IS_ERR(fid))
76  return PTR_ERR(fid);
77 
78  err = p9_client_open(fid, omode);
79  if (err < 0) {
80  p9_client_clunk(fid);
81  return err;
82  }
83  if (file->f_flags & O_TRUNC) {
84  i_size_write(inode, 0);
85  inode->i_blocks = 0;
86  }
87  if ((file->f_flags & O_APPEND) &&
88  (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)))
89  generic_file_llseek(file, 0, SEEK_END);
90  }
91 
92  file->private_data = fid;
93  mutex_lock(&v9inode->v_mutex);
94  if (v9ses->cache && !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 #ifdef CONFIG_9P_FSCACHE
113  if (v9ses->cache)
114  v9fs_cache_inode_set_cookie(inode, file);
115 #endif
116  return 0;
117 out_error:
119  file->private_data = NULL;
120  return err;
121 }
122 
133 static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
134 {
135  int res = 0;
136  struct inode *inode = filp->f_path.dentry->d_inode;
137 
138  p9_debug(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
139 
140  /* No mandatory locks */
141  if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
142  return -ENOLCK;
143 
144  if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
146  invalidate_mapping_pages(&inode->i_data, 0, -1);
147  }
148 
149  return res;
150 }
151 
152 static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
153 {
154  struct p9_flock flock;
155  struct p9_fid *fid;
156  uint8_t status;
157  int res = 0;
158  unsigned char fl_type;
159 
160  fid = filp->private_data;
161  BUG_ON(fid == NULL);
162 
163  if ((fl->fl_flags & FL_POSIX) != FL_POSIX)
164  BUG();
165 
166  res = posix_lock_file_wait(filp, fl);
167  if (res < 0)
168  goto out;
169 
170  /* convert posix lock to p9 tlock args */
171  memset(&flock, 0, sizeof(flock));
172  /* map the lock type */
173  switch (fl->fl_type) {
174  case F_RDLCK:
175  flock.type = P9_LOCK_TYPE_RDLCK;
176  break;
177  case F_WRLCK:
178  flock.type = P9_LOCK_TYPE_WRLCK;
179  break;
180  case F_UNLCK:
181  flock.type = P9_LOCK_TYPE_UNLCK;
182  break;
183  }
184  flock.start = fl->fl_start;
185  if (fl->fl_end == OFFSET_MAX)
186  flock.length = 0;
187  else
188  flock.length = fl->fl_end - fl->fl_start + 1;
189  flock.proc_id = fl->fl_pid;
190  flock.client_id = utsname()->nodename;
191  if (IS_SETLKW(cmd))
192  flock.flags = P9_LOCK_FLAGS_BLOCK;
193 
194  /*
195  * if its a blocked request and we get P9_LOCK_BLOCKED as the status
196  * for lock request, keep on trying
197  */
198  for (;;) {
199  res = p9_client_lock_dotl(fid, &flock, &status);
200  if (res < 0)
201  break;
202 
203  if (status != P9_LOCK_BLOCKED)
204  break;
205  if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd))
206  break;
208  break;
209  }
210 
211  /* map 9p status to VFS status */
212  switch (status) {
213  case P9_LOCK_SUCCESS:
214  res = 0;
215  break;
216  case P9_LOCK_BLOCKED:
217  res = -EAGAIN;
218  break;
219  case P9_LOCK_ERROR:
220  case P9_LOCK_GRACE:
221  res = -ENOLCK;
222  break;
223  default:
224  BUG();
225  }
226 
227  /*
228  * incase server returned error for lock request, revert
229  * it locally
230  */
231  if (res < 0 && fl->fl_type != F_UNLCK) {
232  fl_type = fl->fl_type;
233  fl->fl_type = F_UNLCK;
234  res = posix_lock_file_wait(filp, fl);
235  fl->fl_type = fl_type;
236  }
237 out:
238  return res;
239 }
240 
241 static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
242 {
243  struct p9_getlock glock;
244  struct p9_fid *fid;
245  int res = 0;
246 
247  fid = filp->private_data;
248  BUG_ON(fid == NULL);
249 
250  posix_test_lock(filp, fl);
251  /*
252  * if we have a conflicting lock locally, no need to validate
253  * with server
254  */
255  if (fl->fl_type != F_UNLCK)
256  return res;
257 
258  /* convert posix lock to p9 tgetlock args */
259  memset(&glock, 0, sizeof(glock));
260  glock.type = P9_LOCK_TYPE_UNLCK;
261  glock.start = fl->fl_start;
262  if (fl->fl_end == OFFSET_MAX)
263  glock.length = 0;
264  else
265  glock.length = fl->fl_end - fl->fl_start + 1;
266  glock.proc_id = fl->fl_pid;
267  glock.client_id = utsname()->nodename;
268 
269  res = p9_client_getlock_dotl(fid, &glock);
270  if (res < 0)
271  return res;
272  /* map 9p lock type to os lock type */
273  switch (glock.type) {
274  case P9_LOCK_TYPE_RDLCK:
275  fl->fl_type = F_RDLCK;
276  break;
277  case P9_LOCK_TYPE_WRLCK:
278  fl->fl_type = F_WRLCK;
279  break;
280  case P9_LOCK_TYPE_UNLCK:
281  fl->fl_type = F_UNLCK;
282  break;
283  }
284  if (glock.type != P9_LOCK_TYPE_UNLCK) {
285  fl->fl_start = glock.start;
286  if (glock.length == 0)
287  fl->fl_end = OFFSET_MAX;
288  else
289  fl->fl_end = glock.start + glock.length - 1;
290  fl->fl_pid = glock.proc_id;
291  }
292  return res;
293 }
294 
303 static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl)
304 {
305  struct inode *inode = filp->f_path.dentry->d_inode;
306  int ret = -ENOLCK;
307 
308  p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %s\n",
309  filp, cmd, fl, filp->f_path.dentry->d_name.name);
310 
311  /* No mandatory locks */
312  if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
313  goto out_err;
314 
315  if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
317  invalidate_mapping_pages(&inode->i_data, 0, -1);
318  }
319 
320  if (IS_SETLK(cmd) || IS_SETLKW(cmd))
321  ret = v9fs_file_do_lock(filp, cmd, fl);
322  else if (IS_GETLK(cmd))
323  ret = v9fs_file_getlock(filp, fl);
324  else
325  ret = -EINVAL;
326 out_err:
327  return ret;
328 }
329 
338 static int v9fs_file_flock_dotl(struct file *filp, int cmd,
339  struct file_lock *fl)
340 {
341  struct inode *inode = filp->f_path.dentry->d_inode;
342  int ret = -ENOLCK;
343 
344  p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %s\n",
345  filp, cmd, fl, filp->f_path.dentry->d_name.name);
346 
347  /* No mandatory locks */
348  if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
349  goto out_err;
350 
351  if (!(fl->fl_flags & FL_FLOCK))
352  goto out_err;
353 
354  if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
356  invalidate_mapping_pages(&inode->i_data, 0, -1);
357  }
358  /* Convert flock to posix lock */
359  fl->fl_owner = (fl_owner_t)filp;
360  fl->fl_start = 0;
361  fl->fl_end = OFFSET_MAX;
362  fl->fl_flags |= FL_POSIX;
363  fl->fl_flags ^= FL_FLOCK;
364 
365  if (IS_SETLK(cmd) | IS_SETLKW(cmd))
366  ret = v9fs_file_do_lock(filp, cmd, fl);
367  else
368  ret = -EINVAL;
369 out_err:
370  return ret;
371 }
372 
382 ssize_t
383 v9fs_fid_readn(struct p9_fid *fid, char *data, char __user *udata, u32 count,
384  u64 offset)
385 {
386  int n, total, size;
387 
388  p9_debug(P9_DEBUG_VFS, "fid %d offset %llu count %d\n",
389  fid->fid, (long long unsigned)offset, count);
390  n = 0;
391  total = 0;
392  size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
393  do {
394  n = p9_client_read(fid, data, udata, offset, count);
395  if (n <= 0)
396  break;
397 
398  if (data)
399  data += n;
400  if (udata)
401  udata += n;
402 
403  offset += n;
404  count -= n;
405  total += n;
406  } while (count > 0 && n == size);
407 
408  if (n < 0)
409  total = n;
410 
411  return total;
412 }
413 
423 ssize_t
424 v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count,
425  u64 offset)
426 {
427  return v9fs_fid_readn(filp->private_data, data, udata, count, offset);
428 }
429 
439 static ssize_t
440 v9fs_file_read(struct file *filp, char __user *udata, size_t count,
441  loff_t * offset)
442 {
443  int ret;
444  struct p9_fid *fid;
445  size_t size;
446 
447  p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n", count, *offset);
448  fid = filp->private_data;
449 
450  size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
451  if (count > size)
452  ret = v9fs_file_readn(filp, NULL, udata, count, *offset);
453  else
454  ret = p9_client_read(fid, NULL, udata, *offset, count);
455 
456  if (ret > 0)
457  *offset += ret;
458 
459  return ret;
460 }
461 
462 ssize_t
463 v9fs_file_write_internal(struct inode *inode, struct p9_fid *fid,
464  const char __user *data, size_t count,
465  loff_t *offset, int invalidate)
466 {
467  int n;
468  loff_t i_size;
469  size_t total = 0;
470  struct p9_client *clnt;
471  loff_t origin = *offset;
472  unsigned long pg_start, pg_end;
473 
474  p9_debug(P9_DEBUG_VFS, "data %p count %d offset %x\n",
475  data, (int)count, (int)*offset);
476 
477  clnt = fid->clnt;
478  do {
479  n = p9_client_write(fid, NULL, data+total, origin+total, count);
480  if (n <= 0)
481  break;
482  count -= n;
483  total += n;
484  } while (count > 0);
485 
486  if (invalidate && (total > 0)) {
487  pg_start = origin >> PAGE_CACHE_SHIFT;
488  pg_end = (origin + total - 1) >> PAGE_CACHE_SHIFT;
489  if (inode->i_mapping && inode->i_mapping->nrpages)
491  pg_start, pg_end);
492  *offset += total;
493  i_size = i_size_read(inode);
494  if (*offset > i_size) {
495  inode_add_bytes(inode, *offset - i_size);
496  i_size_write(inode, *offset);
497  }
498  }
499  if (n < 0)
500  return n;
501 
502  return total;
503 }
504 
513 static ssize_t
514 v9fs_file_write(struct file *filp, const char __user * data,
515  size_t count, loff_t *offset)
516 {
517  ssize_t retval = 0;
518  loff_t origin = *offset;
519 
520 
521  retval = generic_write_checks(filp, &origin, &count, 0);
522  if (retval)
523  goto out;
524 
525  retval = -EINVAL;
526  if ((ssize_t) count < 0)
527  goto out;
528  retval = 0;
529  if (!count)
530  goto out;
531 
532  retval = v9fs_file_write_internal(filp->f_path.dentry->d_inode,
533  filp->private_data,
534  data, count, &origin, 1);
535  /* update offset on successful write */
536  if (retval > 0)
537  *offset = origin;
538 out:
539  return retval;
540 }
541 
542 
543 static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end,
544  int datasync)
545 {
546  struct p9_fid *fid;
547  struct inode *inode = filp->f_mapping->host;
548  struct p9_wstat wstat;
549  int retval;
550 
551  retval = filemap_write_and_wait_range(inode->i_mapping, start, end);
552  if (retval)
553  return retval;
554 
555  mutex_lock(&inode->i_mutex);
556  p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
557 
558  fid = filp->private_data;
559  v9fs_blank_wstat(&wstat);
560 
561  retval = p9_client_wstat(fid, &wstat);
562  mutex_unlock(&inode->i_mutex);
563 
564  return retval;
565 }
566 
567 int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
568  int datasync)
569 {
570  struct p9_fid *fid;
571  struct inode *inode = filp->f_mapping->host;
572  int retval;
573 
574  retval = filemap_write_and_wait_range(inode->i_mapping, start, end);
575  if (retval)
576  return retval;
577 
578  mutex_lock(&inode->i_mutex);
579  p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
580 
581  fid = filp->private_data;
582 
583  retval = p9_client_fsync(fid, datasync);
584  mutex_unlock(&inode->i_mutex);
585 
586  return retval;
587 }
588 
589 static int
590 v9fs_file_mmap(struct file *file, struct vm_area_struct *vma)
591 {
592  int retval;
593 
594  retval = generic_file_mmap(file, vma);
595  if (!retval)
596  vma->vm_ops = &v9fs_file_vm_ops;
597 
598  return retval;
599 }
600 
601 static int
602 v9fs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
603 {
604  struct v9fs_inode *v9inode;
605  struct page *page = vmf->page;
606  struct file *filp = vma->vm_file;
607  struct inode *inode = filp->f_path.dentry->d_inode;
608 
609 
610  p9_debug(P9_DEBUG_VFS, "page %p fid %lx\n",
611  page, (unsigned long)filp->private_data);
612 
613  /* Update file times before taking page lock */
614  file_update_time(filp);
615 
616  v9inode = V9FS_I(inode);
617  /* make sure the cache has finished storing the page */
618  v9fs_fscache_wait_on_page_write(inode, page);
619  BUG_ON(!v9inode->writeback_fid);
620  lock_page(page);
621  if (page->mapping != inode->i_mapping)
622  goto out_unlock;
623 
624  return VM_FAULT_LOCKED;
625 out_unlock:
626  unlock_page(page);
627  return VM_FAULT_NOPAGE;
628 }
629 
630 static ssize_t
631 v9fs_direct_read(struct file *filp, char __user *udata, size_t count,
632  loff_t *offsetp)
633 {
634  loff_t size, offset;
635  struct inode *inode;
636  struct address_space *mapping;
637 
638  offset = *offsetp;
639  mapping = filp->f_mapping;
640  inode = mapping->host;
641  if (!count)
642  return 0;
643  size = i_size_read(inode);
644  if (offset < size)
645  filemap_write_and_wait_range(mapping, offset,
646  offset + count - 1);
647 
648  return v9fs_file_read(filp, udata, count, offsetp);
649 }
650 
659 static ssize_t
660 v9fs_cached_file_read(struct file *filp, char __user *data, size_t count,
661  loff_t *offset)
662 {
663  if (filp->f_flags & O_DIRECT)
664  return v9fs_direct_read(filp, data, count, offset);
665  return do_sync_read(filp, data, count, offset);
666 }
667 
668 static ssize_t
669 v9fs_direct_write(struct file *filp, const char __user * data,
670  size_t count, loff_t *offsetp)
671 {
672  loff_t offset;
673  ssize_t retval;
674  struct inode *inode;
675  struct address_space *mapping;
676 
677  offset = *offsetp;
678  mapping = filp->f_mapping;
679  inode = mapping->host;
680  if (!count)
681  return 0;
682 
683  mutex_lock(&inode->i_mutex);
684  retval = filemap_write_and_wait_range(mapping, offset,
685  offset + count - 1);
686  if (retval)
687  goto err_out;
688  /*
689  * After a write we want buffered reads to be sure to go to disk to get
690  * the new data. We invalidate clean cached page from the region we're
691  * about to write. We do this *before* the write so that if we fail
692  * here we fall back to buffered write
693  */
694  if (mapping->nrpages) {
695  pgoff_t pg_start = offset >> PAGE_CACHE_SHIFT;
696  pgoff_t pg_end = (offset + count - 1) >> PAGE_CACHE_SHIFT;
697 
698  retval = invalidate_inode_pages2_range(mapping,
699  pg_start, pg_end);
700  /*
701  * If a page can not be invalidated, fall back
702  * to buffered write.
703  */
704  if (retval) {
705  if (retval == -EBUSY)
706  goto buff_write;
707  goto err_out;
708  }
709  }
710  retval = v9fs_file_write(filp, data, count, offsetp);
711 err_out:
712  mutex_unlock(&inode->i_mutex);
713  return retval;
714 
715 buff_write:
716  mutex_unlock(&inode->i_mutex);
717  return do_sync_write(filp, data, count, offsetp);
718 }
719 
728 static ssize_t
729 v9fs_cached_file_write(struct file *filp, const char __user * data,
730  size_t count, loff_t *offset)
731 {
732 
733  if (filp->f_flags & O_DIRECT)
734  return v9fs_direct_write(filp, data, count, offset);
735  return do_sync_write(filp, data, count, offset);
736 }
737 
738 static const struct vm_operations_struct v9fs_file_vm_ops = {
739  .fault = filemap_fault,
740  .page_mkwrite = v9fs_vm_page_mkwrite,
741  .remap_pages = generic_file_remap_pages,
742 };
743 
744 
746  .llseek = generic_file_llseek,
747  .read = v9fs_cached_file_read,
748  .write = v9fs_cached_file_write,
749  .aio_read = generic_file_aio_read,
750  .aio_write = generic_file_aio_write,
751  .open = v9fs_file_open,
752  .release = v9fs_dir_release,
753  .lock = v9fs_file_lock,
754  .mmap = v9fs_file_mmap,
755  .fsync = v9fs_file_fsync,
756 };
757 
759  .llseek = generic_file_llseek,
760  .read = v9fs_cached_file_read,
761  .write = v9fs_cached_file_write,
762  .aio_read = generic_file_aio_read,
763  .aio_write = generic_file_aio_write,
764  .open = v9fs_file_open,
765  .release = v9fs_dir_release,
766  .lock = v9fs_file_lock_dotl,
767  .flock = v9fs_file_flock_dotl,
768  .mmap = v9fs_file_mmap,
769  .fsync = v9fs_file_fsync_dotl,
770 };
771 
773  .llseek = generic_file_llseek,
774  .read = v9fs_file_read,
775  .write = v9fs_file_write,
776  .open = v9fs_file_open,
777  .release = v9fs_dir_release,
778  .lock = v9fs_file_lock,
780  .fsync = v9fs_file_fsync,
781 };
782 
784  .llseek = generic_file_llseek,
785  .read = v9fs_file_read,
786  .write = v9fs_file_write,
787  .open = v9fs_file_open,
788  .release = v9fs_dir_release,
789  .lock = v9fs_file_lock_dotl,
790  .flock = v9fs_file_flock_dotl,
792  .fsync = v9fs_file_fsync_dotl,
793 };