Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vfs_inode_dotl.c
Go to the documentation of this file.
1 /*
2  * linux/fs/9p/vfs_inode_dotl.c
3  *
4  * This file contains vfs inode ops for the 9P2000.L protocol.
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/file.h>
30 #include <linux/pagemap.h>
31 #include <linux/stat.h>
32 #include <linux/string.h>
33 #include <linux/inet.h>
34 #include <linux/namei.h>
35 #include <linux/idr.h>
36 #include <linux/sched.h>
37 #include <linux/slab.h>
38 #include <linux/xattr.h>
39 #include <linux/posix_acl.h>
40 #include <net/9p/9p.h>
41 #include <net/9p/client.h>
42 
43 #include "v9fs.h"
44 #include "v9fs_vfs.h"
45 #include "fid.h"
46 #include "cache.h"
47 #include "xattr.h"
48 #include "acl.h"
49 
50 static int
51 v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
52  dev_t rdev);
53 
60 static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
61 {
62  BUG_ON(dir_inode == NULL);
63 
64  if (dir_inode->i_mode & S_ISGID) {
65  /* set_gid bit is set.*/
66  return dir_inode->i_gid;
67  }
68  return current_fsgid();
69 }
70 
71 static int v9fs_test_inode_dotl(struct inode *inode, void *data)
72 {
73  struct v9fs_inode *v9inode = V9FS_I(inode);
74  struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
75 
76  /* don't match inode of different type */
77  if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
78  return 0;
79 
80  if (inode->i_generation != st->st_gen)
81  return 0;
82 
83  /* compare qid details */
84  if (memcmp(&v9inode->qid.version,
85  &st->qid.version, sizeof(v9inode->qid.version)))
86  return 0;
87 
88  if (v9inode->qid.type != st->qid.type)
89  return 0;
90  return 1;
91 }
92 
93 /* Always get a new inode */
94 static int v9fs_test_new_inode_dotl(struct inode *inode, void *data)
95 {
96  return 0;
97 }
98 
99 static int v9fs_set_inode_dotl(struct inode *inode, void *data)
100 {
101  struct v9fs_inode *v9inode = V9FS_I(inode);
102  struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
103 
104  memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
105  inode->i_generation = st->st_gen;
106  return 0;
107 }
108 
109 static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
110  struct p9_qid *qid,
111  struct p9_fid *fid,
112  struct p9_stat_dotl *st,
113  int new)
114 {
115  int retval;
116  unsigned long i_ino;
117  struct inode *inode;
118  struct v9fs_session_info *v9ses = sb->s_fs_info;
119  int (*test)(struct inode *, void *);
120 
121  if (new)
122  test = v9fs_test_new_inode_dotl;
123  else
124  test = v9fs_test_inode_dotl;
125 
126  i_ino = v9fs_qid2ino(qid);
127  inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st);
128  if (!inode)
129  return ERR_PTR(-ENOMEM);
130  if (!(inode->i_state & I_NEW))
131  return inode;
132  /*
133  * initialize the inode with the stat info
134  * FIXME!! we may need support for stale inodes
135  * later.
136  */
137  inode->i_ino = i_ino;
138  retval = v9fs_init_inode(v9ses, inode,
139  st->st_mode, new_decode_dev(st->st_rdev));
140  if (retval)
141  goto error;
142 
143  v9fs_stat2inode_dotl(st, inode);
144 #ifdef CONFIG_9P_FSCACHE
146 #endif
147  retval = v9fs_get_acl(inode, fid);
148  if (retval)
149  goto error;
150 
151  unlock_new_inode(inode);
152  return inode;
153 error:
154  unlock_new_inode(inode);
155  iput(inode);
156  return ERR_PTR(retval);
157 
158 }
159 
160 struct inode *
162  struct super_block *sb, int new)
163 {
164  struct p9_stat_dotl *st;
165  struct inode *inode = NULL;
166 
168  if (IS_ERR(st))
169  return ERR_CAST(st);
170 
171  inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new);
172  kfree(st);
173  return inode;
174 }
175 
179 };
180 
181 static int v9fs_mapped_dotl_flags(int flags)
182 {
183  int i;
184  int rflags = 0;
185  struct dotl_openflag_map dotl_oflag_map[] = {
186  { O_CREAT, P9_DOTL_CREATE },
187  { O_EXCL, P9_DOTL_EXCL },
189  { O_TRUNC, P9_DOTL_TRUNC },
192  { O_DSYNC, P9_DOTL_DSYNC },
193  { FASYNC, P9_DOTL_FASYNC },
200  { O_SYNC, P9_DOTL_SYNC},
201  };
202  for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) {
203  if (flags & dotl_oflag_map[i].open_flag)
204  rflags |= dotl_oflag_map[i].dotl_flag;
205  }
206  return rflags;
207 }
208 
215 {
216  int rflags = 0;
217 
218  /*
219  * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY
220  * and P9_DOTL_NOACCESS
221  */
222  rflags |= flags & O_ACCMODE;
223  rflags |= v9fs_mapped_dotl_flags(flags);
224 
225  return rflags;
226 }
227 
236 static int
237 v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
238  bool excl)
239 {
240  return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
241 }
242 
243 static int
244 v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
245  struct file *file, unsigned flags, umode_t omode,
246  int *opened)
247 {
248  int err = 0;
249  gid_t gid;
250  umode_t mode;
251  char *name = NULL;
252  struct p9_qid qid;
253  struct inode *inode;
254  struct p9_fid *fid = NULL;
255  struct v9fs_inode *v9inode;
256  struct p9_fid *dfid, *ofid, *inode_fid;
257  struct v9fs_session_info *v9ses;
258  struct posix_acl *pacl = NULL, *dacl = NULL;
259  struct dentry *res = NULL;
260 
261  if (d_unhashed(dentry)) {
262  res = v9fs_vfs_lookup(dir, dentry, 0);
263  if (IS_ERR(res))
264  return PTR_ERR(res);
265 
266  if (res)
267  dentry = res;
268  }
269 
270  /* Only creates */
271  if (!(flags & O_CREAT) || dentry->d_inode)
272  return finish_no_open(file, res);
273 
274  v9ses = v9fs_inode2v9ses(dir);
275 
276  name = (char *) dentry->d_name.name;
277  p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%hx\n",
278  name, flags, omode);
279 
280  dfid = v9fs_fid_lookup(dentry->d_parent);
281  if (IS_ERR(dfid)) {
282  err = PTR_ERR(dfid);
283  p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
284  goto out;
285  }
286 
287  /* clone a fid to use for creation */
288  ofid = p9_client_walk(dfid, 0, NULL, 1);
289  if (IS_ERR(ofid)) {
290  err = PTR_ERR(ofid);
291  p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
292  goto out;
293  }
294 
295  gid = v9fs_get_fsgid_for_create(dir);
296 
297  mode = omode;
298  /* Update mode based on ACL value */
299  err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
300  if (err) {
301  p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d\n",
302  err);
303  goto error;
304  }
305  err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags),
306  mode, gid, &qid);
307  if (err < 0) {
308  p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d\n",
309  err);
310  goto error;
311  }
312  v9fs_invalidate_inode_attr(dir);
313 
314  /* instantiate inode and assign the unopened fid to the dentry */
315  fid = p9_client_walk(dfid, 1, &name, 1);
316  if (IS_ERR(fid)) {
317  err = PTR_ERR(fid);
318  p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
319  fid = NULL;
320  goto error;
321  }
322  inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
323  if (IS_ERR(inode)) {
324  err = PTR_ERR(inode);
325  p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err);
326  goto error;
327  }
328  err = v9fs_fid_add(dentry, fid);
329  if (err < 0)
330  goto error;
331  d_instantiate(dentry, inode);
332 
333  /* Now set the ACL based on the default value */
334  v9fs_set_create_acl(dentry, &dacl, &pacl);
335 
336  v9inode = V9FS_I(inode);
337  mutex_lock(&v9inode->v_mutex);
338  if (v9ses->cache && !v9inode->writeback_fid &&
339  ((flags & O_ACCMODE) != O_RDONLY)) {
340  /*
341  * clone a fid and add it to writeback_fid
342  * we do it during open time instead of
343  * page dirty time via write_begin/page_mkwrite
344  * because we want write after unlink usecase
345  * to work.
346  */
347  inode_fid = v9fs_writeback_fid(dentry);
348  if (IS_ERR(inode_fid)) {
349  err = PTR_ERR(inode_fid);
350  mutex_unlock(&v9inode->v_mutex);
351  goto err_clunk_old_fid;
352  }
353  v9inode->writeback_fid = (void *) inode_fid;
354  }
355  mutex_unlock(&v9inode->v_mutex);
356  /* Since we are opening a file, assign the open fid to the file */
357  err = finish_open(file, dentry, generic_file_open, opened);
358  if (err)
359  goto err_clunk_old_fid;
360  file->private_data = ofid;
361 #ifdef CONFIG_9P_FSCACHE
362  if (v9ses->cache)
363  v9fs_cache_inode_set_cookie(inode, file);
364 #endif
365  *opened |= FILE_CREATED;
366 out:
367  dput(res);
368  return err;
369 
370 error:
371  if (fid)
372  p9_client_clunk(fid);
373 err_clunk_old_fid:
374  if (ofid)
375  p9_client_clunk(ofid);
376  v9fs_set_create_acl(NULL, &dacl, &pacl);
377  goto out;
378 }
379 
388 static int v9fs_vfs_mkdir_dotl(struct inode *dir,
389  struct dentry *dentry, umode_t omode)
390 {
391  int err;
392  struct v9fs_session_info *v9ses;
393  struct p9_fid *fid = NULL, *dfid = NULL;
394  gid_t gid;
395  char *name;
396  umode_t mode;
397  struct inode *inode;
398  struct p9_qid qid;
399  struct dentry *dir_dentry;
400  struct posix_acl *dacl = NULL, *pacl = NULL;
401 
402  p9_debug(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
403  err = 0;
404  v9ses = v9fs_inode2v9ses(dir);
405 
406  omode |= S_IFDIR;
407  if (dir->i_mode & S_ISGID)
408  omode |= S_ISGID;
409 
410  dir_dentry = dentry->d_parent;
411  dfid = v9fs_fid_lookup(dir_dentry);
412  if (IS_ERR(dfid)) {
413  err = PTR_ERR(dfid);
414  p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
415  dfid = NULL;
416  goto error;
417  }
418 
419  gid = v9fs_get_fsgid_for_create(dir);
420  mode = omode;
421  /* Update mode based on ACL value */
422  err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
423  if (err) {
424  p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mkdir %d\n",
425  err);
426  goto error;
427  }
428  name = (char *) dentry->d_name.name;
429  err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
430  if (err < 0)
431  goto error;
432 
433  /* instantiate inode and assign the unopened fid to the dentry */
434  if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
435  fid = p9_client_walk(dfid, 1, &name, 1);
436  if (IS_ERR(fid)) {
437  err = PTR_ERR(fid);
438  p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
439  err);
440  fid = NULL;
441  goto error;
442  }
443 
444  inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
445  if (IS_ERR(inode)) {
446  err = PTR_ERR(inode);
447  p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
448  err);
449  goto error;
450  }
451  err = v9fs_fid_add(dentry, fid);
452  if (err < 0)
453  goto error;
454  d_instantiate(dentry, inode);
455  fid = NULL;
456  } else {
457  /*
458  * Not in cached mode. No need to populate
459  * inode with stat. We need to get an inode
460  * so that we can set the acl with dentry
461  */
462  inode = v9fs_get_inode(dir->i_sb, mode, 0);
463  if (IS_ERR(inode)) {
464  err = PTR_ERR(inode);
465  goto error;
466  }
467  d_instantiate(dentry, inode);
468  }
469  /* Now set the ACL based on the default value */
470  v9fs_set_create_acl(dentry, &dacl, &pacl);
471  inc_nlink(dir);
472  v9fs_invalidate_inode_attr(dir);
473 error:
474  if (fid)
475  p9_client_clunk(fid);
476  v9fs_set_create_acl(NULL, &dacl, &pacl);
477  return err;
478 }
479 
480 static int
481 v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
482  struct kstat *stat)
483 {
484  int err;
485  struct v9fs_session_info *v9ses;
486  struct p9_fid *fid;
487  struct p9_stat_dotl *st;
488 
489  p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
490  err = -EPERM;
491  v9ses = v9fs_dentry2v9ses(dentry);
492  if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
493  generic_fillattr(dentry->d_inode, stat);
494  return 0;
495  }
496  fid = v9fs_fid_lookup(dentry);
497  if (IS_ERR(fid))
498  return PTR_ERR(fid);
499 
500  /* Ask for all the fields in stat structure. Server will return
501  * whatever it supports
502  */
503 
505  if (IS_ERR(st))
506  return PTR_ERR(st);
507 
508  v9fs_stat2inode_dotl(st, dentry->d_inode);
509  generic_fillattr(dentry->d_inode, stat);
510  /* Change block size to what the server returned */
511  stat->blksize = st->st_blksize;
512 
513  kfree(st);
514  return 0;
515 }
516 
517 /*
518  * Attribute flags.
519  */
520 #define P9_ATTR_MODE (1 << 0)
521 #define P9_ATTR_UID (1 << 1)
522 #define P9_ATTR_GID (1 << 2)
523 #define P9_ATTR_SIZE (1 << 3)
524 #define P9_ATTR_ATIME (1 << 4)
525 #define P9_ATTR_MTIME (1 << 5)
526 #define P9_ATTR_CTIME (1 << 6)
527 #define P9_ATTR_ATIME_SET (1 << 7)
528 #define P9_ATTR_MTIME_SET (1 << 8)
529 
533 };
534 
535 static int v9fs_mapped_iattr_valid(int iattr_valid)
536 {
537  int i;
538  int p9_iattr_valid = 0;
539  struct dotl_iattr_map dotl_iattr_map[] = {
540  { ATTR_MODE, P9_ATTR_MODE },
541  { ATTR_UID, P9_ATTR_UID },
542  { ATTR_GID, P9_ATTR_GID },
543  { ATTR_SIZE, P9_ATTR_SIZE },
549  };
550  for (i = 0; i < ARRAY_SIZE(dotl_iattr_map); i++) {
551  if (iattr_valid & dotl_iattr_map[i].iattr_valid)
552  p9_iattr_valid |= dotl_iattr_map[i].p9_iattr_valid;
553  }
554  return p9_iattr_valid;
555 }
556 
564 int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
565 {
566  int retval;
567  struct v9fs_session_info *v9ses;
568  struct p9_fid *fid;
569  struct p9_iattr_dotl p9attr;
570 
571  p9_debug(P9_DEBUG_VFS, "\n");
572 
573  retval = inode_change_ok(dentry->d_inode, iattr);
574  if (retval)
575  return retval;
576 
577  p9attr.valid = v9fs_mapped_iattr_valid(iattr->ia_valid);
578  p9attr.mode = iattr->ia_mode;
579  p9attr.uid = iattr->ia_uid;
580  p9attr.gid = iattr->ia_gid;
581  p9attr.size = iattr->ia_size;
582  p9attr.atime_sec = iattr->ia_atime.tv_sec;
583  p9attr.atime_nsec = iattr->ia_atime.tv_nsec;
584  p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
585  p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
586 
587  retval = -EPERM;
588  v9ses = v9fs_dentry2v9ses(dentry);
589  fid = v9fs_fid_lookup(dentry);
590  if (IS_ERR(fid))
591  return PTR_ERR(fid);
592 
593  /* Write all dirty data */
594  if (S_ISREG(dentry->d_inode->i_mode))
595  filemap_write_and_wait(dentry->d_inode->i_mapping);
596 
597  retval = p9_client_setattr(fid, &p9attr);
598  if (retval < 0)
599  return retval;
600 
601  if ((iattr->ia_valid & ATTR_SIZE) &&
602  iattr->ia_size != i_size_read(dentry->d_inode))
603  truncate_setsize(dentry->d_inode, iattr->ia_size);
604 
605  v9fs_invalidate_inode_attr(dentry->d_inode);
606  setattr_copy(dentry->d_inode, iattr);
607  mark_inode_dirty(dentry->d_inode);
608  if (iattr->ia_valid & ATTR_MODE) {
609  /* We also want to update ACL when we update mode bits */
610  retval = v9fs_acl_chmod(dentry);
611  if (retval < 0)
612  return retval;
613  }
614  return 0;
615 }
616 
625 void
626 v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
627 {
628  umode_t mode;
629  struct v9fs_inode *v9inode = V9FS_I(inode);
630 
631  if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
632  inode->i_atime.tv_sec = stat->st_atime_sec;
633  inode->i_atime.tv_nsec = stat->st_atime_nsec;
634  inode->i_mtime.tv_sec = stat->st_mtime_sec;
635  inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
636  inode->i_ctime.tv_sec = stat->st_ctime_sec;
637  inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
638  inode->i_uid = stat->st_uid;
639  inode->i_gid = stat->st_gid;
640  set_nlink(inode, stat->st_nlink);
641 
642  mode = stat->st_mode & S_IALLUGO;
643  mode |= inode->i_mode & ~S_IALLUGO;
644  inode->i_mode = mode;
645 
646  i_size_write(inode, stat->st_size);
647  inode->i_blocks = stat->st_blocks;
648  } else {
649  if (stat->st_result_mask & P9_STATS_ATIME) {
650  inode->i_atime.tv_sec = stat->st_atime_sec;
651  inode->i_atime.tv_nsec = stat->st_atime_nsec;
652  }
653  if (stat->st_result_mask & P9_STATS_MTIME) {
654  inode->i_mtime.tv_sec = stat->st_mtime_sec;
655  inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
656  }
657  if (stat->st_result_mask & P9_STATS_CTIME) {
658  inode->i_ctime.tv_sec = stat->st_ctime_sec;
659  inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
660  }
661  if (stat->st_result_mask & P9_STATS_UID)
662  inode->i_uid = stat->st_uid;
663  if (stat->st_result_mask & P9_STATS_GID)
664  inode->i_gid = stat->st_gid;
665  if (stat->st_result_mask & P9_STATS_NLINK)
666  set_nlink(inode, stat->st_nlink);
667  if (stat->st_result_mask & P9_STATS_MODE) {
668  inode->i_mode = stat->st_mode;
669  if ((S_ISBLK(inode->i_mode)) ||
670  (S_ISCHR(inode->i_mode)))
671  init_special_inode(inode, inode->i_mode,
672  inode->i_rdev);
673  }
674  if (stat->st_result_mask & P9_STATS_RDEV)
675  inode->i_rdev = new_decode_dev(stat->st_rdev);
676  if (stat->st_result_mask & P9_STATS_SIZE)
677  i_size_write(inode, stat->st_size);
678  if (stat->st_result_mask & P9_STATS_BLOCKS)
679  inode->i_blocks = stat->st_blocks;
680  }
681  if (stat->st_result_mask & P9_STATS_GEN)
682  inode->i_generation = stat->st_gen;
683 
684  /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
685  * because the inode structure does not have fields for them.
686  */
688 }
689 
690 static int
691 v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
692  const char *symname)
693 {
694  int err;
695  gid_t gid;
696  char *name;
697  struct p9_qid qid;
698  struct inode *inode;
699  struct p9_fid *dfid;
700  struct p9_fid *fid = NULL;
701  struct v9fs_session_info *v9ses;
702 
703  name = (char *) dentry->d_name.name;
704  p9_debug(P9_DEBUG_VFS, "%lu,%s,%s\n", dir->i_ino, name, symname);
705  v9ses = v9fs_inode2v9ses(dir);
706 
707  dfid = v9fs_fid_lookup(dentry->d_parent);
708  if (IS_ERR(dfid)) {
709  err = PTR_ERR(dfid);
710  p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
711  return err;
712  }
713 
714  gid = v9fs_get_fsgid_for_create(dir);
715 
716  /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
717  err = p9_client_symlink(dfid, name, (char *)symname, gid, &qid);
718 
719  if (err < 0) {
720  p9_debug(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err);
721  goto error;
722  }
723 
724  v9fs_invalidate_inode_attr(dir);
725  if (v9ses->cache) {
726  /* Now walk from the parent so we can get an unopened fid. */
727  fid = p9_client_walk(dfid, 1, &name, 1);
728  if (IS_ERR(fid)) {
729  err = PTR_ERR(fid);
730  p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
731  err);
732  fid = NULL;
733  goto error;
734  }
735 
736  /* instantiate inode and assign the unopened fid to dentry */
737  inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
738  if (IS_ERR(inode)) {
739  err = PTR_ERR(inode);
740  p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
741  err);
742  goto error;
743  }
744  err = v9fs_fid_add(dentry, fid);
745  if (err < 0)
746  goto error;
747  d_instantiate(dentry, inode);
748  fid = NULL;
749  } else {
750  /* Not in cached mode. No need to populate inode with stat */
751  inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0);
752  if (IS_ERR(inode)) {
753  err = PTR_ERR(inode);
754  goto error;
755  }
756  d_instantiate(dentry, inode);
757  }
758 
759 error:
760  if (fid)
761  p9_client_clunk(fid);
762 
763  return err;
764 }
765 
774 static int
775 v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
776  struct dentry *dentry)
777 {
778  int err;
779  char *name;
780  struct dentry *dir_dentry;
781  struct p9_fid *dfid, *oldfid;
782  struct v9fs_session_info *v9ses;
783 
784  p9_debug(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n",
785  dir->i_ino, old_dentry->d_name.name, dentry->d_name.name);
786 
787  v9ses = v9fs_inode2v9ses(dir);
788  dir_dentry = dentry->d_parent;
789  dfid = v9fs_fid_lookup(dir_dentry);
790  if (IS_ERR(dfid))
791  return PTR_ERR(dfid);
792 
793  oldfid = v9fs_fid_lookup(old_dentry);
794  if (IS_ERR(oldfid))
795  return PTR_ERR(oldfid);
796 
797  name = (char *) dentry->d_name.name;
798 
799  err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name);
800 
801  if (err < 0) {
802  p9_debug(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
803  return err;
804  }
805 
806  v9fs_invalidate_inode_attr(dir);
807  if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
808  /* Get the latest stat info from server. */
809  struct p9_fid *fid;
810  fid = v9fs_fid_lookup(old_dentry);
811  if (IS_ERR(fid))
812  return PTR_ERR(fid);
813 
814  v9fs_refresh_inode_dotl(fid, old_dentry->d_inode);
815  }
816  ihold(old_dentry->d_inode);
817  d_instantiate(dentry, old_dentry->d_inode);
818 
819  return err;
820 }
821 
830 static int
831 v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
832  dev_t rdev)
833 {
834  int err;
835  gid_t gid;
836  char *name;
837  umode_t mode;
838  struct v9fs_session_info *v9ses;
839  struct p9_fid *fid = NULL, *dfid = NULL;
840  struct inode *inode;
841  struct p9_qid qid;
842  struct dentry *dir_dentry;
843  struct posix_acl *dacl = NULL, *pacl = NULL;
844 
845  p9_debug(P9_DEBUG_VFS, " %lu,%s mode: %hx MAJOR: %u MINOR: %u\n",
846  dir->i_ino, dentry->d_name.name, omode,
847  MAJOR(rdev), MINOR(rdev));
848 
849  if (!new_valid_dev(rdev))
850  return -EINVAL;
851 
852  v9ses = v9fs_inode2v9ses(dir);
853  dir_dentry = dentry->d_parent;
854  dfid = v9fs_fid_lookup(dir_dentry);
855  if (IS_ERR(dfid)) {
856  err = PTR_ERR(dfid);
857  p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
858  dfid = NULL;
859  goto error;
860  }
861 
862  gid = v9fs_get_fsgid_for_create(dir);
863  mode = omode;
864  /* Update mode based on ACL value */
865  err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
866  if (err) {
867  p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mknod %d\n",
868  err);
869  goto error;
870  }
871  name = (char *) dentry->d_name.name;
872 
873  err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
874  if (err < 0)
875  goto error;
876 
877  v9fs_invalidate_inode_attr(dir);
878  /* instantiate inode and assign the unopened fid to the dentry */
879  if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
880  fid = p9_client_walk(dfid, 1, &name, 1);
881  if (IS_ERR(fid)) {
882  err = PTR_ERR(fid);
883  p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
884  err);
885  fid = NULL;
886  goto error;
887  }
888 
889  inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
890  if (IS_ERR(inode)) {
891  err = PTR_ERR(inode);
892  p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
893  err);
894  goto error;
895  }
896  err = v9fs_fid_add(dentry, fid);
897  if (err < 0)
898  goto error;
899  d_instantiate(dentry, inode);
900  fid = NULL;
901  } else {
902  /*
903  * Not in cached mode. No need to populate inode with stat.
904  * socket syscall returns a fd, so we need instantiate
905  */
906  inode = v9fs_get_inode(dir->i_sb, mode, rdev);
907  if (IS_ERR(inode)) {
908  err = PTR_ERR(inode);
909  goto error;
910  }
911  d_instantiate(dentry, inode);
912  }
913  /* Now set the ACL based on the default value */
914  v9fs_set_create_acl(dentry, &dacl, &pacl);
915 error:
916  if (fid)
917  p9_client_clunk(fid);
918  v9fs_set_create_acl(NULL, &dacl, &pacl);
919  return err;
920 }
921 
929 static void *
930 v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd)
931 {
932  int retval;
933  struct p9_fid *fid;
934  char *link = __getname();
935  char *target;
936 
937  p9_debug(P9_DEBUG_VFS, "%s\n", dentry->d_name.name);
938 
939  if (!link) {
940  link = ERR_PTR(-ENOMEM);
941  goto ndset;
942  }
943  fid = v9fs_fid_lookup(dentry);
944  if (IS_ERR(fid)) {
945  __putname(link);
946  link = ERR_CAST(fid);
947  goto ndset;
948  }
949  retval = p9_client_readlink(fid, &target);
950  if (!retval) {
951  strcpy(link, target);
952  kfree(target);
953  goto ndset;
954  }
955  __putname(link);
956  link = ERR_PTR(retval);
957 ndset:
958  nd_set_link(nd, link);
959  return NULL;
960 }
961 
962 int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
963 {
964  loff_t i_size;
965  struct p9_stat_dotl *st;
966  struct v9fs_session_info *v9ses;
967 
968  v9ses = v9fs_inode2v9ses(inode);
970  if (IS_ERR(st))
971  return PTR_ERR(st);
972  /*
973  * Don't update inode if the file type is different
974  */
975  if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
976  goto out;
977 
978  spin_lock(&inode->i_lock);
979  /*
980  * We don't want to refresh inode->i_size,
981  * because we may have cached data
982  */
983  i_size = inode->i_size;
984  v9fs_stat2inode_dotl(st, inode);
985  if (v9ses->cache)
986  inode->i_size = i_size;
987  spin_unlock(&inode->i_lock);
988 out:
989  kfree(st);
990  return 0;
991 }
992 
994  .create = v9fs_vfs_create_dotl,
995  .atomic_open = v9fs_vfs_atomic_open_dotl,
996  .lookup = v9fs_vfs_lookup,
997  .link = v9fs_vfs_link_dotl,
998  .symlink = v9fs_vfs_symlink_dotl,
999  .unlink = v9fs_vfs_unlink,
1000  .mkdir = v9fs_vfs_mkdir_dotl,
1001  .rmdir = v9fs_vfs_rmdir,
1002  .mknod = v9fs_vfs_mknod_dotl,
1003  .rename = v9fs_vfs_rename,
1004  .getattr = v9fs_vfs_getattr_dotl,
1005  .setattr = v9fs_vfs_setattr_dotl,
1006  .setxattr = generic_setxattr,
1007  .getxattr = generic_getxattr,
1008  .removexattr = generic_removexattr,
1009  .listxattr = v9fs_listxattr,
1010  .get_acl = v9fs_iop_get_acl,
1011 };
1012 
1014  .getattr = v9fs_vfs_getattr_dotl,
1015  .setattr = v9fs_vfs_setattr_dotl,
1016  .setxattr = generic_setxattr,
1017  .getxattr = generic_getxattr,
1018  .removexattr = generic_removexattr,
1019  .listxattr = v9fs_listxattr,
1020  .get_acl = v9fs_iop_get_acl,
1021 };
1022 
1024  .readlink = generic_readlink,
1025  .follow_link = v9fs_vfs_follow_link_dotl,
1026  .put_link = v9fs_vfs_put_link,
1027  .getattr = v9fs_vfs_getattr_dotl,
1028  .setattr = v9fs_vfs_setattr_dotl,
1029  .setxattr = generic_setxattr,
1030  .getxattr = generic_getxattr,
1031  .removexattr = generic_removexattr,
1032  .listxattr = v9fs_listxattr,
1033 };