GNU Linux-libre 6.8.7-gnu
[releases.git] / fs / 9p / vfs_inode.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * This file contains vfs inode ops for the 9P2000 protocol.
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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
11 #include <linux/module.h>
12 #include <linux/errno.h>
13 #include <linux/fs.h>
14 #include <linux/file.h>
15 #include <linux/pagemap.h>
16 #include <linux/stat.h>
17 #include <linux/string.h>
18 #include <linux/namei.h>
19 #include <linux/sched.h>
20 #include <linux/slab.h>
21 #include <linux/xattr.h>
22 #include <linux/posix_acl.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 #include "xattr.h"
31 #include "acl.h"
32
33 static const struct inode_operations v9fs_dir_inode_operations;
34 static const struct inode_operations v9fs_dir_inode_operations_dotu;
35 static const struct inode_operations v9fs_file_inode_operations;
36 static const struct inode_operations v9fs_symlink_inode_operations;
37
38 /**
39  * unixmode2p9mode - convert unix mode bits to plan 9
40  * @v9ses: v9fs session information
41  * @mode: mode to convert
42  *
43  */
44
45 static u32 unixmode2p9mode(struct v9fs_session_info *v9ses, umode_t mode)
46 {
47         int res;
48
49         res = mode & 0777;
50         if (S_ISDIR(mode))
51                 res |= P9_DMDIR;
52         if (v9fs_proto_dotu(v9ses)) {
53                 if (v9ses->nodev == 0) {
54                         if (S_ISSOCK(mode))
55                                 res |= P9_DMSOCKET;
56                         if (S_ISFIFO(mode))
57                                 res |= P9_DMNAMEDPIPE;
58                         if (S_ISBLK(mode))
59                                 res |= P9_DMDEVICE;
60                         if (S_ISCHR(mode))
61                                 res |= P9_DMDEVICE;
62                 }
63
64                 if ((mode & S_ISUID) == S_ISUID)
65                         res |= P9_DMSETUID;
66                 if ((mode & S_ISGID) == S_ISGID)
67                         res |= P9_DMSETGID;
68                 if ((mode & S_ISVTX) == S_ISVTX)
69                         res |= P9_DMSETVTX;
70         }
71         return res;
72 }
73
74 /**
75  * p9mode2perm- convert plan9 mode bits to unix permission bits
76  * @v9ses: v9fs session information
77  * @stat: p9_wstat from which mode need to be derived
78  *
79  */
80 static int p9mode2perm(struct v9fs_session_info *v9ses,
81                        struct p9_wstat *stat)
82 {
83         int res;
84         int mode = stat->mode;
85
86         res = mode & S_IALLUGO;
87         if (v9fs_proto_dotu(v9ses)) {
88                 if ((mode & P9_DMSETUID) == P9_DMSETUID)
89                         res |= S_ISUID;
90
91                 if ((mode & P9_DMSETGID) == P9_DMSETGID)
92                         res |= S_ISGID;
93
94                 if ((mode & P9_DMSETVTX) == P9_DMSETVTX)
95                         res |= S_ISVTX;
96         }
97         return res;
98 }
99
100 /**
101  * p9mode2unixmode- convert plan9 mode bits to unix mode bits
102  * @v9ses: v9fs session information
103  * @stat: p9_wstat from which mode need to be derived
104  * @rdev: major number, minor number in case of device files.
105  *
106  */
107 static umode_t p9mode2unixmode(struct v9fs_session_info *v9ses,
108                                struct p9_wstat *stat, dev_t *rdev)
109 {
110         int res, r;
111         u32 mode = stat->mode;
112
113         *rdev = 0;
114         res = p9mode2perm(v9ses, stat);
115
116         if ((mode & P9_DMDIR) == P9_DMDIR)
117                 res |= S_IFDIR;
118         else if ((mode & P9_DMSYMLINK) && (v9fs_proto_dotu(v9ses)))
119                 res |= S_IFLNK;
120         else if ((mode & P9_DMSOCKET) && (v9fs_proto_dotu(v9ses))
121                  && (v9ses->nodev == 0))
122                 res |= S_IFSOCK;
123         else if ((mode & P9_DMNAMEDPIPE) && (v9fs_proto_dotu(v9ses))
124                  && (v9ses->nodev == 0))
125                 res |= S_IFIFO;
126         else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses))
127                  && (v9ses->nodev == 0)) {
128                 char type = 0;
129                 int major = -1, minor = -1;
130
131                 r = sscanf(stat->extension, "%c %i %i", &type, &major, &minor);
132                 if (r != 3) {
133                         p9_debug(P9_DEBUG_ERROR,
134                                  "invalid device string, umode will be bogus: %s\n",
135                                  stat->extension);
136                         return res;
137                 }
138                 switch (type) {
139                 case 'c':
140                         res |= S_IFCHR;
141                         break;
142                 case 'b':
143                         res |= S_IFBLK;
144                         break;
145                 default:
146                         p9_debug(P9_DEBUG_ERROR, "Unknown special type %c %s\n",
147                                  type, stat->extension);
148                 }
149                 *rdev = MKDEV(major, minor);
150         } else
151                 res |= S_IFREG;
152
153         return res;
154 }
155
156 /**
157  * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits
158  * @uflags: flags to convert
159  * @extended: if .u extensions are active
160  */
161
162 int v9fs_uflags2omode(int uflags, int extended)
163 {
164         int ret;
165
166         switch (uflags&3) {
167         default:
168         case O_RDONLY:
169                 ret = P9_OREAD;
170                 break;
171
172         case O_WRONLY:
173                 ret = P9_OWRITE;
174                 break;
175
176         case O_RDWR:
177                 ret = P9_ORDWR;
178                 break;
179         }
180
181         if (extended) {
182                 if (uflags & O_EXCL)
183                         ret |= P9_OEXCL;
184
185                 if (uflags & O_APPEND)
186                         ret |= P9_OAPPEND;
187         }
188
189         return ret;
190 }
191
192 /**
193  * v9fs_blank_wstat - helper function to setup a 9P stat structure
194  * @wstat: structure to initialize
195  *
196  */
197
198 void
199 v9fs_blank_wstat(struct p9_wstat *wstat)
200 {
201         wstat->type = ~0;
202         wstat->dev = ~0;
203         wstat->qid.type = ~0;
204         wstat->qid.version = ~0;
205         *((long long *)&wstat->qid.path) = ~0;
206         wstat->mode = ~0;
207         wstat->atime = ~0;
208         wstat->mtime = ~0;
209         wstat->length = ~0;
210         wstat->name = NULL;
211         wstat->uid = NULL;
212         wstat->gid = NULL;
213         wstat->muid = NULL;
214         wstat->n_uid = INVALID_UID;
215         wstat->n_gid = INVALID_GID;
216         wstat->n_muid = INVALID_UID;
217         wstat->extension = NULL;
218 }
219
220 /**
221  * v9fs_alloc_inode - helper function to allocate an inode
222  * @sb: The superblock to allocate the inode from
223  */
224 struct inode *v9fs_alloc_inode(struct super_block *sb)
225 {
226         struct v9fs_inode *v9inode;
227
228         v9inode = alloc_inode_sb(sb, v9fs_inode_cache, GFP_KERNEL);
229         if (!v9inode)
230                 return NULL;
231         v9inode->cache_validity = 0;
232         mutex_init(&v9inode->v_mutex);
233         return &v9inode->netfs.inode;
234 }
235
236 /**
237  * v9fs_free_inode - destroy an inode
238  * @inode: The inode to be freed
239  */
240
241 void v9fs_free_inode(struct inode *inode)
242 {
243         kmem_cache_free(v9fs_inode_cache, V9FS_I(inode));
244 }
245
246 /*
247  * Set parameters for the netfs library
248  */
249 void v9fs_set_netfs_context(struct inode *inode)
250 {
251         struct v9fs_inode *v9inode = V9FS_I(inode);
252         netfs_inode_init(&v9inode->netfs, &v9fs_req_ops, true);
253 }
254
255 int v9fs_init_inode(struct v9fs_session_info *v9ses,
256                     struct inode *inode, umode_t mode, dev_t rdev)
257 {
258         int err = 0;
259
260         inode_init_owner(&nop_mnt_idmap, inode, NULL, mode);
261         inode->i_blocks = 0;
262         inode->i_rdev = rdev;
263         simple_inode_init_ts(inode);
264         inode->i_mapping->a_ops = &v9fs_addr_operations;
265         inode->i_private = NULL;
266
267         switch (mode & S_IFMT) {
268         case S_IFIFO:
269         case S_IFBLK:
270         case S_IFCHR:
271         case S_IFSOCK:
272                 if (v9fs_proto_dotl(v9ses)) {
273                         inode->i_op = &v9fs_file_inode_operations_dotl;
274                 } else if (v9fs_proto_dotu(v9ses)) {
275                         inode->i_op = &v9fs_file_inode_operations;
276                 } else {
277                         p9_debug(P9_DEBUG_ERROR,
278                                  "special files without extended mode\n");
279                         err = -EINVAL;
280                         goto error;
281                 }
282                 init_special_inode(inode, inode->i_mode, inode->i_rdev);
283                 break;
284         case S_IFREG:
285                 if (v9fs_proto_dotl(v9ses)) {
286                         inode->i_op = &v9fs_file_inode_operations_dotl;
287                         inode->i_fop = &v9fs_file_operations_dotl;
288                 } else {
289                         inode->i_op = &v9fs_file_inode_operations;
290                         inode->i_fop = &v9fs_file_operations;
291                 }
292
293                 break;
294         case S_IFLNK:
295                 if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)) {
296                         p9_debug(P9_DEBUG_ERROR,
297                                  "extended modes used with legacy protocol\n");
298                         err = -EINVAL;
299                         goto error;
300                 }
301
302                 if (v9fs_proto_dotl(v9ses))
303                         inode->i_op = &v9fs_symlink_inode_operations_dotl;
304                 else
305                         inode->i_op = &v9fs_symlink_inode_operations;
306
307                 break;
308         case S_IFDIR:
309                 inc_nlink(inode);
310                 if (v9fs_proto_dotl(v9ses))
311                         inode->i_op = &v9fs_dir_inode_operations_dotl;
312                 else if (v9fs_proto_dotu(v9ses))
313                         inode->i_op = &v9fs_dir_inode_operations_dotu;
314                 else
315                         inode->i_op = &v9fs_dir_inode_operations;
316
317                 if (v9fs_proto_dotl(v9ses))
318                         inode->i_fop = &v9fs_dir_operations_dotl;
319                 else
320                         inode->i_fop = &v9fs_dir_operations;
321
322                 break;
323         default:
324                 p9_debug(P9_DEBUG_ERROR, "BAD mode 0x%hx S_IFMT 0x%x\n",
325                          mode, mode & S_IFMT);
326                 err = -EINVAL;
327                 goto error;
328         }
329 error:
330         return err;
331
332 }
333
334 /**
335  * v9fs_get_inode - helper function to setup an inode
336  * @sb: superblock
337  * @mode: mode to setup inode with
338  * @rdev: The device numbers to set
339  */
340
341 struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t rdev)
342 {
343         int err;
344         struct inode *inode;
345         struct v9fs_session_info *v9ses = sb->s_fs_info;
346
347         p9_debug(P9_DEBUG_VFS, "super block: %p mode: %ho\n", sb, mode);
348
349         inode = new_inode(sb);
350         if (!inode) {
351                 pr_warn("%s (%d): Problem allocating inode\n",
352                         __func__, task_pid_nr(current));
353                 return ERR_PTR(-ENOMEM);
354         }
355         err = v9fs_init_inode(v9ses, inode, mode, rdev);
356         if (err) {
357                 iput(inode);
358                 return ERR_PTR(err);
359         }
360         v9fs_set_netfs_context(inode);
361         return inode;
362 }
363
364 /**
365  * v9fs_evict_inode - Remove an inode from the inode cache
366  * @inode: inode to release
367  *
368  */
369 void v9fs_evict_inode(struct inode *inode)
370 {
371         struct v9fs_inode __maybe_unused *v9inode = V9FS_I(inode);
372         __le32 __maybe_unused version;
373
374         truncate_inode_pages_final(&inode->i_data);
375
376         version = cpu_to_le32(v9inode->qid.version);
377         netfs_clear_inode_writeback(inode, &version);
378
379         clear_inode(inode);
380         filemap_fdatawrite(&inode->i_data);
381
382 #ifdef CONFIG_9P_FSCACHE
383         fscache_relinquish_cookie(v9fs_inode_cookie(v9inode), false);
384 #endif
385 }
386
387 static int v9fs_test_inode(struct inode *inode, void *data)
388 {
389         int umode;
390         dev_t rdev;
391         struct v9fs_inode *v9inode = V9FS_I(inode);
392         struct p9_wstat *st = (struct p9_wstat *)data;
393         struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
394
395         umode = p9mode2unixmode(v9ses, st, &rdev);
396         /* don't match inode of different type */
397         if (inode_wrong_type(inode, umode))
398                 return 0;
399
400         /* compare qid details */
401         if (memcmp(&v9inode->qid.version,
402                    &st->qid.version, sizeof(v9inode->qid.version)))
403                 return 0;
404
405         if (v9inode->qid.type != st->qid.type)
406                 return 0;
407
408         if (v9inode->qid.path != st->qid.path)
409                 return 0;
410         return 1;
411 }
412
413 static int v9fs_test_new_inode(struct inode *inode, void *data)
414 {
415         return 0;
416 }
417
418 static int v9fs_set_inode(struct inode *inode,  void *data)
419 {
420         struct v9fs_inode *v9inode = V9FS_I(inode);
421         struct p9_wstat *st = (struct p9_wstat *)data;
422
423         memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
424         return 0;
425 }
426
427 static struct inode *v9fs_qid_iget(struct super_block *sb,
428                                    struct p9_qid *qid,
429                                    struct p9_wstat *st,
430                                    int new)
431 {
432         dev_t rdev;
433         int retval;
434         umode_t umode;
435         unsigned long i_ino;
436         struct inode *inode;
437         struct v9fs_session_info *v9ses = sb->s_fs_info;
438         int (*test)(struct inode *inode, void *data);
439
440         if (new)
441                 test = v9fs_test_new_inode;
442         else
443                 test = v9fs_test_inode;
444
445         i_ino = v9fs_qid2ino(qid);
446         inode = iget5_locked(sb, i_ino, test, v9fs_set_inode, st);
447         if (!inode)
448                 return ERR_PTR(-ENOMEM);
449         if (!(inode->i_state & I_NEW))
450                 return inode;
451         /*
452          * initialize the inode with the stat info
453          * FIXME!! we may need support for stale inodes
454          * later.
455          */
456         inode->i_ino = i_ino;
457         umode = p9mode2unixmode(v9ses, st, &rdev);
458         retval = v9fs_init_inode(v9ses, inode, umode, rdev);
459         if (retval)
460                 goto error;
461
462         v9fs_stat2inode(st, inode, sb, 0);
463         v9fs_set_netfs_context(inode);
464         v9fs_cache_inode_get_cookie(inode);
465         unlock_new_inode(inode);
466         return inode;
467 error:
468         iget_failed(inode);
469         return ERR_PTR(retval);
470
471 }
472
473 struct inode *
474 v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
475                     struct super_block *sb, int new)
476 {
477         struct p9_wstat *st;
478         struct inode *inode = NULL;
479
480         st = p9_client_stat(fid);
481         if (IS_ERR(st))
482                 return ERR_CAST(st);
483
484         inode = v9fs_qid_iget(sb, &st->qid, st, new);
485         p9stat_free(st);
486         kfree(st);
487         return inode;
488 }
489
490 /**
491  * v9fs_at_to_dotl_flags- convert Linux specific AT flags to
492  * plan 9 AT flag.
493  * @flags: flags to convert
494  */
495 static int v9fs_at_to_dotl_flags(int flags)
496 {
497         int rflags = 0;
498
499         if (flags & AT_REMOVEDIR)
500                 rflags |= P9_DOTL_AT_REMOVEDIR;
501
502         return rflags;
503 }
504
505 /**
506  * v9fs_dec_count - helper functon to drop i_nlink.
507  *
508  * If a directory had nlink <= 2 (including . and ..), then we should not drop
509  * the link count, which indicates the underlying exported fs doesn't maintain
510  * nlink accurately. e.g.
511  * - overlayfs sets nlink to 1 for merged dir
512  * - ext4 (with dir_nlink feature enabled) sets nlink to 1 if a dir has more
513  *   than EXT4_LINK_MAX (65000) links.
514  *
515  * @inode: inode whose nlink is being dropped
516  */
517 static void v9fs_dec_count(struct inode *inode)
518 {
519         if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2)
520                 drop_nlink(inode);
521 }
522
523 /**
524  * v9fs_remove - helper function to remove files and directories
525  * @dir: directory inode that is being deleted
526  * @dentry:  dentry that is being deleted
527  * @flags: removing a directory
528  *
529  */
530
531 static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
532 {
533         struct inode *inode;
534         int retval = -EOPNOTSUPP;
535         struct p9_fid *v9fid, *dfid;
536         struct v9fs_session_info *v9ses;
537
538         p9_debug(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %x\n",
539                  dir, dentry, flags);
540
541         v9ses = v9fs_inode2v9ses(dir);
542         inode = d_inode(dentry);
543         dfid = v9fs_parent_fid(dentry);
544         if (IS_ERR(dfid)) {
545                 retval = PTR_ERR(dfid);
546                 p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", retval);
547                 return retval;
548         }
549         if (v9fs_proto_dotl(v9ses))
550                 retval = p9_client_unlinkat(dfid, dentry->d_name.name,
551                                             v9fs_at_to_dotl_flags(flags));
552         p9_fid_put(dfid);
553         if (retval == -EOPNOTSUPP) {
554                 /* Try the one based on path */
555                 v9fid = v9fs_fid_clone(dentry);
556                 if (IS_ERR(v9fid))
557                         return PTR_ERR(v9fid);
558                 retval = p9_client_remove(v9fid);
559         }
560         if (!retval) {
561                 /*
562                  * directories on unlink should have zero
563                  * link count
564                  */
565                 if (flags & AT_REMOVEDIR) {
566                         clear_nlink(inode);
567                         v9fs_dec_count(dir);
568                 } else
569                         v9fs_dec_count(inode);
570
571                 v9fs_invalidate_inode_attr(inode);
572                 v9fs_invalidate_inode_attr(dir);
573
574                 /* invalidate all fids associated with dentry */
575                 /* NOTE: This will not include open fids */
576                 dentry->d_op->d_release(dentry);
577         }
578         return retval;
579 }
580
581 /**
582  * v9fs_create - Create a file
583  * @v9ses: session information
584  * @dir: directory that dentry is being created in
585  * @dentry:  dentry that is being created
586  * @extension: 9p2000.u extension string to support devices, etc.
587  * @perm: create permissions
588  * @mode: open mode
589  *
590  */
591 static struct p9_fid *
592 v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
593                 struct dentry *dentry, char *extension, u32 perm, u8 mode)
594 {
595         int err;
596         const unsigned char *name;
597         struct p9_fid *dfid, *ofid = NULL, *fid = NULL;
598         struct inode *inode;
599
600         p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry);
601
602         name = dentry->d_name.name;
603         dfid = v9fs_parent_fid(dentry);
604         if (IS_ERR(dfid)) {
605                 err = PTR_ERR(dfid);
606                 p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
607                 return ERR_PTR(err);
608         }
609
610         /* clone a fid to use for creation */
611         ofid = clone_fid(dfid);
612         if (IS_ERR(ofid)) {
613                 err = PTR_ERR(ofid);
614                 p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
615                 goto error;
616         }
617
618         err = p9_client_fcreate(ofid, name, perm, mode, extension);
619         if (err < 0) {
620                 p9_debug(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err);
621                 goto error;
622         }
623
624         if (!(perm & P9_DMLINK)) {
625                 /* now walk from the parent so we can get unopened fid */
626                 fid = p9_client_walk(dfid, 1, &name, 1);
627                 if (IS_ERR(fid)) {
628                         err = PTR_ERR(fid);
629                         p9_debug(P9_DEBUG_VFS,
630                                    "p9_client_walk failed %d\n", err);
631                         goto error;
632                 }
633                 /*
634                  * instantiate inode and assign the unopened fid to the dentry
635                  */
636                 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
637                 if (IS_ERR(inode)) {
638                         err = PTR_ERR(inode);
639                         p9_debug(P9_DEBUG_VFS,
640                                    "inode creation failed %d\n", err);
641                         goto error;
642                 }
643                 v9fs_fid_add(dentry, &fid);
644                 d_instantiate(dentry, inode);
645         }
646         p9_fid_put(dfid);
647         return ofid;
648 error:
649         p9_fid_put(dfid);
650         p9_fid_put(ofid);
651         p9_fid_put(fid);
652         return ERR_PTR(err);
653 }
654
655 /**
656  * v9fs_vfs_create - VFS hook to create a regular file
657  * @idmap: idmap of the mount
658  * @dir: The parent directory
659  * @dentry: The name of file to be created
660  * @mode: The UNIX file mode to set
661  * @excl: True if the file must not yet exist
662  *
663  * open(.., O_CREAT) is handled in v9fs_vfs_atomic_open().  This is only called
664  * for mknod(2).
665  *
666  */
667
668 static int
669 v9fs_vfs_create(struct mnt_idmap *idmap, struct inode *dir,
670                 struct dentry *dentry, umode_t mode, bool excl)
671 {
672         struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
673         u32 perm = unixmode2p9mode(v9ses, mode);
674         struct p9_fid *fid;
675
676         /* P9_OEXCL? */
677         fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_ORDWR);
678         if (IS_ERR(fid))
679                 return PTR_ERR(fid);
680
681         v9fs_invalidate_inode_attr(dir);
682         p9_fid_put(fid);
683
684         return 0;
685 }
686
687 /**
688  * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
689  * @idmap: idmap of the mount
690  * @dir:  inode that is being unlinked
691  * @dentry: dentry that is being unlinked
692  * @mode: mode for new directory
693  *
694  */
695
696 static int v9fs_vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
697                           struct dentry *dentry, umode_t mode)
698 {
699         int err;
700         u32 perm;
701         struct p9_fid *fid;
702         struct v9fs_session_info *v9ses;
703
704         p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry);
705         err = 0;
706         v9ses = v9fs_inode2v9ses(dir);
707         perm = unixmode2p9mode(v9ses, mode | S_IFDIR);
708         fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_OREAD);
709         if (IS_ERR(fid)) {
710                 err = PTR_ERR(fid);
711                 fid = NULL;
712         } else {
713                 inc_nlink(dir);
714                 v9fs_invalidate_inode_attr(dir);
715         }
716
717         if (fid)
718                 p9_fid_put(fid);
719
720         return err;
721 }
722
723 /**
724  * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
725  * @dir:  inode that is being walked from
726  * @dentry: dentry that is being walked to?
727  * @flags: lookup flags (unused)
728  *
729  */
730
731 struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
732                                       unsigned int flags)
733 {
734         struct dentry *res;
735         struct v9fs_session_info *v9ses;
736         struct p9_fid *dfid, *fid;
737         struct inode *inode;
738         const unsigned char *name;
739
740         p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%pd) %p flags: %x\n",
741                  dir, dentry, dentry, flags);
742
743         if (dentry->d_name.len > NAME_MAX)
744                 return ERR_PTR(-ENAMETOOLONG);
745
746         v9ses = v9fs_inode2v9ses(dir);
747         /* We can walk d_parent because we hold the dir->i_mutex */
748         dfid = v9fs_parent_fid(dentry);
749         if (IS_ERR(dfid))
750                 return ERR_CAST(dfid);
751
752         /*
753          * Make sure we don't use a wrong inode due to parallel
754          * unlink. For cached mode create calls request for new
755          * inode. But with cache disabled, lookup should do this.
756          */
757         name = dentry->d_name.name;
758         fid = p9_client_walk(dfid, 1, &name, 1);
759         p9_fid_put(dfid);
760         if (fid == ERR_PTR(-ENOENT))
761                 inode = NULL;
762         else if (IS_ERR(fid))
763                 inode = ERR_CAST(fid);
764         else if (v9ses->cache & (CACHE_META|CACHE_LOOSE))
765                 inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
766         else
767                 inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
768         /*
769          * If we had a rename on the server and a parallel lookup
770          * for the new name, then make sure we instantiate with
771          * the new name. ie look up for a/b, while on server somebody
772          * moved b under k and client parallely did a lookup for
773          * k/b.
774          */
775         res = d_splice_alias(inode, dentry);
776         if (!IS_ERR(fid)) {
777                 if (!res)
778                         v9fs_fid_add(dentry, &fid);
779                 else if (!IS_ERR(res))
780                         v9fs_fid_add(res, &fid);
781                 else
782                         p9_fid_put(fid);
783         }
784         return res;
785 }
786
787 static int
788 v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
789                      struct file *file, unsigned int flags, umode_t mode)
790 {
791         int err;
792         u32 perm;
793         struct v9fs_inode __maybe_unused *v9inode;
794         struct v9fs_session_info *v9ses;
795         struct p9_fid *fid;
796         struct dentry *res = NULL;
797         struct inode *inode;
798         int p9_omode;
799
800         if (d_in_lookup(dentry)) {
801                 res = v9fs_vfs_lookup(dir, dentry, 0);
802                 if (IS_ERR(res))
803                         return PTR_ERR(res);
804
805                 if (res)
806                         dentry = res;
807         }
808
809         /* Only creates */
810         if (!(flags & O_CREAT) || d_really_is_positive(dentry))
811                 return finish_no_open(file, res);
812
813         v9ses = v9fs_inode2v9ses(dir);
814         perm = unixmode2p9mode(v9ses, mode);
815         p9_omode = v9fs_uflags2omode(flags, v9fs_proto_dotu(v9ses));
816
817         if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) {
818                 p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR;
819                 p9_debug(P9_DEBUG_CACHE,
820                         "write-only file with writeback enabled, creating w/ O_RDWR\n");
821         }
822         fid = v9fs_create(v9ses, dir, dentry, NULL, perm, p9_omode);
823         if (IS_ERR(fid)) {
824                 err = PTR_ERR(fid);
825                 goto error;
826         }
827
828         v9fs_invalidate_inode_attr(dir);
829         inode = d_inode(dentry);
830         v9inode = V9FS_I(inode);
831         err = finish_open(file, dentry, generic_file_open);
832         if (err)
833                 goto error;
834
835         file->private_data = fid;
836 #ifdef CONFIG_9P_FSCACHE
837         if (v9ses->cache & CACHE_FSCACHE)
838                 fscache_use_cookie(v9fs_inode_cookie(v9inode),
839                                    file->f_mode & FMODE_WRITE);
840 #endif
841
842         v9fs_fid_add_modes(fid, v9ses->flags, v9ses->cache, file->f_flags);
843         v9fs_open_fid_add(inode, &fid);
844
845         file->f_mode |= FMODE_CREATED;
846 out:
847         dput(res);
848         return err;
849
850 error:
851         p9_fid_put(fid);
852         goto out;
853 }
854
855 /**
856  * v9fs_vfs_unlink - VFS unlink hook to delete an inode
857  * @i:  inode that is being unlinked
858  * @d: dentry that is being unlinked
859  *
860  */
861
862 int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
863 {
864         return v9fs_remove(i, d, 0);
865 }
866
867 /**
868  * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
869  * @i:  inode that is being unlinked
870  * @d: dentry that is being unlinked
871  *
872  */
873
874 int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
875 {
876         return v9fs_remove(i, d, AT_REMOVEDIR);
877 }
878
879 /**
880  * v9fs_vfs_rename - VFS hook to rename an inode
881  * @idmap: The idmap of the mount
882  * @old_dir:  old dir inode
883  * @old_dentry: old dentry
884  * @new_dir: new dir inode
885  * @new_dentry: new dentry
886  * @flags: RENAME_* flags
887  *
888  */
889
890 int
891 v9fs_vfs_rename(struct mnt_idmap *idmap, struct inode *old_dir,
892                 struct dentry *old_dentry, struct inode *new_dir,
893                 struct dentry *new_dentry, unsigned int flags)
894 {
895         int retval;
896         struct inode *old_inode;
897         struct inode *new_inode;
898         struct v9fs_session_info *v9ses;
899         struct p9_fid *oldfid = NULL, *dfid = NULL;
900         struct p9_fid *olddirfid = NULL;
901         struct p9_fid *newdirfid = NULL;
902         struct p9_wstat wstat;
903
904         if (flags)
905                 return -EINVAL;
906
907         p9_debug(P9_DEBUG_VFS, "\n");
908         old_inode = d_inode(old_dentry);
909         new_inode = d_inode(new_dentry);
910         v9ses = v9fs_inode2v9ses(old_inode);
911         oldfid = v9fs_fid_lookup(old_dentry);
912         if (IS_ERR(oldfid))
913                 return PTR_ERR(oldfid);
914
915         dfid = v9fs_parent_fid(old_dentry);
916         olddirfid = clone_fid(dfid);
917         p9_fid_put(dfid);
918         dfid = NULL;
919
920         if (IS_ERR(olddirfid)) {
921                 retval = PTR_ERR(olddirfid);
922                 goto error;
923         }
924
925         dfid = v9fs_parent_fid(new_dentry);
926         newdirfid = clone_fid(dfid);
927         p9_fid_put(dfid);
928         dfid = NULL;
929
930         if (IS_ERR(newdirfid)) {
931                 retval = PTR_ERR(newdirfid);
932                 goto error;
933         }
934
935         down_write(&v9ses->rename_sem);
936         if (v9fs_proto_dotl(v9ses)) {
937                 retval = p9_client_renameat(olddirfid, old_dentry->d_name.name,
938                                             newdirfid, new_dentry->d_name.name);
939                 if (retval == -EOPNOTSUPP)
940                         retval = p9_client_rename(oldfid, newdirfid,
941                                                   new_dentry->d_name.name);
942                 if (retval != -EOPNOTSUPP)
943                         goto error_locked;
944         }
945         if (old_dentry->d_parent != new_dentry->d_parent) {
946                 /*
947                  * 9P .u can only handle file rename in the same directory
948                  */
949
950                 p9_debug(P9_DEBUG_ERROR, "old dir and new dir are different\n");
951                 retval = -EXDEV;
952                 goto error_locked;
953         }
954         v9fs_blank_wstat(&wstat);
955         wstat.muid = v9ses->uname;
956         wstat.name = new_dentry->d_name.name;
957         retval = p9_client_wstat(oldfid, &wstat);
958
959 error_locked:
960         if (!retval) {
961                 if (new_inode) {
962                         if (S_ISDIR(new_inode->i_mode))
963                                 clear_nlink(new_inode);
964                         else
965                                 v9fs_dec_count(new_inode);
966                 }
967                 if (S_ISDIR(old_inode->i_mode)) {
968                         if (!new_inode)
969                                 inc_nlink(new_dir);
970                         v9fs_dec_count(old_dir);
971                 }
972                 v9fs_invalidate_inode_attr(old_inode);
973                 v9fs_invalidate_inode_attr(old_dir);
974                 v9fs_invalidate_inode_attr(new_dir);
975
976                 /* successful rename */
977                 d_move(old_dentry, new_dentry);
978         }
979         up_write(&v9ses->rename_sem);
980
981 error:
982         p9_fid_put(newdirfid);
983         p9_fid_put(olddirfid);
984         p9_fid_put(oldfid);
985         return retval;
986 }
987
988 /**
989  * v9fs_vfs_getattr - retrieve file metadata
990  * @idmap: idmap of the mount
991  * @path: Object to query
992  * @stat: metadata structure to populate
993  * @request_mask: Mask of STATX_xxx flags indicating the caller's interests
994  * @flags: AT_STATX_xxx setting
995  *
996  */
997
998 static int
999 v9fs_vfs_getattr(struct mnt_idmap *idmap, const struct path *path,
1000                  struct kstat *stat, u32 request_mask, unsigned int flags)
1001 {
1002         struct dentry *dentry = path->dentry;
1003         struct inode *inode = d_inode(dentry);
1004         struct v9fs_session_info *v9ses;
1005         struct p9_fid *fid;
1006         struct p9_wstat *st;
1007
1008         p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
1009         v9ses = v9fs_dentry2v9ses(dentry);
1010         if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
1011                 generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat);
1012                 return 0;
1013         } else if (v9ses->cache & CACHE_WRITEBACK) {
1014                 if (S_ISREG(inode->i_mode)) {
1015                         int retval = filemap_fdatawrite(inode->i_mapping);
1016
1017                         if (retval)
1018                                 p9_debug(P9_DEBUG_ERROR,
1019                                     "flushing writeback during getattr returned %d\n", retval);
1020                 }
1021         }
1022         fid = v9fs_fid_lookup(dentry);
1023         if (IS_ERR(fid))
1024                 return PTR_ERR(fid);
1025
1026         st = p9_client_stat(fid);
1027         p9_fid_put(fid);
1028         if (IS_ERR(st))
1029                 return PTR_ERR(st);
1030
1031         v9fs_stat2inode(st, d_inode(dentry), dentry->d_sb, 0);
1032         generic_fillattr(&nop_mnt_idmap, request_mask, d_inode(dentry), stat);
1033
1034         p9stat_free(st);
1035         kfree(st);
1036         return 0;
1037 }
1038
1039 /**
1040  * v9fs_vfs_setattr - set file metadata
1041  * @idmap: idmap of the mount
1042  * @dentry: file whose metadata to set
1043  * @iattr: metadata assignment structure
1044  *
1045  */
1046
1047 static int v9fs_vfs_setattr(struct mnt_idmap *idmap,
1048                             struct dentry *dentry, struct iattr *iattr)
1049 {
1050         int retval, use_dentry = 0;
1051         struct inode *inode = d_inode(dentry);
1052         struct v9fs_session_info *v9ses;
1053         struct p9_fid *fid = NULL;
1054         struct p9_wstat wstat;
1055
1056         p9_debug(P9_DEBUG_VFS, "\n");
1057         retval = setattr_prepare(&nop_mnt_idmap, dentry, iattr);
1058         if (retval)
1059                 return retval;
1060
1061         v9ses = v9fs_dentry2v9ses(dentry);
1062         if (iattr->ia_valid & ATTR_FILE) {
1063                 fid = iattr->ia_file->private_data;
1064                 WARN_ON(!fid);
1065         }
1066         if (!fid) {
1067                 fid = v9fs_fid_lookup(dentry);
1068                 use_dentry = 1;
1069         }
1070         if (IS_ERR(fid))
1071                 return PTR_ERR(fid);
1072
1073         v9fs_blank_wstat(&wstat);
1074         if (iattr->ia_valid & ATTR_MODE)
1075                 wstat.mode = unixmode2p9mode(v9ses, iattr->ia_mode);
1076
1077         if (iattr->ia_valid & ATTR_MTIME)
1078                 wstat.mtime = iattr->ia_mtime.tv_sec;
1079
1080         if (iattr->ia_valid & ATTR_ATIME)
1081                 wstat.atime = iattr->ia_atime.tv_sec;
1082
1083         if (iattr->ia_valid & ATTR_SIZE)
1084                 wstat.length = iattr->ia_size;
1085
1086         if (v9fs_proto_dotu(v9ses)) {
1087                 if (iattr->ia_valid & ATTR_UID)
1088                         wstat.n_uid = iattr->ia_uid;
1089
1090                 if (iattr->ia_valid & ATTR_GID)
1091                         wstat.n_gid = iattr->ia_gid;
1092         }
1093
1094         /* Write all dirty data */
1095         if (d_is_reg(dentry)) {
1096                 retval = filemap_fdatawrite(inode->i_mapping);
1097                 if (retval)
1098                         p9_debug(P9_DEBUG_ERROR,
1099                             "flushing writeback during setattr returned %d\n", retval);
1100         }
1101
1102         retval = p9_client_wstat(fid, &wstat);
1103
1104         if (use_dentry)
1105                 p9_fid_put(fid);
1106
1107         if (retval < 0)
1108                 return retval;
1109
1110         if ((iattr->ia_valid & ATTR_SIZE) &&
1111                  iattr->ia_size != i_size_read(inode)) {
1112                 truncate_setsize(inode, iattr->ia_size);
1113                 netfs_resize_file(netfs_inode(inode), iattr->ia_size, true);
1114
1115 #ifdef CONFIG_9P_FSCACHE
1116                 if (v9ses->cache & CACHE_FSCACHE) {
1117                         struct v9fs_inode *v9inode = V9FS_I(inode);
1118
1119                         fscache_resize_cookie(v9fs_inode_cookie(v9inode), iattr->ia_size);
1120                 }
1121 #endif
1122         }
1123
1124         v9fs_invalidate_inode_attr(inode);
1125
1126         setattr_copy(&nop_mnt_idmap, inode, iattr);
1127         mark_inode_dirty(inode);
1128         return 0;
1129 }
1130
1131 /**
1132  * v9fs_stat2inode - populate an inode structure with mistat info
1133  * @stat: Plan 9 metadata (mistat) structure
1134  * @inode: inode to populate
1135  * @sb: superblock of filesystem
1136  * @flags: control flags (e.g. V9FS_STAT2INODE_KEEP_ISIZE)
1137  *
1138  */
1139
1140 void
1141 v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
1142                  struct super_block *sb, unsigned int flags)
1143 {
1144         umode_t mode;
1145         struct v9fs_session_info *v9ses = sb->s_fs_info;
1146         struct v9fs_inode *v9inode = V9FS_I(inode);
1147
1148         set_nlink(inode, 1);
1149
1150         inode_set_atime(inode, stat->atime, 0);
1151         inode_set_mtime(inode, stat->mtime, 0);
1152         inode_set_ctime(inode, stat->mtime, 0);
1153
1154         inode->i_uid = v9ses->dfltuid;
1155         inode->i_gid = v9ses->dfltgid;
1156
1157         if (v9fs_proto_dotu(v9ses)) {
1158                 inode->i_uid = stat->n_uid;
1159                 inode->i_gid = stat->n_gid;
1160         }
1161         if ((S_ISREG(inode->i_mode)) || (S_ISDIR(inode->i_mode))) {
1162                 if (v9fs_proto_dotu(v9ses)) {
1163                         unsigned int i_nlink;
1164                         /*
1165                          * Hadlink support got added later to the .u extension.
1166                          * So there can be a server out there that doesn't
1167                          * support this even with .u extension. That would
1168                          * just leave us with stat->extension being an empty
1169                          * string, though.
1170                          */
1171                         /* HARDLINKCOUNT %u */
1172                         if (sscanf(stat->extension,
1173                                    " HARDLINKCOUNT %u", &i_nlink) == 1)
1174                                 set_nlink(inode, i_nlink);
1175                 }
1176         }
1177         mode = p9mode2perm(v9ses, stat);
1178         mode |= inode->i_mode & ~S_IALLUGO;
1179         inode->i_mode = mode;
1180
1181         v9inode->netfs.remote_i_size = stat->length;
1182         if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE))
1183                 v9fs_i_size_write(inode, stat->length);
1184         /* not real number of blocks, but 512 byte ones ... */
1185         inode->i_blocks = (stat->length + 512 - 1) >> 9;
1186         v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
1187 }
1188
1189 /**
1190  * v9fs_qid2ino - convert qid into inode number
1191  * @qid: qid to hash
1192  *
1193  * BUG: potential for inode number collisions?
1194  */
1195
1196 ino_t v9fs_qid2ino(struct p9_qid *qid)
1197 {
1198         u64 path = qid->path + 2;
1199         ino_t i = 0;
1200
1201         if (sizeof(ino_t) == sizeof(path))
1202                 memcpy(&i, &path, sizeof(ino_t));
1203         else
1204                 i = (ino_t) (path ^ (path >> 32));
1205
1206         return i;
1207 }
1208
1209 /**
1210  * v9fs_vfs_get_link - follow a symlink path
1211  * @dentry: dentry for symlink
1212  * @inode: inode for symlink
1213  * @done: delayed call for when we are done with the return value
1214  */
1215
1216 static const char *v9fs_vfs_get_link(struct dentry *dentry,
1217                                      struct inode *inode,
1218                                      struct delayed_call *done)
1219 {
1220         struct v9fs_session_info *v9ses;
1221         struct p9_fid *fid;
1222         struct p9_wstat *st;
1223         char *res;
1224
1225         if (!dentry)
1226                 return ERR_PTR(-ECHILD);
1227
1228         v9ses = v9fs_dentry2v9ses(dentry);
1229         if (!v9fs_proto_dotu(v9ses))
1230                 return ERR_PTR(-EBADF);
1231
1232         p9_debug(P9_DEBUG_VFS, "%pd\n", dentry);
1233         fid = v9fs_fid_lookup(dentry);
1234
1235         if (IS_ERR(fid))
1236                 return ERR_CAST(fid);
1237
1238         st = p9_client_stat(fid);
1239         p9_fid_put(fid);
1240         if (IS_ERR(st))
1241                 return ERR_CAST(st);
1242
1243         if (!(st->mode & P9_DMSYMLINK)) {
1244                 p9stat_free(st);
1245                 kfree(st);
1246                 return ERR_PTR(-EINVAL);
1247         }
1248         res = st->extension;
1249         st->extension = NULL;
1250         if (strlen(res) >= PATH_MAX)
1251                 res[PATH_MAX - 1] = '\0';
1252
1253         p9stat_free(st);
1254         kfree(st);
1255         set_delayed_call(done, kfree_link, res);
1256         return res;
1257 }
1258
1259 /**
1260  * v9fs_vfs_mkspecial - create a special file
1261  * @dir: inode to create special file in
1262  * @dentry: dentry to create
1263  * @perm: mode to create special file
1264  * @extension: 9p2000.u format extension string representing special file
1265  *
1266  */
1267
1268 static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
1269         u32 perm, const char *extension)
1270 {
1271         struct p9_fid *fid;
1272         struct v9fs_session_info *v9ses;
1273
1274         v9ses = v9fs_inode2v9ses(dir);
1275         if (!v9fs_proto_dotu(v9ses)) {
1276                 p9_debug(P9_DEBUG_ERROR, "not extended\n");
1277                 return -EPERM;
1278         }
1279
1280         fid = v9fs_create(v9ses, dir, dentry, (char *) extension, perm,
1281                                                                 P9_OREAD);
1282         if (IS_ERR(fid))
1283                 return PTR_ERR(fid);
1284
1285         v9fs_invalidate_inode_attr(dir);
1286         p9_fid_put(fid);
1287         return 0;
1288 }
1289
1290 /**
1291  * v9fs_vfs_symlink - helper function to create symlinks
1292  * @idmap: idmap of the mount
1293  * @dir: directory inode containing symlink
1294  * @dentry: dentry for symlink
1295  * @symname: symlink data
1296  *
1297  * See Also: 9P2000.u RFC for more information
1298  *
1299  */
1300
1301 static int
1302 v9fs_vfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
1303                  struct dentry *dentry, const char *symname)
1304 {
1305         p9_debug(P9_DEBUG_VFS, " %lu,%pd,%s\n",
1306                  dir->i_ino, dentry, symname);
1307
1308         return v9fs_vfs_mkspecial(dir, dentry, P9_DMSYMLINK, symname);
1309 }
1310
1311 #define U32_MAX_DIGITS 10
1312
1313 /**
1314  * v9fs_vfs_link - create a hardlink
1315  * @old_dentry: dentry for file to link to
1316  * @dir: inode destination for new link
1317  * @dentry: dentry for link
1318  *
1319  */
1320
1321 static int
1322 v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
1323               struct dentry *dentry)
1324 {
1325         int retval;
1326         char name[1 + U32_MAX_DIGITS + 2]; /* sign + number + \n + \0 */
1327         struct p9_fid *oldfid;
1328
1329         p9_debug(P9_DEBUG_VFS, " %lu,%pd,%pd\n",
1330                  dir->i_ino, dentry, old_dentry);
1331
1332         oldfid = v9fs_fid_clone(old_dentry);
1333         if (IS_ERR(oldfid))
1334                 return PTR_ERR(oldfid);
1335
1336         sprintf(name, "%d\n", oldfid->fid);
1337         retval = v9fs_vfs_mkspecial(dir, dentry, P9_DMLINK, name);
1338         if (!retval) {
1339                 v9fs_refresh_inode(oldfid, d_inode(old_dentry));
1340                 v9fs_invalidate_inode_attr(dir);
1341         }
1342         p9_fid_put(oldfid);
1343         return retval;
1344 }
1345
1346 /**
1347  * v9fs_vfs_mknod - create a special file
1348  * @idmap: idmap of the mount
1349  * @dir: inode destination for new link
1350  * @dentry: dentry for file
1351  * @mode: mode for creation
1352  * @rdev: device associated with special file
1353  *
1354  */
1355
1356 static int
1357 v9fs_vfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
1358                struct dentry *dentry, umode_t mode, dev_t rdev)
1359 {
1360         struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
1361         int retval;
1362         char name[2 + U32_MAX_DIGITS + 1 + U32_MAX_DIGITS + 1];
1363         u32 perm;
1364
1365         p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %x MAJOR: %u MINOR: %u\n",
1366                  dir->i_ino, dentry, mode,
1367                  MAJOR(rdev), MINOR(rdev));
1368
1369         /* build extension */
1370         if (S_ISBLK(mode))
1371                 sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev));
1372         else if (S_ISCHR(mode))
1373                 sprintf(name, "c %u %u", MAJOR(rdev), MINOR(rdev));
1374         else
1375                 *name = 0;
1376
1377         perm = unixmode2p9mode(v9ses, mode);
1378         retval = v9fs_vfs_mkspecial(dir, dentry, perm, name);
1379
1380         return retval;
1381 }
1382
1383 int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
1384 {
1385         int umode;
1386         dev_t rdev;
1387         struct p9_wstat *st;
1388         struct v9fs_session_info *v9ses;
1389         unsigned int flags;
1390
1391         v9ses = v9fs_inode2v9ses(inode);
1392         st = p9_client_stat(fid);
1393         if (IS_ERR(st))
1394                 return PTR_ERR(st);
1395         /*
1396          * Don't update inode if the file type is different
1397          */
1398         umode = p9mode2unixmode(v9ses, st, &rdev);
1399         if (inode_wrong_type(inode, umode))
1400                 goto out;
1401
1402         /*
1403          * We don't want to refresh inode->i_size,
1404          * because we may have cached data
1405          */
1406         flags = (v9ses->cache & CACHE_LOOSE) ?
1407                 V9FS_STAT2INODE_KEEP_ISIZE : 0;
1408         v9fs_stat2inode(st, inode, inode->i_sb, flags);
1409 out:
1410         p9stat_free(st);
1411         kfree(st);
1412         return 0;
1413 }
1414
1415 static const struct inode_operations v9fs_dir_inode_operations_dotu = {
1416         .create = v9fs_vfs_create,
1417         .lookup = v9fs_vfs_lookup,
1418         .atomic_open = v9fs_vfs_atomic_open,
1419         .symlink = v9fs_vfs_symlink,
1420         .link = v9fs_vfs_link,
1421         .unlink = v9fs_vfs_unlink,
1422         .mkdir = v9fs_vfs_mkdir,
1423         .rmdir = v9fs_vfs_rmdir,
1424         .mknod = v9fs_vfs_mknod,
1425         .rename = v9fs_vfs_rename,
1426         .getattr = v9fs_vfs_getattr,
1427         .setattr = v9fs_vfs_setattr,
1428 };
1429
1430 static const struct inode_operations v9fs_dir_inode_operations = {
1431         .create = v9fs_vfs_create,
1432         .lookup = v9fs_vfs_lookup,
1433         .atomic_open = v9fs_vfs_atomic_open,
1434         .unlink = v9fs_vfs_unlink,
1435         .mkdir = v9fs_vfs_mkdir,
1436         .rmdir = v9fs_vfs_rmdir,
1437         .mknod = v9fs_vfs_mknod,
1438         .rename = v9fs_vfs_rename,
1439         .getattr = v9fs_vfs_getattr,
1440         .setattr = v9fs_vfs_setattr,
1441 };
1442
1443 static const struct inode_operations v9fs_file_inode_operations = {
1444         .getattr = v9fs_vfs_getattr,
1445         .setattr = v9fs_vfs_setattr,
1446 };
1447
1448 static const struct inode_operations v9fs_symlink_inode_operations = {
1449         .get_link = v9fs_vfs_get_link,
1450         .getattr = v9fs_vfs_getattr,
1451         .setattr = v9fs_vfs_setattr,
1452 };
1453