68f02973c338823ae58437b16b6ce5049b1ace98
[cascardo/linux.git] / fs / 9p / vfs_inode.c
1 /*
2  *  linux/fs/9p/vfs_inode.c
3  *
4  * This file contains vfs inode ops for the 9P2000 protocol.
5  *
6  *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7  *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License version 2
11  *  as published by the Free Software Foundation.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to:
20  *  Free Software Foundation
21  *  51 Franklin Street, Fifth Floor
22  *  Boston, MA  02111-1301  USA
23  *
24  */
25
26 #include <linux/module.h>
27 #include <linux/errno.h>
28 #include <linux/fs.h>
29 #include <linux/file.h>
30 #include <linux/pagemap.h>
31 #include <linux/stat.h>
32 #include <linux/string.h>
33 #include <linux/inet.h>
34 #include <linux/namei.h>
35 #include <linux/idr.h>
36 #include <linux/sched.h>
37 #include <linux/slab.h>
38 #include <linux/xattr.h>
39 #include <linux/posix_acl.h>
40 #include <net/9p/9p.h>
41 #include <net/9p/client.h>
42
43 #include "v9fs.h"
44 #include "v9fs_vfs.h"
45 #include "fid.h"
46 #include "cache.h"
47 #include "xattr.h"
48 #include "acl.h"
49
50 static const struct inode_operations v9fs_dir_inode_operations;
51 static const struct inode_operations v9fs_dir_inode_operations_dotu;
52 static const struct inode_operations v9fs_dir_inode_operations_dotl;
53 static const struct inode_operations v9fs_file_inode_operations;
54 static const struct inode_operations v9fs_file_inode_operations_dotl;
55 static const struct inode_operations v9fs_symlink_inode_operations;
56 static const struct inode_operations v9fs_symlink_inode_operations_dotl;
57
58 /**
59  * unixmode2p9mode - convert unix mode bits to plan 9
60  * @v9ses: v9fs session information
61  * @mode: mode to convert
62  *
63  */
64
65 static int unixmode2p9mode(struct v9fs_session_info *v9ses, int mode)
66 {
67         int res;
68         res = mode & 0777;
69         if (S_ISDIR(mode))
70                 res |= P9_DMDIR;
71         if (v9fs_proto_dotu(v9ses)) {
72                 if (S_ISLNK(mode))
73                         res |= P9_DMSYMLINK;
74                 if (v9ses->nodev == 0) {
75                         if (S_ISSOCK(mode))
76                                 res |= P9_DMSOCKET;
77                         if (S_ISFIFO(mode))
78                                 res |= P9_DMNAMEDPIPE;
79                         if (S_ISBLK(mode))
80                                 res |= P9_DMDEVICE;
81                         if (S_ISCHR(mode))
82                                 res |= P9_DMDEVICE;
83                 }
84
85                 if ((mode & S_ISUID) == S_ISUID)
86                         res |= P9_DMSETUID;
87                 if ((mode & S_ISGID) == S_ISGID)
88                         res |= P9_DMSETGID;
89                 if ((mode & S_ISVTX) == S_ISVTX)
90                         res |= P9_DMSETVTX;
91                 if ((mode & P9_DMLINK))
92                         res |= P9_DMLINK;
93         }
94
95         return res;
96 }
97
98 /**
99  * p9mode2unixmode- convert plan9 mode bits to unix mode bits
100  * @v9ses: v9fs session information
101  * @mode: mode to convert
102  *
103  */
104
105 static int p9mode2unixmode(struct v9fs_session_info *v9ses, int mode)
106 {
107         int res;
108
109         res = mode & 0777;
110
111         if ((mode & P9_DMDIR) == P9_DMDIR)
112                 res |= S_IFDIR;
113         else if ((mode & P9_DMSYMLINK) && (v9fs_proto_dotu(v9ses)))
114                 res |= S_IFLNK;
115         else if ((mode & P9_DMSOCKET) && (v9fs_proto_dotu(v9ses))
116                  && (v9ses->nodev == 0))
117                 res |= S_IFSOCK;
118         else if ((mode & P9_DMNAMEDPIPE) && (v9fs_proto_dotu(v9ses))
119                  && (v9ses->nodev == 0))
120                 res |= S_IFIFO;
121         else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses))
122                  && (v9ses->nodev == 0))
123                 res |= S_IFBLK;
124         else
125                 res |= S_IFREG;
126
127         if (v9fs_proto_dotu(v9ses)) {
128                 if ((mode & P9_DMSETUID) == P9_DMSETUID)
129                         res |= S_ISUID;
130
131                 if ((mode & P9_DMSETGID) == P9_DMSETGID)
132                         res |= S_ISGID;
133
134                 if ((mode & P9_DMSETVTX) == P9_DMSETVTX)
135                         res |= S_ISVTX;
136         }
137
138         return res;
139 }
140
141 /**
142  * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits
143  * @uflags: flags to convert
144  * @extended: if .u extensions are active
145  */
146
147 int v9fs_uflags2omode(int uflags, int extended)
148 {
149         int ret;
150
151         ret = 0;
152         switch (uflags&3) {
153         default:
154         case O_RDONLY:
155                 ret = P9_OREAD;
156                 break;
157
158         case O_WRONLY:
159                 ret = P9_OWRITE;
160                 break;
161
162         case O_RDWR:
163                 ret = P9_ORDWR;
164                 break;
165         }
166
167         if (uflags & O_TRUNC)
168                 ret |= P9_OTRUNC;
169
170         if (extended) {
171                 if (uflags & O_EXCL)
172                         ret |= P9_OEXCL;
173
174                 if (uflags & O_APPEND)
175                         ret |= P9_OAPPEND;
176         }
177
178         return ret;
179 }
180
181 /**
182  * v9fs_blank_wstat - helper function to setup a 9P stat structure
183  * @wstat: structure to initialize
184  *
185  */
186
187 void
188 v9fs_blank_wstat(struct p9_wstat *wstat)
189 {
190         wstat->type = ~0;
191         wstat->dev = ~0;
192         wstat->qid.type = ~0;
193         wstat->qid.version = ~0;
194         *((long long *)&wstat->qid.path) = ~0;
195         wstat->mode = ~0;
196         wstat->atime = ~0;
197         wstat->mtime = ~0;
198         wstat->length = ~0;
199         wstat->name = NULL;
200         wstat->uid = NULL;
201         wstat->gid = NULL;
202         wstat->muid = NULL;
203         wstat->n_uid = ~0;
204         wstat->n_gid = ~0;
205         wstat->n_muid = ~0;
206         wstat->extension = NULL;
207 }
208
209 #ifdef CONFIG_9P_FSCACHE
210 /**
211  * v9fs_alloc_inode - helper function to allocate an inode
212  * This callback is executed before setting up the inode so that we
213  * can associate a vcookie with each inode.
214  *
215  */
216
217 struct inode *v9fs_alloc_inode(struct super_block *sb)
218 {
219         struct v9fs_cookie *vcookie;
220         vcookie = (struct v9fs_cookie *)kmem_cache_alloc(vcookie_cache,
221                                                          GFP_KERNEL);
222         if (!vcookie)
223                 return NULL;
224
225         vcookie->fscache = NULL;
226         vcookie->qid = NULL;
227         spin_lock_init(&vcookie->lock);
228         return &vcookie->inode;
229 }
230
231 /**
232  * v9fs_destroy_inode - destroy an inode
233  *
234  */
235
236 void v9fs_destroy_inode(struct inode *inode)
237 {
238         kmem_cache_free(vcookie_cache, v9fs_inode2cookie(inode));
239 }
240 #endif
241
242 /**
243  * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
244  * new file system object. This checks the S_ISGID to determine the owning
245  * group of the new file system object.
246  */
247
248 static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
249 {
250         BUG_ON(dir_inode == NULL);
251
252         if (dir_inode->i_mode & S_ISGID) {
253                 /* set_gid bit is set.*/
254                 return dir_inode->i_gid;
255         }
256         return current_fsgid();
257 }
258
259 /**
260  * v9fs_dentry_from_dir_inode - helper function to get the dentry from
261  * dir inode.
262  *
263  */
264
265 static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
266 {
267         struct dentry *dentry;
268
269         spin_lock(&dcache_lock);
270         /* Directory should have only one entry. */
271         BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry));
272         dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
273         spin_unlock(&dcache_lock);
274         return dentry;
275 }
276
277 /**
278  * v9fs_get_inode - helper function to setup an inode
279  * @sb: superblock
280  * @mode: mode to setup inode with
281  *
282  */
283
284 struct inode *v9fs_get_inode(struct super_block *sb, int mode)
285 {
286         int err;
287         struct inode *inode;
288         struct v9fs_session_info *v9ses = sb->s_fs_info;
289
290         P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode);
291
292         inode = new_inode(sb);
293         if (!inode) {
294                 P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
295                 return ERR_PTR(-ENOMEM);
296         }
297
298         inode_init_owner(inode, NULL, mode);
299         inode->i_blocks = 0;
300         inode->i_rdev = 0;
301         inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
302         inode->i_mapping->a_ops = &v9fs_addr_operations;
303
304         switch (mode & S_IFMT) {
305         case S_IFIFO:
306         case S_IFBLK:
307         case S_IFCHR:
308         case S_IFSOCK:
309                 if (v9fs_proto_dotl(v9ses)) {
310                         inode->i_op = &v9fs_file_inode_operations_dotl;
311                         inode->i_fop = &v9fs_file_operations_dotl;
312                 } else if (v9fs_proto_dotu(v9ses)) {
313                         inode->i_op = &v9fs_file_inode_operations;
314                         inode->i_fop = &v9fs_file_operations;
315                 } else {
316                         P9_DPRINTK(P9_DEBUG_ERROR,
317                                    "special files without extended mode\n");
318                         err = -EINVAL;
319                         goto error;
320                 }
321                 init_special_inode(inode, inode->i_mode, inode->i_rdev);
322                 break;
323         case S_IFREG:
324                 if (v9fs_proto_dotl(v9ses)) {
325                         inode->i_op = &v9fs_file_inode_operations_dotl;
326                         inode->i_fop = &v9fs_file_operations_dotl;
327                 } else {
328                         inode->i_op = &v9fs_file_inode_operations;
329                         inode->i_fop = &v9fs_file_operations;
330                 }
331
332                 break;
333
334         case S_IFLNK:
335                 if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)) {
336                         P9_DPRINTK(P9_DEBUG_ERROR, "extended modes used with "
337                                                 "legacy protocol.\n");
338                         err = -EINVAL;
339                         goto error;
340                 }
341
342                 if (v9fs_proto_dotl(v9ses))
343                         inode->i_op = &v9fs_symlink_inode_operations_dotl;
344                 else
345                         inode->i_op = &v9fs_symlink_inode_operations;
346
347                 break;
348         case S_IFDIR:
349                 inc_nlink(inode);
350                 if (v9fs_proto_dotl(v9ses))
351                         inode->i_op = &v9fs_dir_inode_operations_dotl;
352                 else if (v9fs_proto_dotu(v9ses))
353                         inode->i_op = &v9fs_dir_inode_operations_dotu;
354                 else
355                         inode->i_op = &v9fs_dir_inode_operations;
356
357                 if (v9fs_proto_dotl(v9ses))
358                         inode->i_fop = &v9fs_dir_operations_dotl;
359                 else
360                         inode->i_fop = &v9fs_dir_operations;
361
362                 break;
363         default:
364                 P9_DPRINTK(P9_DEBUG_ERROR, "BAD mode 0x%x S_IFMT 0x%x\n",
365                            mode, mode & S_IFMT);
366                 err = -EINVAL;
367                 goto error;
368         }
369
370         return inode;
371
372 error:
373         iput(inode);
374         return ERR_PTR(err);
375 }
376
377 /*
378 static struct v9fs_fid*
379 v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry)
380 {
381         int err;
382         int nfid;
383         struct v9fs_fid *ret;
384         struct v9fs_fcall *fcall;
385
386         nfid = v9fs_get_idpool(&v9ses->fidpool);
387         if (nfid < 0) {
388                 eprintk(KERN_WARNING, "no free fids available\n");
389                 return ERR_PTR(-ENOSPC);
390         }
391
392         err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name,
393                 &fcall);
394
395         if (err < 0) {
396                 if (fcall && fcall->id == RWALK)
397                         goto clunk_fid;
398
399                 PRINT_FCALL_ERROR("walk error", fcall);
400                 v9fs_put_idpool(nfid, &v9ses->fidpool);
401                 goto error;
402         }
403
404         kfree(fcall);
405         fcall = NULL;
406         ret = v9fs_fid_create(v9ses, nfid);
407         if (!ret) {
408                 err = -ENOMEM;
409                 goto clunk_fid;
410         }
411
412         err = v9fs_fid_insert(ret, dentry);
413         if (err < 0) {
414                 v9fs_fid_destroy(ret);
415                 goto clunk_fid;
416         }
417
418         return ret;
419
420 clunk_fid:
421         v9fs_t_clunk(v9ses, nfid);
422
423 error:
424         kfree(fcall);
425         return ERR_PTR(err);
426 }
427 */
428
429
430 /**
431  * v9fs_clear_inode - release an inode
432  * @inode: inode to release
433  *
434  */
435 void v9fs_evict_inode(struct inode *inode)
436 {
437         truncate_inode_pages(inode->i_mapping, 0);
438         end_writeback(inode);
439         filemap_fdatawrite(inode->i_mapping);
440
441 #ifdef CONFIG_9P_FSCACHE
442         v9fs_cache_inode_put_cookie(inode);
443 #endif
444 }
445
446 static struct inode *
447 v9fs_inode(struct v9fs_session_info *v9ses, struct p9_fid *fid,
448         struct super_block *sb)
449 {
450         int err, umode;
451         struct inode *ret = NULL;
452         struct p9_wstat *st;
453
454         st = p9_client_stat(fid);
455         if (IS_ERR(st))
456                 return ERR_CAST(st);
457
458         umode = p9mode2unixmode(v9ses, st->mode);
459         ret = v9fs_get_inode(sb, umode);
460         if (IS_ERR(ret)) {
461                 err = PTR_ERR(ret);
462                 goto error;
463         }
464
465         v9fs_stat2inode(st, ret, sb);
466         ret->i_ino = v9fs_qid2ino(&st->qid);
467
468 #ifdef CONFIG_9P_FSCACHE
469         v9fs_vcookie_set_qid(ret, &st->qid);
470         v9fs_cache_inode_get_cookie(ret);
471 #endif
472         p9stat_free(st);
473         kfree(st);
474         return ret;
475 error:
476         p9stat_free(st);
477         kfree(st);
478         return ERR_PTR(err);
479 }
480
481 static struct inode *
482 v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
483         struct super_block *sb)
484 {
485         struct inode *ret = NULL;
486         int err;
487         struct p9_stat_dotl *st;
488
489         st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
490         if (IS_ERR(st))
491                 return ERR_CAST(st);
492
493         ret = v9fs_get_inode(sb, st->st_mode);
494         if (IS_ERR(ret)) {
495                 err = PTR_ERR(ret);
496                 goto error;
497         }
498
499         v9fs_stat2inode_dotl(st, ret);
500         ret->i_ino = v9fs_qid2ino(&st->qid);
501 #ifdef CONFIG_9P_FSCACHE
502         v9fs_vcookie_set_qid(ret, &st->qid);
503         v9fs_cache_inode_get_cookie(ret);
504 #endif
505         err = v9fs_get_acl(ret, fid);
506         if (err) {
507                 iput(ret);
508                 goto error;
509         }
510         kfree(st);
511         return ret;
512 error:
513         kfree(st);
514         return ERR_PTR(err);
515 }
516
517 /**
518  * v9fs_inode_from_fid - Helper routine to populate an inode by
519  * issuing a attribute request
520  * @v9ses: session information
521  * @fid: fid to issue attribute request for
522  * @sb: superblock on which to create inode
523  *
524  */
525 static inline struct inode *
526 v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
527                         struct super_block *sb)
528 {
529         if (v9fs_proto_dotl(v9ses))
530                 return v9fs_inode_dotl(v9ses, fid, sb);
531         else
532                 return v9fs_inode(v9ses, fid, sb);
533 }
534
535 /**
536  * v9fs_remove - helper function to remove files and directories
537  * @dir: directory inode that is being deleted
538  * @file:  dentry that is being deleted
539  * @rmdir: removing a directory
540  *
541  */
542
543 static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
544 {
545         int retval;
546         struct inode *file_inode;
547         struct p9_fid *v9fid;
548
549         P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file,
550                 rmdir);
551
552         file_inode = file->d_inode;
553         v9fid = v9fs_fid_clone(file);
554         if (IS_ERR(v9fid))
555                 return PTR_ERR(v9fid);
556
557         retval = p9_client_remove(v9fid);
558         if (!retval)
559                 drop_nlink(file_inode);
560         return retval;
561 }
562
563 static int
564 v9fs_open_created(struct inode *inode, struct file *file)
565 {
566         return 0;
567 }
568
569
570 /**
571  * v9fs_create - Create a file
572  * @v9ses: session information
573  * @dir: directory that dentry is being created in
574  * @dentry:  dentry that is being created
575  * @extension: 9p2000.u extension string to support devices, etc.
576  * @perm: create permissions
577  * @mode: open mode
578  *
579  */
580 static struct p9_fid *
581 v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
582                 struct dentry *dentry, char *extension, u32 perm, u8 mode)
583 {
584         int err;
585         char *name;
586         struct p9_fid *dfid, *ofid, *fid;
587         struct inode *inode;
588
589         P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
590
591         err = 0;
592         ofid = NULL;
593         fid = NULL;
594         name = (char *) dentry->d_name.name;
595         dfid = v9fs_fid_lookup(dentry->d_parent);
596         if (IS_ERR(dfid)) {
597                 err = PTR_ERR(dfid);
598                 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
599                 return ERR_PTR(err);
600         }
601
602         /* clone a fid to use for creation */
603         ofid = p9_client_walk(dfid, 0, NULL, 1);
604         if (IS_ERR(ofid)) {
605                 err = PTR_ERR(ofid);
606                 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
607                 return ERR_PTR(err);
608         }
609
610         err = p9_client_fcreate(ofid, name, perm, mode, extension);
611         if (err < 0) {
612                 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err);
613                 goto error;
614         }
615
616         /* now walk from the parent so we can get unopened fid */
617         fid = p9_client_walk(dfid, 1, &name, 1);
618         if (IS_ERR(fid)) {
619                 err = PTR_ERR(fid);
620                 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
621                 fid = NULL;
622                 goto error;
623         }
624
625         /* instantiate inode and assign the unopened fid to the dentry */
626         inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
627         if (IS_ERR(inode)) {
628                 err = PTR_ERR(inode);
629                 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
630                 goto error;
631         }
632
633         if (v9ses->cache)
634                 dentry->d_op = &v9fs_cached_dentry_operations;
635         else
636                 dentry->d_op = &v9fs_dentry_operations;
637
638         d_instantiate(dentry, inode);
639         err = v9fs_fid_add(dentry, fid);
640         if (err < 0)
641                 goto error;
642
643         return ofid;
644
645 error:
646         if (ofid)
647                 p9_client_clunk(ofid);
648
649         if (fid)
650                 p9_client_clunk(fid);
651
652         return ERR_PTR(err);
653 }
654
655 /**
656  * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
657  * @dir: directory inode that is being created
658  * @dentry:  dentry that is being deleted
659  * @mode: create permissions
660  * @nd: path information
661  *
662  */
663
664 static int
665 v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
666                 struct nameidata *nd)
667 {
668         int err = 0;
669         char *name = NULL;
670         gid_t gid;
671         int flags;
672         mode_t mode;
673         struct v9fs_session_info *v9ses;
674         struct p9_fid *fid = NULL;
675         struct p9_fid *dfid, *ofid;
676         struct file *filp;
677         struct p9_qid qid;
678         struct inode *inode;
679         struct posix_acl *pacl = NULL, *dacl = NULL;
680
681         v9ses = v9fs_inode2v9ses(dir);
682         if (nd && nd->flags & LOOKUP_OPEN)
683                 flags = nd->intent.open.flags - 1;
684         else
685                 flags = O_RDWR;
686
687         name = (char *) dentry->d_name.name;
688         P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_create_dotl: name:%s flags:0x%x "
689                         "mode:0x%x\n", name, flags, omode);
690
691         dfid = v9fs_fid_lookup(dentry->d_parent);
692         if (IS_ERR(dfid)) {
693                 err = PTR_ERR(dfid);
694                 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
695                 return err;
696         }
697
698         /* clone a fid to use for creation */
699         ofid = p9_client_walk(dfid, 0, NULL, 1);
700         if (IS_ERR(ofid)) {
701                 err = PTR_ERR(ofid);
702                 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
703                 return err;
704         }
705
706         gid = v9fs_get_fsgid_for_create(dir);
707
708         mode = omode;
709         /* Update mode based on ACL value */
710         err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
711         if (err) {
712                 P9_DPRINTK(P9_DEBUG_VFS,
713                            "Failed to get acl values in creat %d\n", err);
714                 goto error;
715         }
716         err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid);
717         if (err < 0) {
718                 P9_DPRINTK(P9_DEBUG_VFS,
719                                 "p9_client_open_dotl failed in creat %d\n",
720                                 err);
721                 goto error;
722         }
723         /* instantiate inode and assign the unopened fid to the dentry */
724         if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE ||
725             (nd && nd->flags & LOOKUP_OPEN)) {
726                 fid = p9_client_walk(dfid, 1, &name, 1);
727                 if (IS_ERR(fid)) {
728                         err = PTR_ERR(fid);
729                         P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
730                                 err);
731                         fid = NULL;
732                         goto error;
733                 }
734
735                 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
736                 if (IS_ERR(inode)) {
737                         err = PTR_ERR(inode);
738                         P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
739                                 err);
740                         goto error;
741                 }
742                 dentry->d_op = &v9fs_cached_dentry_operations;
743                 d_instantiate(dentry, inode);
744                 err = v9fs_fid_add(dentry, fid);
745                 if (err < 0)
746                         goto error;
747                 /* The fid would get clunked via a dput */
748                 fid = NULL;
749         } else {
750                 /*
751                  * Not in cached mode. No need to populate
752                  * inode with stat. We need to get an inode
753                  * so that we can set the acl with dentry
754                  */
755                 inode = v9fs_get_inode(dir->i_sb, mode);
756                 if (IS_ERR(inode)) {
757                         err = PTR_ERR(inode);
758                         goto error;
759                 }
760                 dentry->d_op = &v9fs_dentry_operations;
761                 d_instantiate(dentry, inode);
762         }
763         /* Now set the ACL based on the default value */
764         v9fs_set_create_acl(dentry, dacl, pacl);
765
766         /* if we are opening a file, assign the open fid to the file */
767         if (nd && nd->flags & LOOKUP_OPEN) {
768                 filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created);
769                 if (IS_ERR(filp)) {
770                         p9_client_clunk(ofid);
771                         return PTR_ERR(filp);
772                 }
773                 filp->private_data = ofid;
774         } else
775                 p9_client_clunk(ofid);
776
777         return 0;
778
779 error:
780         if (ofid)
781                 p9_client_clunk(ofid);
782         if (fid)
783                 p9_client_clunk(fid);
784         return err;
785 }
786
787 /**
788  * v9fs_vfs_create - VFS hook to create files
789  * @dir: directory inode that is being created
790  * @dentry:  dentry that is being deleted
791  * @mode: create permissions
792  * @nd: path information
793  *
794  */
795
796 static int
797 v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
798                 struct nameidata *nd)
799 {
800         int err;
801         u32 perm;
802         int flags;
803         struct v9fs_session_info *v9ses;
804         struct p9_fid *fid;
805         struct file *filp;
806
807         err = 0;
808         fid = NULL;
809         v9ses = v9fs_inode2v9ses(dir);
810         perm = unixmode2p9mode(v9ses, mode);
811         if (nd && nd->flags & LOOKUP_OPEN)
812                 flags = nd->intent.open.flags - 1;
813         else
814                 flags = O_RDWR;
815
816         fid = v9fs_create(v9ses, dir, dentry, NULL, perm,
817                                 v9fs_uflags2omode(flags,
818                                                 v9fs_proto_dotu(v9ses)));
819         if (IS_ERR(fid)) {
820                 err = PTR_ERR(fid);
821                 fid = NULL;
822                 goto error;
823         }
824
825         /* if we are opening a file, assign the open fid to the file */
826         if (nd && nd->flags & LOOKUP_OPEN) {
827                 filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created);
828                 if (IS_ERR(filp)) {
829                         err = PTR_ERR(filp);
830                         goto error;
831                 }
832
833                 filp->private_data = fid;
834         } else
835                 p9_client_clunk(fid);
836
837         return 0;
838
839 error:
840         if (fid)
841                 p9_client_clunk(fid);
842
843         return err;
844 }
845
846 /**
847  * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
848  * @dir:  inode that is being unlinked
849  * @dentry: dentry that is being unlinked
850  * @mode: mode for new directory
851  *
852  */
853
854 static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
855 {
856         int err;
857         u32 perm;
858         struct v9fs_session_info *v9ses;
859         struct p9_fid *fid;
860
861         P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
862         err = 0;
863         v9ses = v9fs_inode2v9ses(dir);
864         perm = unixmode2p9mode(v9ses, mode | S_IFDIR);
865         fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_OREAD);
866         if (IS_ERR(fid)) {
867                 err = PTR_ERR(fid);
868                 fid = NULL;
869         }
870
871         if (fid)
872                 p9_client_clunk(fid);
873
874         return err;
875 }
876
877
878 /**
879  * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
880  * @dir:  inode that is being unlinked
881  * @dentry: dentry that is being unlinked
882  * @mode: mode for new directory
883  *
884  */
885
886 static int v9fs_vfs_mkdir_dotl(struct inode *dir,
887                                struct dentry *dentry, int omode)
888 {
889         int err;
890         struct v9fs_session_info *v9ses;
891         struct p9_fid *fid = NULL, *dfid = NULL;
892         gid_t gid;
893         char *name;
894         mode_t mode;
895         struct inode *inode;
896         struct p9_qid qid;
897         struct dentry *dir_dentry;
898         struct posix_acl *dacl = NULL, *pacl = NULL;
899
900         P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
901         err = 0;
902         v9ses = v9fs_inode2v9ses(dir);
903
904         omode |= S_IFDIR;
905         if (dir->i_mode & S_ISGID)
906                 omode |= S_ISGID;
907
908         dir_dentry = v9fs_dentry_from_dir_inode(dir);
909         dfid = v9fs_fid_lookup(dir_dentry);
910         if (IS_ERR(dfid)) {
911                 err = PTR_ERR(dfid);
912                 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
913                 dfid = NULL;
914                 goto error;
915         }
916
917         gid = v9fs_get_fsgid_for_create(dir);
918         mode = omode;
919         /* Update mode based on ACL value */
920         err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
921         if (err) {
922                 P9_DPRINTK(P9_DEBUG_VFS,
923                            "Failed to get acl values in mkdir %d\n", err);
924                 goto error;
925         }
926         name = (char *) dentry->d_name.name;
927         err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
928         if (err < 0)
929                 goto error;
930
931         /* instantiate inode and assign the unopened fid to the dentry */
932         if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
933                 fid = p9_client_walk(dfid, 1, &name, 1);
934                 if (IS_ERR(fid)) {
935                         err = PTR_ERR(fid);
936                         P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
937                                 err);
938                         fid = NULL;
939                         goto error;
940                 }
941
942                 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
943                 if (IS_ERR(inode)) {
944                         err = PTR_ERR(inode);
945                         P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
946                                 err);
947                         goto error;
948                 }
949                 dentry->d_op = &v9fs_cached_dentry_operations;
950                 d_instantiate(dentry, inode);
951                 err = v9fs_fid_add(dentry, fid);
952                 if (err < 0)
953                         goto error;
954                 fid = NULL;
955         } else {
956                 /*
957                  * Not in cached mode. No need to populate
958                  * inode with stat. We need to get an inode
959                  * so that we can set the acl with dentry
960                  */
961                 inode = v9fs_get_inode(dir->i_sb, mode);
962                 if (IS_ERR(inode)) {
963                         err = PTR_ERR(inode);
964                         goto error;
965                 }
966                 dentry->d_op = &v9fs_dentry_operations;
967                 d_instantiate(dentry, inode);
968         }
969         /* Now set the ACL based on the default value */
970         v9fs_set_create_acl(dentry, dacl, pacl);
971
972 error:
973         if (fid)
974                 p9_client_clunk(fid);
975         return err;
976 }
977
978 /**
979  * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
980  * @dir:  inode that is being walked from
981  * @dentry: dentry that is being walked to?
982  * @nameidata: path data
983  *
984  */
985
986 static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
987                                       struct nameidata *nameidata)
988 {
989         struct super_block *sb;
990         struct v9fs_session_info *v9ses;
991         struct p9_fid *dfid, *fid;
992         struct inode *inode;
993         char *name;
994         int result = 0;
995
996         P9_DPRINTK(P9_DEBUG_VFS, "dir: %p dentry: (%s) %p nameidata: %p\n",
997                 dir, dentry->d_name.name, dentry, nameidata);
998
999         if (dentry->d_name.len > NAME_MAX)
1000                 return ERR_PTR(-ENAMETOOLONG);
1001
1002         sb = dir->i_sb;
1003         v9ses = v9fs_inode2v9ses(dir);
1004         /* We can walk d_parent because we hold the dir->i_mutex */
1005         dfid = v9fs_fid_lookup(dentry->d_parent);
1006         if (IS_ERR(dfid))
1007                 return ERR_CAST(dfid);
1008
1009         name = (char *) dentry->d_name.name;
1010         fid = p9_client_walk(dfid, 1, &name, 1);
1011         if (IS_ERR(fid)) {
1012                 result = PTR_ERR(fid);
1013                 if (result == -ENOENT) {
1014                         inode = NULL;
1015                         goto inst_out;
1016                 }
1017
1018                 return ERR_PTR(result);
1019         }
1020
1021         inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
1022         if (IS_ERR(inode)) {
1023                 result = PTR_ERR(inode);
1024                 inode = NULL;
1025                 goto error;
1026         }
1027
1028         result = v9fs_fid_add(dentry, fid);
1029         if (result < 0)
1030                 goto error;
1031
1032 inst_out:
1033         if (v9ses->cache)
1034                 dentry->d_op = &v9fs_cached_dentry_operations;
1035         else
1036                 dentry->d_op = &v9fs_dentry_operations;
1037
1038         d_add(dentry, inode);
1039         return NULL;
1040
1041 error:
1042         p9_client_clunk(fid);
1043
1044         return ERR_PTR(result);
1045 }
1046
1047 /**
1048  * v9fs_vfs_unlink - VFS unlink hook to delete an inode
1049  * @i:  inode that is being unlinked
1050  * @d: dentry that is being unlinked
1051  *
1052  */
1053
1054 static int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
1055 {
1056         return v9fs_remove(i, d, 0);
1057 }
1058
1059 /**
1060  * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
1061  * @i:  inode that is being unlinked
1062  * @d: dentry that is being unlinked
1063  *
1064  */
1065
1066 static int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
1067 {
1068         return v9fs_remove(i, d, 1);
1069 }
1070
1071 /**
1072  * v9fs_vfs_rename - VFS hook to rename an inode
1073  * @old_dir:  old dir inode
1074  * @old_dentry: old dentry
1075  * @new_dir: new dir inode
1076  * @new_dentry: new dentry
1077  *
1078  */
1079
1080 static int
1081 v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1082                 struct inode *new_dir, struct dentry *new_dentry)
1083 {
1084         struct inode *old_inode;
1085         struct v9fs_session_info *v9ses;
1086         struct p9_fid *oldfid;
1087         struct p9_fid *olddirfid;
1088         struct p9_fid *newdirfid;
1089         struct p9_wstat wstat;
1090         int retval;
1091
1092         P9_DPRINTK(P9_DEBUG_VFS, "\n");
1093         retval = 0;
1094         old_inode = old_dentry->d_inode;
1095         v9ses = v9fs_inode2v9ses(old_inode);
1096         oldfid = v9fs_fid_lookup(old_dentry);
1097         if (IS_ERR(oldfid))
1098                 return PTR_ERR(oldfid);
1099
1100         olddirfid = v9fs_fid_clone(old_dentry->d_parent);
1101         if (IS_ERR(olddirfid)) {
1102                 retval = PTR_ERR(olddirfid);
1103                 goto done;
1104         }
1105
1106         newdirfid = v9fs_fid_clone(new_dentry->d_parent);
1107         if (IS_ERR(newdirfid)) {
1108                 retval = PTR_ERR(newdirfid);
1109                 goto clunk_olddir;
1110         }
1111
1112         down_write(&v9ses->rename_sem);
1113         if (v9fs_proto_dotl(v9ses)) {
1114                 retval = p9_client_rename(oldfid, newdirfid,
1115                                         (char *) new_dentry->d_name.name);
1116                 if (retval != -ENOSYS)
1117                         goto clunk_newdir;
1118         }
1119         if (old_dentry->d_parent != new_dentry->d_parent) {
1120                 /*
1121                  * 9P .u can only handle file rename in the same directory
1122                  */
1123
1124                 P9_DPRINTK(P9_DEBUG_ERROR,
1125                                 "old dir and new dir are different\n");
1126                 retval = -EXDEV;
1127                 goto clunk_newdir;
1128         }
1129         v9fs_blank_wstat(&wstat);
1130         wstat.muid = v9ses->uname;
1131         wstat.name = (char *) new_dentry->d_name.name;
1132         retval = p9_client_wstat(oldfid, &wstat);
1133
1134 clunk_newdir:
1135         if (!retval)
1136                 /* successful rename */
1137                 d_move(old_dentry, new_dentry);
1138         up_write(&v9ses->rename_sem);
1139         p9_client_clunk(newdirfid);
1140
1141 clunk_olddir:
1142         p9_client_clunk(olddirfid);
1143
1144 done:
1145         return retval;
1146 }
1147
1148 /**
1149  * v9fs_vfs_getattr - retrieve file metadata
1150  * @mnt: mount information
1151  * @dentry: file to get attributes on
1152  * @stat: metadata structure to populate
1153  *
1154  */
1155
1156 static int
1157 v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1158                  struct kstat *stat)
1159 {
1160         int err;
1161         struct v9fs_session_info *v9ses;
1162         struct p9_fid *fid;
1163         struct p9_wstat *st;
1164
1165         P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
1166         err = -EPERM;
1167         v9ses = v9fs_inode2v9ses(dentry->d_inode);
1168         if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
1169                 return simple_getattr(mnt, dentry, stat);
1170
1171         fid = v9fs_fid_lookup(dentry);
1172         if (IS_ERR(fid))
1173                 return PTR_ERR(fid);
1174
1175         st = p9_client_stat(fid);
1176         if (IS_ERR(st))
1177                 return PTR_ERR(st);
1178
1179         v9fs_stat2inode(st, dentry->d_inode, dentry->d_inode->i_sb);
1180                 generic_fillattr(dentry->d_inode, stat);
1181
1182         p9stat_free(st);
1183         kfree(st);
1184         return 0;
1185 }
1186
1187 static int
1188 v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
1189                  struct kstat *stat)
1190 {
1191         int err;
1192         struct v9fs_session_info *v9ses;
1193         struct p9_fid *fid;
1194         struct p9_stat_dotl *st;
1195
1196         P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
1197         err = -EPERM;
1198         v9ses = v9fs_inode2v9ses(dentry->d_inode);
1199         if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
1200                 return simple_getattr(mnt, dentry, stat);
1201
1202         fid = v9fs_fid_lookup(dentry);
1203         if (IS_ERR(fid))
1204                 return PTR_ERR(fid);
1205
1206         /* Ask for all the fields in stat structure. Server will return
1207          * whatever it supports
1208          */
1209
1210         st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
1211         if (IS_ERR(st))
1212                 return PTR_ERR(st);
1213
1214         v9fs_stat2inode_dotl(st, dentry->d_inode);
1215         generic_fillattr(dentry->d_inode, stat);
1216         /* Change block size to what the server returned */
1217         stat->blksize = st->st_blksize;
1218
1219         kfree(st);
1220         return 0;
1221 }
1222
1223 /**
1224  * v9fs_vfs_setattr - set file metadata
1225  * @dentry: file whose metadata to set
1226  * @iattr: metadata assignment structure
1227  *
1228  */
1229
1230 static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
1231 {
1232         int retval;
1233         struct v9fs_session_info *v9ses;
1234         struct p9_fid *fid;
1235         struct p9_wstat wstat;
1236
1237         P9_DPRINTK(P9_DEBUG_VFS, "\n");
1238         retval = -EPERM;
1239         v9ses = v9fs_inode2v9ses(dentry->d_inode);
1240         fid = v9fs_fid_lookup(dentry);
1241         if(IS_ERR(fid))
1242                 return PTR_ERR(fid);
1243
1244         v9fs_blank_wstat(&wstat);
1245         if (iattr->ia_valid & ATTR_MODE)
1246                 wstat.mode = unixmode2p9mode(v9ses, iattr->ia_mode);
1247
1248         if (iattr->ia_valid & ATTR_MTIME)
1249                 wstat.mtime = iattr->ia_mtime.tv_sec;
1250
1251         if (iattr->ia_valid & ATTR_ATIME)
1252                 wstat.atime = iattr->ia_atime.tv_sec;
1253
1254         if (iattr->ia_valid & ATTR_SIZE)
1255                 wstat.length = iattr->ia_size;
1256
1257         if (v9fs_proto_dotu(v9ses)) {
1258                 if (iattr->ia_valid & ATTR_UID)
1259                         wstat.n_uid = iattr->ia_uid;
1260
1261                 if (iattr->ia_valid & ATTR_GID)
1262                         wstat.n_gid = iattr->ia_gid;
1263         }
1264
1265         retval = p9_client_wstat(fid, &wstat);
1266         if (retval < 0)
1267                 return retval;
1268
1269         if ((iattr->ia_valid & ATTR_SIZE) &&
1270             iattr->ia_size != i_size_read(dentry->d_inode)) {
1271                 retval = vmtruncate(dentry->d_inode, iattr->ia_size);
1272                 if (retval)
1273                         return retval;
1274         }
1275
1276         setattr_copy(dentry->d_inode, iattr);
1277         mark_inode_dirty(dentry->d_inode);
1278         return 0;
1279 }
1280
1281 /**
1282  * v9fs_vfs_setattr_dotl - set file metadata
1283  * @dentry: file whose metadata to set
1284  * @iattr: metadata assignment structure
1285  *
1286  */
1287
1288 int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
1289 {
1290         int retval;
1291         struct v9fs_session_info *v9ses;
1292         struct p9_fid *fid;
1293         struct p9_iattr_dotl p9attr;
1294
1295         P9_DPRINTK(P9_DEBUG_VFS, "\n");
1296
1297         retval = inode_change_ok(dentry->d_inode, iattr);
1298         if (retval)
1299                 return retval;
1300
1301         p9attr.valid = iattr->ia_valid;
1302         p9attr.mode = iattr->ia_mode;
1303         p9attr.uid = iattr->ia_uid;
1304         p9attr.gid = iattr->ia_gid;
1305         p9attr.size = iattr->ia_size;
1306         p9attr.atime_sec = iattr->ia_atime.tv_sec;
1307         p9attr.atime_nsec = iattr->ia_atime.tv_nsec;
1308         p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
1309         p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
1310
1311         retval = -EPERM;
1312         v9ses = v9fs_inode2v9ses(dentry->d_inode);
1313         fid = v9fs_fid_lookup(dentry);
1314         if (IS_ERR(fid))
1315                 return PTR_ERR(fid);
1316
1317         retval = p9_client_setattr(fid, &p9attr);
1318         if (retval < 0)
1319                 return retval;
1320
1321         if ((iattr->ia_valid & ATTR_SIZE) &&
1322             iattr->ia_size != i_size_read(dentry->d_inode)) {
1323                 retval = vmtruncate(dentry->d_inode, iattr->ia_size);
1324                 if (retval)
1325                         return retval;
1326         }
1327
1328         setattr_copy(dentry->d_inode, iattr);
1329         mark_inode_dirty(dentry->d_inode);
1330         if (iattr->ia_valid & ATTR_MODE) {
1331                 /* We also want to update ACL when we update mode bits */
1332                 retval = v9fs_acl_chmod(dentry);
1333                 if (retval < 0)
1334                         return retval;
1335         }
1336         return 0;
1337 }
1338
1339 /**
1340  * v9fs_stat2inode - populate an inode structure with mistat info
1341  * @stat: Plan 9 metadata (mistat) structure
1342  * @inode: inode to populate
1343  * @sb: superblock of filesystem
1344  *
1345  */
1346
1347 void
1348 v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
1349         struct super_block *sb)
1350 {
1351         char ext[32];
1352         char tag_name[14];
1353         unsigned int i_nlink;
1354         struct v9fs_session_info *v9ses = sb->s_fs_info;
1355
1356         inode->i_nlink = 1;
1357
1358         inode->i_atime.tv_sec = stat->atime;
1359         inode->i_mtime.tv_sec = stat->mtime;
1360         inode->i_ctime.tv_sec = stat->mtime;
1361
1362         inode->i_uid = v9ses->dfltuid;
1363         inode->i_gid = v9ses->dfltgid;
1364
1365         if (v9fs_proto_dotu(v9ses)) {
1366                 inode->i_uid = stat->n_uid;
1367                 inode->i_gid = stat->n_gid;
1368         }
1369         if ((S_ISREG(inode->i_mode)) || (S_ISDIR(inode->i_mode))) {
1370                 if (v9fs_proto_dotu(v9ses) && (stat->extension[0] != '\0')) {
1371                         /*
1372                          * Hadlink support got added later to
1373                          * to the .u extension. So there can be
1374                          * server out there that doesn't support
1375                          * this even with .u extension. So check
1376                          * for non NULL stat->extension
1377                          */
1378                         strncpy(ext, stat->extension, sizeof(ext));
1379                         /* HARDLINKCOUNT %u */
1380                         sscanf(ext, "%13s %u", tag_name, &i_nlink);
1381                         if (!strncmp(tag_name, "HARDLINKCOUNT", 13))
1382                                 inode->i_nlink = i_nlink;
1383                 }
1384         }
1385         inode->i_mode = p9mode2unixmode(v9ses, stat->mode);
1386         if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode))) {
1387                 char type = 0;
1388                 int major = -1;
1389                 int minor = -1;
1390
1391                 strncpy(ext, stat->extension, sizeof(ext));
1392                 sscanf(ext, "%c %u %u", &type, &major, &minor);
1393                 switch (type) {
1394                 case 'c':
1395                         inode->i_mode &= ~S_IFBLK;
1396                         inode->i_mode |= S_IFCHR;
1397                         break;
1398                 case 'b':
1399                         break;
1400                 default:
1401                         P9_DPRINTK(P9_DEBUG_ERROR,
1402                                 "Unknown special type %c %s\n", type,
1403                                 stat->extension);
1404                 };
1405                 inode->i_rdev = MKDEV(major, minor);
1406                 init_special_inode(inode, inode->i_mode, inode->i_rdev);
1407         } else
1408                 inode->i_rdev = 0;
1409
1410         i_size_write(inode, stat->length);
1411
1412         /* not real number of blocks, but 512 byte ones ... */
1413         inode->i_blocks = (i_size_read(inode) + 512 - 1) >> 9;
1414 }
1415
1416 /**
1417  * v9fs_stat2inode_dotl - populate an inode structure with stat info
1418  * @stat: stat structure
1419  * @inode: inode to populate
1420  * @sb: superblock of filesystem
1421  *
1422  */
1423
1424 void
1425 v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
1426 {
1427
1428         if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
1429                 inode->i_atime.tv_sec = stat->st_atime_sec;
1430                 inode->i_atime.tv_nsec = stat->st_atime_nsec;
1431                 inode->i_mtime.tv_sec = stat->st_mtime_sec;
1432                 inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
1433                 inode->i_ctime.tv_sec = stat->st_ctime_sec;
1434                 inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
1435                 inode->i_uid = stat->st_uid;
1436                 inode->i_gid = stat->st_gid;
1437                 inode->i_nlink = stat->st_nlink;
1438                 inode->i_mode = stat->st_mode;
1439                 inode->i_rdev = new_decode_dev(stat->st_rdev);
1440
1441                 if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode)))
1442                         init_special_inode(inode, inode->i_mode, inode->i_rdev);
1443
1444                 i_size_write(inode, stat->st_size);
1445                 inode->i_blocks = stat->st_blocks;
1446         } else {
1447                 if (stat->st_result_mask & P9_STATS_ATIME) {
1448                         inode->i_atime.tv_sec = stat->st_atime_sec;
1449                         inode->i_atime.tv_nsec = stat->st_atime_nsec;
1450                 }
1451                 if (stat->st_result_mask & P9_STATS_MTIME) {
1452                         inode->i_mtime.tv_sec = stat->st_mtime_sec;
1453                         inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
1454                 }
1455                 if (stat->st_result_mask & P9_STATS_CTIME) {
1456                         inode->i_ctime.tv_sec = stat->st_ctime_sec;
1457                         inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
1458                 }
1459                 if (stat->st_result_mask & P9_STATS_UID)
1460                         inode->i_uid = stat->st_uid;
1461                 if (stat->st_result_mask & P9_STATS_GID)
1462                         inode->i_gid = stat->st_gid;
1463                 if (stat->st_result_mask & P9_STATS_NLINK)
1464                         inode->i_nlink = stat->st_nlink;
1465                 if (stat->st_result_mask & P9_STATS_MODE) {
1466                         inode->i_mode = stat->st_mode;
1467                         if ((S_ISBLK(inode->i_mode)) ||
1468                                                 (S_ISCHR(inode->i_mode)))
1469                                 init_special_inode(inode, inode->i_mode,
1470                                                                 inode->i_rdev);
1471                 }
1472                 if (stat->st_result_mask & P9_STATS_RDEV)
1473                         inode->i_rdev = new_decode_dev(stat->st_rdev);
1474                 if (stat->st_result_mask & P9_STATS_SIZE)
1475                         i_size_write(inode, stat->st_size);
1476                 if (stat->st_result_mask & P9_STATS_BLOCKS)
1477                         inode->i_blocks = stat->st_blocks;
1478         }
1479         if (stat->st_result_mask & P9_STATS_GEN)
1480                         inode->i_generation = stat->st_gen;
1481
1482         /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
1483          * because the inode structure does not have fields for them.
1484          */
1485 }
1486
1487 /**
1488  * v9fs_qid2ino - convert qid into inode number
1489  * @qid: qid to hash
1490  *
1491  * BUG: potential for inode number collisions?
1492  */
1493
1494 ino_t v9fs_qid2ino(struct p9_qid *qid)
1495 {
1496         u64 path = qid->path + 2;
1497         ino_t i = 0;
1498
1499         if (sizeof(ino_t) == sizeof(path))
1500                 memcpy(&i, &path, sizeof(ino_t));
1501         else
1502                 i = (ino_t) (path ^ (path >> 32));
1503
1504         return i;
1505 }
1506
1507 /**
1508  * v9fs_readlink - read a symlink's location (internal version)
1509  * @dentry: dentry for symlink
1510  * @buffer: buffer to load symlink location into
1511  * @buflen: length of buffer
1512  *
1513  */
1514
1515 static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
1516 {
1517         int retval;
1518
1519         struct v9fs_session_info *v9ses;
1520         struct p9_fid *fid;
1521         struct p9_wstat *st;
1522
1523         P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name);
1524         retval = -EPERM;
1525         v9ses = v9fs_inode2v9ses(dentry->d_inode);
1526         fid = v9fs_fid_lookup(dentry);
1527         if (IS_ERR(fid))
1528                 return PTR_ERR(fid);
1529
1530         if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses))
1531                 return -EBADF;
1532
1533         st = p9_client_stat(fid);
1534         if (IS_ERR(st))
1535                 return PTR_ERR(st);
1536
1537         if (!(st->mode & P9_DMSYMLINK)) {
1538                 retval = -EINVAL;
1539                 goto done;
1540         }
1541
1542         /* copy extension buffer into buffer */
1543         strncpy(buffer, st->extension, buflen);
1544
1545         P9_DPRINTK(P9_DEBUG_VFS,
1546                 "%s -> %s (%s)\n", dentry->d_name.name, st->extension, buffer);
1547
1548         retval = strnlen(buffer, buflen);
1549 done:
1550         p9stat_free(st);
1551         kfree(st);
1552         return retval;
1553 }
1554
1555 /**
1556  * v9fs_vfs_follow_link - follow a symlink path
1557  * @dentry: dentry for symlink
1558  * @nd: nameidata
1559  *
1560  */
1561
1562 static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
1563 {
1564         int len = 0;
1565         char *link = __getname();
1566
1567         P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name);
1568
1569         if (!link)
1570                 link = ERR_PTR(-ENOMEM);
1571         else {
1572                 len = v9fs_readlink(dentry, link, PATH_MAX);
1573
1574                 if (len < 0) {
1575                         __putname(link);
1576                         link = ERR_PTR(len);
1577                 } else
1578                         link[min(len, PATH_MAX-1)] = 0;
1579         }
1580         nd_set_link(nd, link);
1581
1582         return NULL;
1583 }
1584
1585 /**
1586  * v9fs_vfs_put_link - release a symlink path
1587  * @dentry: dentry for symlink
1588  * @nd: nameidata
1589  * @p: unused
1590  *
1591  */
1592
1593 static void
1594 v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
1595 {
1596         char *s = nd_get_link(nd);
1597
1598         P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name,
1599                 IS_ERR(s) ? "<error>" : s);
1600         if (!IS_ERR(s))
1601                 __putname(s);
1602 }
1603
1604 /**
1605  * v9fs_vfs_mkspecial - create a special file
1606  * @dir: inode to create special file in
1607  * @dentry: dentry to create
1608  * @mode: mode to create special file
1609  * @extension: 9p2000.u format extension string representing special file
1610  *
1611  */
1612
1613 static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
1614         int mode, const char *extension)
1615 {
1616         u32 perm;
1617         struct v9fs_session_info *v9ses;
1618         struct p9_fid *fid;
1619
1620         v9ses = v9fs_inode2v9ses(dir);
1621         if (!v9fs_proto_dotu(v9ses)) {
1622                 P9_DPRINTK(P9_DEBUG_ERROR, "not extended\n");
1623                 return -EPERM;
1624         }
1625
1626         perm = unixmode2p9mode(v9ses, mode);
1627         fid = v9fs_create(v9ses, dir, dentry, (char *) extension, perm,
1628                                                                 P9_OREAD);
1629         if (IS_ERR(fid))
1630                 return PTR_ERR(fid);
1631
1632         p9_client_clunk(fid);
1633         return 0;
1634 }
1635
1636 /**
1637  * v9fs_vfs_symlink_dotl - helper function to create symlinks
1638  * @dir: directory inode containing symlink
1639  * @dentry: dentry for symlink
1640  * @symname: symlink data
1641  *
1642  * See Also: 9P2000.L RFC for more information
1643  *
1644  */
1645
1646 static int
1647 v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
1648                 const char *symname)
1649 {
1650         struct v9fs_session_info *v9ses;
1651         struct p9_fid *dfid;
1652         struct p9_fid *fid = NULL;
1653         struct inode *inode;
1654         struct p9_qid qid;
1655         char *name;
1656         int err;
1657         gid_t gid;
1658
1659         name = (char *) dentry->d_name.name;
1660         P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n",
1661                         dir->i_ino, name, symname);
1662         v9ses = v9fs_inode2v9ses(dir);
1663
1664         dfid = v9fs_fid_lookup(dentry->d_parent);
1665         if (IS_ERR(dfid)) {
1666                 err = PTR_ERR(dfid);
1667                 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
1668                 return err;
1669         }
1670
1671         gid = v9fs_get_fsgid_for_create(dir);
1672
1673         /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
1674         err = p9_client_symlink(dfid, name, (char *)symname, gid, &qid);
1675
1676         if (err < 0) {
1677                 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err);
1678                 goto error;
1679         }
1680
1681         if (v9ses->cache) {
1682                 /* Now walk from the parent so we can get an unopened fid. */
1683                 fid = p9_client_walk(dfid, 1, &name, 1);
1684                 if (IS_ERR(fid)) {
1685                         err = PTR_ERR(fid);
1686                         P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
1687                                         err);
1688                         fid = NULL;
1689                         goto error;
1690                 }
1691
1692                 /* instantiate inode and assign the unopened fid to dentry */
1693                 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
1694                 if (IS_ERR(inode)) {
1695                         err = PTR_ERR(inode);
1696                         P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
1697                                         err);
1698                         goto error;
1699                 }
1700                 dentry->d_op = &v9fs_cached_dentry_operations;
1701                 d_instantiate(dentry, inode);
1702                 err = v9fs_fid_add(dentry, fid);
1703                 if (err < 0)
1704                         goto error;
1705                 fid = NULL;
1706         } else {
1707                 /* Not in cached mode. No need to populate inode with stat */
1708                 inode = v9fs_get_inode(dir->i_sb, S_IFLNK);
1709                 if (IS_ERR(inode)) {
1710                         err = PTR_ERR(inode);
1711                         goto error;
1712                 }
1713                 dentry->d_op = &v9fs_dentry_operations;
1714                 d_instantiate(dentry, inode);
1715         }
1716
1717 error:
1718         if (fid)
1719                 p9_client_clunk(fid);
1720
1721         return err;
1722 }
1723
1724 /**
1725  * v9fs_vfs_symlink - helper function to create symlinks
1726  * @dir: directory inode containing symlink
1727  * @dentry: dentry for symlink
1728  * @symname: symlink data
1729  *
1730  * See Also: 9P2000.u RFC for more information
1731  *
1732  */
1733
1734 static int
1735 v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
1736 {
1737         P9_DPRINTK(P9_DEBUG_VFS, " %lu,%s,%s\n", dir->i_ino,
1738                                         dentry->d_name.name, symname);
1739
1740         return v9fs_vfs_mkspecial(dir, dentry, S_IFLNK, symname);
1741 }
1742
1743 /**
1744  * v9fs_vfs_link - create a hardlink
1745  * @old_dentry: dentry for file to link to
1746  * @dir: inode destination for new link
1747  * @dentry: dentry for link
1748  *
1749  */
1750
1751 static int
1752 v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
1753               struct dentry *dentry)
1754 {
1755         int retval;
1756         struct p9_fid *oldfid;
1757         char *name;
1758
1759         P9_DPRINTK(P9_DEBUG_VFS,
1760                 " %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
1761                 old_dentry->d_name.name);
1762
1763         oldfid = v9fs_fid_clone(old_dentry);
1764         if (IS_ERR(oldfid))
1765                 return PTR_ERR(oldfid);
1766
1767         name = __getname();
1768         if (unlikely(!name)) {
1769                 retval = -ENOMEM;
1770                 goto clunk_fid;
1771         }
1772
1773         sprintf(name, "%d\n", oldfid->fid);
1774         retval = v9fs_vfs_mkspecial(dir, dentry, P9_DMLINK, name);
1775         __putname(name);
1776
1777 clunk_fid:
1778         p9_client_clunk(oldfid);
1779         return retval;
1780 }
1781
1782 /**
1783  * v9fs_vfs_link_dotl - create a hardlink for dotl
1784  * @old_dentry: dentry for file to link to
1785  * @dir: inode destination for new link
1786  * @dentry: dentry for link
1787  *
1788  */
1789
1790 static int
1791 v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
1792                 struct dentry *dentry)
1793 {
1794         int err;
1795         struct p9_fid *dfid, *oldfid;
1796         char *name;
1797         struct v9fs_session_info *v9ses;
1798         struct dentry *dir_dentry;
1799
1800         P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n",
1801                         dir->i_ino, old_dentry->d_name.name,
1802                         dentry->d_name.name);
1803
1804         v9ses = v9fs_inode2v9ses(dir);
1805         dir_dentry = v9fs_dentry_from_dir_inode(dir);
1806         dfid = v9fs_fid_lookup(dir_dentry);
1807         if (IS_ERR(dfid))
1808                 return PTR_ERR(dfid);
1809
1810         oldfid = v9fs_fid_lookup(old_dentry);
1811         if (IS_ERR(oldfid))
1812                 return PTR_ERR(oldfid);
1813
1814         name = (char *) dentry->d_name.name;
1815
1816         err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name);
1817
1818         if (err < 0) {
1819                 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
1820                 return err;
1821         }
1822
1823         if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
1824                 /* Get the latest stat info from server. */
1825                 struct p9_fid *fid;
1826                 struct p9_stat_dotl *st;
1827
1828                 fid = v9fs_fid_lookup(old_dentry);
1829                 if (IS_ERR(fid))
1830                         return PTR_ERR(fid);
1831
1832                 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
1833                 if (IS_ERR(st))
1834                         return PTR_ERR(st);
1835
1836                 v9fs_stat2inode_dotl(st, old_dentry->d_inode);
1837
1838                 kfree(st);
1839         } else {
1840                 /* Caching disabled. No need to get upto date stat info.
1841                  * This dentry will be released immediately. So, just hold the
1842                  * inode
1843                  */
1844                 ihold(old_dentry->d_inode);
1845         }
1846
1847         dentry->d_op = old_dentry->d_op;
1848         d_instantiate(dentry, old_dentry->d_inode);
1849
1850         return err;
1851 }
1852
1853 /**
1854  * v9fs_vfs_mknod - create a special file
1855  * @dir: inode destination for new link
1856  * @dentry: dentry for file
1857  * @mode: mode for creation
1858  * @rdev: device associated with special file
1859  *
1860  */
1861
1862 static int
1863 v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
1864 {
1865         int retval;
1866         char *name;
1867
1868         P9_DPRINTK(P9_DEBUG_VFS,
1869                 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
1870                 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
1871
1872         if (!new_valid_dev(rdev))
1873                 return -EINVAL;
1874
1875         name = __getname();
1876         if (!name)
1877                 return -ENOMEM;
1878         /* build extension */
1879         if (S_ISBLK(mode))
1880                 sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev));
1881         else if (S_ISCHR(mode))
1882                 sprintf(name, "c %u %u", MAJOR(rdev), MINOR(rdev));
1883         else if (S_ISFIFO(mode))
1884                 *name = 0;
1885         else if (S_ISSOCK(mode))
1886                 *name = 0;
1887         else {
1888                 __putname(name);
1889                 return -EINVAL;
1890         }
1891
1892         retval = v9fs_vfs_mkspecial(dir, dentry, mode, name);
1893         __putname(name);
1894
1895         return retval;
1896 }
1897
1898 /**
1899  * v9fs_vfs_mknod_dotl - create a special file
1900  * @dir: inode destination for new link
1901  * @dentry: dentry for file
1902  * @mode: mode for creation
1903  * @rdev: device associated with special file
1904  *
1905  */
1906 static int
1907 v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
1908                 dev_t rdev)
1909 {
1910         int err;
1911         char *name;
1912         mode_t mode;
1913         struct v9fs_session_info *v9ses;
1914         struct p9_fid *fid = NULL, *dfid = NULL;
1915         struct inode *inode;
1916         gid_t gid;
1917         struct p9_qid qid;
1918         struct dentry *dir_dentry;
1919         struct posix_acl *dacl = NULL, *pacl = NULL;
1920
1921         P9_DPRINTK(P9_DEBUG_VFS,
1922                 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
1923                 dentry->d_name.name, omode, MAJOR(rdev), MINOR(rdev));
1924
1925         if (!new_valid_dev(rdev))
1926                 return -EINVAL;
1927
1928         v9ses = v9fs_inode2v9ses(dir);
1929         dir_dentry = v9fs_dentry_from_dir_inode(dir);
1930         dfid = v9fs_fid_lookup(dir_dentry);
1931         if (IS_ERR(dfid)) {
1932                 err = PTR_ERR(dfid);
1933                 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
1934                 dfid = NULL;
1935                 goto error;
1936         }
1937
1938         gid = v9fs_get_fsgid_for_create(dir);
1939         mode = omode;
1940         /* Update mode based on ACL value */
1941         err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
1942         if (err) {
1943                 P9_DPRINTK(P9_DEBUG_VFS,
1944                            "Failed to get acl values in mknod %d\n", err);
1945                 goto error;
1946         }
1947         name = (char *) dentry->d_name.name;
1948
1949         err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
1950         if (err < 0)
1951                 goto error;
1952
1953         /* instantiate inode and assign the unopened fid to the dentry */
1954         if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
1955                 fid = p9_client_walk(dfid, 1, &name, 1);
1956                 if (IS_ERR(fid)) {
1957                         err = PTR_ERR(fid);
1958                         P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
1959                                 err);
1960                         fid = NULL;
1961                         goto error;
1962                 }
1963
1964                 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
1965                 if (IS_ERR(inode)) {
1966                         err = PTR_ERR(inode);
1967                         P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
1968                                 err);
1969                         goto error;
1970                 }
1971                 dentry->d_op = &v9fs_cached_dentry_operations;
1972                 d_instantiate(dentry, inode);
1973                 err = v9fs_fid_add(dentry, fid);
1974                 if (err < 0)
1975                         goto error;
1976                 fid = NULL;
1977         } else {
1978                 /*
1979                  * Not in cached mode. No need to populate inode with stat.
1980                  * socket syscall returns a fd, so we need instantiate
1981                  */
1982                 inode = v9fs_get_inode(dir->i_sb, mode);
1983                 if (IS_ERR(inode)) {
1984                         err = PTR_ERR(inode);
1985                         goto error;
1986                 }
1987                 dentry->d_op = &v9fs_dentry_operations;
1988                 d_instantiate(dentry, inode);
1989         }
1990         /* Now set the ACL based on the default value */
1991         v9fs_set_create_acl(dentry, dacl, pacl);
1992 error:
1993         if (fid)
1994                 p9_client_clunk(fid);
1995         return err;
1996 }
1997
1998 static const struct inode_operations v9fs_dir_inode_operations_dotu = {
1999         .create = v9fs_vfs_create,
2000         .lookup = v9fs_vfs_lookup,
2001         .symlink = v9fs_vfs_symlink,
2002         .link = v9fs_vfs_link,
2003         .unlink = v9fs_vfs_unlink,
2004         .mkdir = v9fs_vfs_mkdir,
2005         .rmdir = v9fs_vfs_rmdir,
2006         .mknod = v9fs_vfs_mknod,
2007         .rename = v9fs_vfs_rename,
2008         .getattr = v9fs_vfs_getattr,
2009         .setattr = v9fs_vfs_setattr,
2010 };
2011
2012 static const struct inode_operations v9fs_dir_inode_operations_dotl = {
2013         .create = v9fs_vfs_create_dotl,
2014         .lookup = v9fs_vfs_lookup,
2015         .link = v9fs_vfs_link_dotl,
2016         .symlink = v9fs_vfs_symlink_dotl,
2017         .unlink = v9fs_vfs_unlink,
2018         .mkdir = v9fs_vfs_mkdir_dotl,
2019         .rmdir = v9fs_vfs_rmdir,
2020         .mknod = v9fs_vfs_mknod_dotl,
2021         .rename = v9fs_vfs_rename,
2022         .getattr = v9fs_vfs_getattr_dotl,
2023         .setattr = v9fs_vfs_setattr_dotl,
2024         .setxattr = generic_setxattr,
2025         .getxattr = generic_getxattr,
2026         .removexattr = generic_removexattr,
2027         .listxattr = v9fs_listxattr,
2028         .check_acl = v9fs_check_acl,
2029 };
2030
2031 static const struct inode_operations v9fs_dir_inode_operations = {
2032         .create = v9fs_vfs_create,
2033         .lookup = v9fs_vfs_lookup,
2034         .unlink = v9fs_vfs_unlink,
2035         .mkdir = v9fs_vfs_mkdir,
2036         .rmdir = v9fs_vfs_rmdir,
2037         .mknod = v9fs_vfs_mknod,
2038         .rename = v9fs_vfs_rename,
2039         .getattr = v9fs_vfs_getattr,
2040         .setattr = v9fs_vfs_setattr,
2041 };
2042
2043 static const struct inode_operations v9fs_file_inode_operations = {
2044         .getattr = v9fs_vfs_getattr,
2045         .setattr = v9fs_vfs_setattr,
2046 };
2047
2048 static const struct inode_operations v9fs_file_inode_operations_dotl = {
2049         .getattr = v9fs_vfs_getattr_dotl,
2050         .setattr = v9fs_vfs_setattr_dotl,
2051         .setxattr = generic_setxattr,
2052         .getxattr = generic_getxattr,
2053         .removexattr = generic_removexattr,
2054         .listxattr = v9fs_listxattr,
2055         .check_acl = v9fs_check_acl,
2056 };
2057
2058 static const struct inode_operations v9fs_symlink_inode_operations = {
2059         .readlink = generic_readlink,
2060         .follow_link = v9fs_vfs_follow_link,
2061         .put_link = v9fs_vfs_put_link,
2062         .getattr = v9fs_vfs_getattr,
2063         .setattr = v9fs_vfs_setattr,
2064 };
2065
2066 static const struct inode_operations v9fs_symlink_inode_operations_dotl = {
2067         .readlink = generic_readlink,
2068         .follow_link = v9fs_vfs_follow_link,
2069         .put_link = v9fs_vfs_put_link,
2070         .getattr = v9fs_vfs_getattr_dotl,
2071         .setattr = v9fs_vfs_setattr_dotl,
2072         .setxattr = generic_setxattr,
2073         .getxattr = generic_getxattr,
2074         .removexattr = generic_removexattr,
2075         .listxattr = v9fs_listxattr,
2076 };