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