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