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