2 * linux/fs/9p/vfs_inode.c
4 * This file contains vfs inode ops for the 9P2000 protocol.
6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
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.
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.
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
26 #include <linux/module.h>
27 #include <linux/errno.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>
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
;
59 v9fs_vfs_mknod_dotl(struct inode
*dir
, struct dentry
*dentry
, int omode
,
63 * unixmode2p9mode - convert unix mode bits to plan 9
64 * @v9ses: v9fs session information
65 * @mode: mode to convert
69 static int unixmode2p9mode(struct v9fs_session_info
*v9ses
, int mode
)
75 if (v9fs_proto_dotu(v9ses
)) {
78 if (v9ses
->nodev
== 0) {
82 res
|= P9_DMNAMEDPIPE
;
89 if ((mode
& S_ISUID
) == S_ISUID
)
91 if ((mode
& S_ISGID
) == S_ISGID
)
93 if ((mode
& S_ISVTX
) == S_ISVTX
)
95 if ((mode
& P9_DMLINK
))
103 * p9mode2unixmode- convert plan9 mode bits to unix mode bits
104 * @v9ses: v9fs session information
105 * @mode: mode to convert
109 static int p9mode2unixmode(struct v9fs_session_info
*v9ses
, int mode
)
115 if ((mode
& P9_DMDIR
) == P9_DMDIR
)
117 else if ((mode
& P9_DMSYMLINK
) && (v9fs_proto_dotu(v9ses
)))
119 else if ((mode
& P9_DMSOCKET
) && (v9fs_proto_dotu(v9ses
))
120 && (v9ses
->nodev
== 0))
122 else if ((mode
& P9_DMNAMEDPIPE
) && (v9fs_proto_dotu(v9ses
))
123 && (v9ses
->nodev
== 0))
125 else if ((mode
& P9_DMDEVICE
) && (v9fs_proto_dotu(v9ses
))
126 && (v9ses
->nodev
== 0))
131 if (v9fs_proto_dotu(v9ses
)) {
132 if ((mode
& P9_DMSETUID
) == P9_DMSETUID
)
135 if ((mode
& P9_DMSETGID
) == P9_DMSETGID
)
138 if ((mode
& P9_DMSETVTX
) == P9_DMSETVTX
)
146 * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits
147 * @uflags: flags to convert
148 * @extended: if .u extensions are active
151 int v9fs_uflags2omode(int uflags
, int extended
)
171 if (uflags
& O_TRUNC
)
178 if (uflags
& O_APPEND
)
186 * v9fs_blank_wstat - helper function to setup a 9P stat structure
187 * @wstat: structure to initialize
192 v9fs_blank_wstat(struct p9_wstat
*wstat
)
196 wstat
->qid
.type
= ~0;
197 wstat
->qid
.version
= ~0;
198 *((long long *)&wstat
->qid
.path
) = ~0;
210 wstat
->extension
= NULL
;
213 #ifdef CONFIG_9P_FSCACHE
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.
221 struct inode
*v9fs_alloc_inode(struct super_block
*sb
)
223 struct v9fs_cookie
*vcookie
;
224 vcookie
= (struct v9fs_cookie
*)kmem_cache_alloc(vcookie_cache
,
229 vcookie
->fscache
= NULL
;
231 spin_lock_init(&vcookie
->lock
);
232 return &vcookie
->inode
;
236 * v9fs_destroy_inode - destroy an inode
240 static void v9fs_i_callback(struct rcu_head
*head
)
242 struct inode
*inode
= container_of(head
, struct inode
, i_rcu
);
243 INIT_LIST_HEAD(&inode
->i_dentry
);
244 kmem_cache_free(vcookie_cache
, v9fs_inode2cookie(inode
));
247 void v9fs_destroy_inode(struct inode
*inode
)
249 call_rcu(&inode
->i_rcu
, v9fs_i_callback
);
254 * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
255 * new file system object. This checks the S_ISGID to determine the owning
256 * group of the new file system object.
259 static gid_t
v9fs_get_fsgid_for_create(struct inode
*dir_inode
)
261 BUG_ON(dir_inode
== NULL
);
263 if (dir_inode
->i_mode
& S_ISGID
) {
264 /* set_gid bit is set.*/
265 return dir_inode
->i_gid
;
267 return current_fsgid();
271 * v9fs_dentry_from_dir_inode - helper function to get the dentry from
276 static struct dentry
*v9fs_dentry_from_dir_inode(struct inode
*inode
)
278 struct dentry
*dentry
;
280 spin_lock(&dcache_inode_lock
);
281 /* Directory should have only one entry. */
282 BUG_ON(S_ISDIR(inode
->i_mode
) && !list_is_singular(&inode
->i_dentry
));
283 dentry
= list_entry(inode
->i_dentry
.next
, struct dentry
, d_alias
);
284 spin_unlock(&dcache_inode_lock
);
289 * v9fs_get_inode - helper function to setup an inode
291 * @mode: mode to setup inode with
295 struct inode
*v9fs_get_inode(struct super_block
*sb
, int mode
)
299 struct v9fs_session_info
*v9ses
= sb
->s_fs_info
;
301 P9_DPRINTK(P9_DEBUG_VFS
, "super block: %p mode: %o\n", sb
, mode
);
303 inode
= new_inode(sb
);
305 P9_EPRINTK(KERN_WARNING
, "Problem allocating inode\n");
306 return ERR_PTR(-ENOMEM
);
309 inode_init_owner(inode
, NULL
, mode
);
312 inode
->i_atime
= inode
->i_mtime
= inode
->i_ctime
= CURRENT_TIME
;
313 inode
->i_mapping
->a_ops
= &v9fs_addr_operations
;
315 switch (mode
& S_IFMT
) {
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 if (v9fs_proto_dotu(v9ses
)) {
324 inode
->i_op
= &v9fs_file_inode_operations
;
325 inode
->i_fop
= &v9fs_file_operations
;
327 P9_DPRINTK(P9_DEBUG_ERROR
,
328 "special files without extended mode\n");
332 init_special_inode(inode
, inode
->i_mode
, inode
->i_rdev
);
335 if (v9fs_proto_dotl(v9ses
)) {
336 inode
->i_op
= &v9fs_file_inode_operations_dotl
;
337 inode
->i_fop
= &v9fs_file_operations_dotl
;
339 inode
->i_op
= &v9fs_file_inode_operations
;
340 inode
->i_fop
= &v9fs_file_operations
;
346 if (!v9fs_proto_dotu(v9ses
) && !v9fs_proto_dotl(v9ses
)) {
347 P9_DPRINTK(P9_DEBUG_ERROR
, "extended modes used with "
348 "legacy protocol.\n");
353 if (v9fs_proto_dotl(v9ses
))
354 inode
->i_op
= &v9fs_symlink_inode_operations_dotl
;
356 inode
->i_op
= &v9fs_symlink_inode_operations
;
361 if (v9fs_proto_dotl(v9ses
))
362 inode
->i_op
= &v9fs_dir_inode_operations_dotl
;
363 else if (v9fs_proto_dotu(v9ses
))
364 inode
->i_op
= &v9fs_dir_inode_operations_dotu
;
366 inode
->i_op
= &v9fs_dir_inode_operations
;
368 if (v9fs_proto_dotl(v9ses
))
369 inode
->i_fop
= &v9fs_dir_operations_dotl
;
371 inode
->i_fop
= &v9fs_dir_operations
;
375 P9_DPRINTK(P9_DEBUG_ERROR
, "BAD mode 0x%x S_IFMT 0x%x\n",
376 mode
, mode
& S_IFMT
);
389 static struct v9fs_fid*
390 v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry)
394 struct v9fs_fid *ret;
395 struct v9fs_fcall *fcall;
397 nfid = v9fs_get_idpool(&v9ses->fidpool);
399 eprintk(KERN_WARNING, "no free fids available\n");
400 return ERR_PTR(-ENOSPC);
403 err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name,
407 if (fcall && fcall->id == RWALK)
410 PRINT_FCALL_ERROR("walk error", fcall);
411 v9fs_put_idpool(nfid, &v9ses->fidpool);
417 ret = v9fs_fid_create(v9ses, nfid);
423 err = v9fs_fid_insert(ret, dentry);
425 v9fs_fid_destroy(ret);
432 v9fs_t_clunk(v9ses, nfid);
442 * v9fs_clear_inode - release an inode
443 * @inode: inode to release
446 void v9fs_evict_inode(struct inode
*inode
)
448 truncate_inode_pages(inode
->i_mapping
, 0);
449 end_writeback(inode
);
450 filemap_fdatawrite(inode
->i_mapping
);
452 #ifdef CONFIG_9P_FSCACHE
453 v9fs_cache_inode_put_cookie(inode
);
457 static struct inode
*
458 v9fs_inode(struct v9fs_session_info
*v9ses
, struct p9_fid
*fid
,
459 struct super_block
*sb
)
462 struct inode
*ret
= NULL
;
465 st
= p9_client_stat(fid
);
469 umode
= p9mode2unixmode(v9ses
, st
->mode
);
470 ret
= v9fs_get_inode(sb
, umode
);
476 v9fs_stat2inode(st
, ret
, sb
);
477 ret
->i_ino
= v9fs_qid2ino(&st
->qid
);
479 #ifdef CONFIG_9P_FSCACHE
480 v9fs_vcookie_set_qid(ret
, &st
->qid
);
481 v9fs_cache_inode_get_cookie(ret
);
492 static struct inode
*
493 v9fs_inode_dotl(struct v9fs_session_info
*v9ses
, struct p9_fid
*fid
,
494 struct super_block
*sb
)
496 struct inode
*ret
= NULL
;
498 struct p9_stat_dotl
*st
;
500 st
= p9_client_getattr_dotl(fid
, P9_STATS_BASIC
);
504 ret
= v9fs_get_inode(sb
, st
->st_mode
);
510 v9fs_stat2inode_dotl(st
, ret
);
511 ret
->i_ino
= v9fs_qid2ino(&st
->qid
);
512 #ifdef CONFIG_9P_FSCACHE
513 v9fs_vcookie_set_qid(ret
, &st
->qid
);
514 v9fs_cache_inode_get_cookie(ret
);
516 err
= v9fs_get_acl(ret
, fid
);
529 * v9fs_inode_from_fid - Helper routine to populate an inode by
530 * issuing a attribute request
531 * @v9ses: session information
532 * @fid: fid to issue attribute request for
533 * @sb: superblock on which to create inode
536 static inline struct inode
*
537 v9fs_inode_from_fid(struct v9fs_session_info
*v9ses
, struct p9_fid
*fid
,
538 struct super_block
*sb
)
540 if (v9fs_proto_dotl(v9ses
))
541 return v9fs_inode_dotl(v9ses
, fid
, sb
);
543 return v9fs_inode(v9ses
, fid
, sb
);
547 * v9fs_remove - helper function to remove files and directories
548 * @dir: directory inode that is being deleted
549 * @file: dentry that is being deleted
550 * @rmdir: removing a directory
554 static int v9fs_remove(struct inode
*dir
, struct dentry
*file
, int rmdir
)
557 struct inode
*file_inode
;
558 struct p9_fid
*v9fid
;
560 P9_DPRINTK(P9_DEBUG_VFS
, "inode: %p dentry: %p rmdir: %d\n", dir
, file
,
563 file_inode
= file
->d_inode
;
564 v9fid
= v9fs_fid_clone(file
);
566 return PTR_ERR(v9fid
);
568 retval
= p9_client_remove(v9fid
);
570 drop_nlink(file_inode
);
575 * v9fs_create - Create a file
576 * @v9ses: session information
577 * @dir: directory that dentry is being created in
578 * @dentry: dentry that is being created
579 * @extension: 9p2000.u extension string to support devices, etc.
580 * @perm: create permissions
584 static struct p9_fid
*
585 v9fs_create(struct v9fs_session_info
*v9ses
, struct inode
*dir
,
586 struct dentry
*dentry
, char *extension
, u32 perm
, u8 mode
)
590 struct p9_fid
*dfid
, *ofid
, *fid
;
593 P9_DPRINTK(P9_DEBUG_VFS
, "name %s\n", dentry
->d_name
.name
);
598 name
= (char *) dentry
->d_name
.name
;
599 dfid
= v9fs_fid_lookup(dentry
->d_parent
);
602 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
606 /* clone a fid to use for creation */
607 ofid
= p9_client_walk(dfid
, 0, NULL
, 1);
610 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
614 err
= p9_client_fcreate(ofid
, name
, perm
, mode
, extension
);
616 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_fcreate failed %d\n", err
);
620 /* now walk from the parent so we can get unopened fid */
621 fid
= p9_client_walk(dfid
, 1, &name
, 1);
624 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
629 /* instantiate inode and assign the unopened fid to the dentry */
630 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
632 err
= PTR_ERR(inode
);
633 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n", err
);
638 d_set_d_op(dentry
, &v9fs_cached_dentry_operations
);
640 d_set_d_op(dentry
, &v9fs_dentry_operations
);
642 d_instantiate(dentry
, inode
);
643 err
= v9fs_fid_add(dentry
, fid
);
651 p9_client_clunk(ofid
);
654 p9_client_clunk(fid
);
660 * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
661 * @dir: directory inode that is being created
662 * @dentry: dentry that is being deleted
663 * @mode: create permissions
664 * @nd: path information
669 v9fs_vfs_create_dotl(struct inode
*dir
, struct dentry
*dentry
, int omode
,
670 struct nameidata
*nd
)
677 struct v9fs_session_info
*v9ses
;
678 struct p9_fid
*fid
= NULL
;
679 struct p9_fid
*dfid
, *ofid
;
683 struct posix_acl
*pacl
= NULL
, *dacl
= NULL
;
685 v9ses
= v9fs_inode2v9ses(dir
);
686 if (nd
&& nd
->flags
& LOOKUP_OPEN
)
687 flags
= nd
->intent
.open
.flags
- 1;
690 * create call without LOOKUP_OPEN is due
691 * to mknod of regular files. So use mknod
694 return v9fs_vfs_mknod_dotl(dir
, dentry
, omode
, 0);
697 name
= (char *) dentry
->d_name
.name
;
698 P9_DPRINTK(P9_DEBUG_VFS
, "v9fs_vfs_create_dotl: name:%s flags:0x%x "
699 "mode:0x%x\n", name
, flags
, omode
);
701 dfid
= v9fs_fid_lookup(dentry
->d_parent
);
704 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
708 /* clone a fid to use for creation */
709 ofid
= p9_client_walk(dfid
, 0, NULL
, 1);
712 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
716 gid
= v9fs_get_fsgid_for_create(dir
);
719 /* Update mode based on ACL value */
720 err
= v9fs_acl_mode(dir
, &mode
, &dacl
, &pacl
);
722 P9_DPRINTK(P9_DEBUG_VFS
,
723 "Failed to get acl values in creat %d\n", err
);
726 err
= p9_client_create_dotl(ofid
, name
, flags
, mode
, gid
, &qid
);
728 P9_DPRINTK(P9_DEBUG_VFS
,
729 "p9_client_open_dotl failed in creat %d\n",
733 /* instantiate inode and assign the unopened fid to the dentry */
734 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
||
735 (nd
&& nd
->flags
& LOOKUP_OPEN
)) {
736 fid
= p9_client_walk(dfid
, 1, &name
, 1);
739 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n",
745 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
747 err
= PTR_ERR(inode
);
748 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n",
752 d_set_d_op(dentry
, &v9fs_cached_dentry_operations
);
753 d_instantiate(dentry
, inode
);
754 err
= v9fs_fid_add(dentry
, fid
);
757 /* The fid would get clunked via a dput */
761 * Not in cached mode. No need to populate
762 * inode with stat. We need to get an inode
763 * so that we can set the acl with dentry
765 inode
= v9fs_get_inode(dir
->i_sb
, mode
);
767 err
= PTR_ERR(inode
);
770 d_set_d_op(dentry
, &v9fs_dentry_operations
);
771 d_instantiate(dentry
, inode
);
773 /* Now set the ACL based on the default value */
774 v9fs_set_create_acl(dentry
, dacl
, pacl
);
776 /* if we are opening a file, assign the open fid to the file */
777 if (nd
&& nd
->flags
& LOOKUP_OPEN
) {
778 filp
= lookup_instantiate_filp(nd
, dentry
, generic_file_open
);
780 p9_client_clunk(ofid
);
781 return PTR_ERR(filp
);
783 filp
->private_data
= ofid
;
785 p9_client_clunk(ofid
);
791 p9_client_clunk(ofid
);
793 p9_client_clunk(fid
);
798 * v9fs_vfs_create - VFS hook to create files
799 * @dir: directory inode that is being created
800 * @dentry: dentry that is being deleted
801 * @mode: create permissions
802 * @nd: path information
807 v9fs_vfs_create(struct inode
*dir
, struct dentry
*dentry
, int mode
,
808 struct nameidata
*nd
)
813 struct v9fs_session_info
*v9ses
;
819 v9ses
= v9fs_inode2v9ses(dir
);
820 perm
= unixmode2p9mode(v9ses
, mode
);
821 if (nd
&& nd
->flags
& LOOKUP_OPEN
)
822 flags
= nd
->intent
.open
.flags
- 1;
826 fid
= v9fs_create(v9ses
, dir
, dentry
, NULL
, perm
,
827 v9fs_uflags2omode(flags
,
828 v9fs_proto_dotu(v9ses
)));
835 /* if we are opening a file, assign the open fid to the file */
836 if (nd
&& nd
->flags
& LOOKUP_OPEN
) {
837 filp
= lookup_instantiate_filp(nd
, dentry
, generic_file_open
);
843 filp
->private_data
= fid
;
845 p9_client_clunk(fid
);
851 p9_client_clunk(fid
);
857 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
858 * @dir: inode that is being unlinked
859 * @dentry: dentry that is being unlinked
860 * @mode: mode for new directory
864 static int v9fs_vfs_mkdir(struct inode
*dir
, struct dentry
*dentry
, int mode
)
868 struct v9fs_session_info
*v9ses
;
871 P9_DPRINTK(P9_DEBUG_VFS
, "name %s\n", dentry
->d_name
.name
);
873 v9ses
= v9fs_inode2v9ses(dir
);
874 perm
= unixmode2p9mode(v9ses
, mode
| S_IFDIR
);
875 fid
= v9fs_create(v9ses
, dir
, dentry
, NULL
, perm
, P9_OREAD
);
882 p9_client_clunk(fid
);
889 * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
890 * @dir: inode that is being unlinked
891 * @dentry: dentry that is being unlinked
892 * @mode: mode for new directory
896 static int v9fs_vfs_mkdir_dotl(struct inode
*dir
,
897 struct dentry
*dentry
, int omode
)
900 struct v9fs_session_info
*v9ses
;
901 struct p9_fid
*fid
= NULL
, *dfid
= NULL
;
907 struct dentry
*dir_dentry
;
908 struct posix_acl
*dacl
= NULL
, *pacl
= NULL
;
910 P9_DPRINTK(P9_DEBUG_VFS
, "name %s\n", dentry
->d_name
.name
);
912 v9ses
= v9fs_inode2v9ses(dir
);
915 if (dir
->i_mode
& S_ISGID
)
918 dir_dentry
= v9fs_dentry_from_dir_inode(dir
);
919 dfid
= v9fs_fid_lookup(dir_dentry
);
922 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
927 gid
= v9fs_get_fsgid_for_create(dir
);
929 /* Update mode based on ACL value */
930 err
= v9fs_acl_mode(dir
, &mode
, &dacl
, &pacl
);
932 P9_DPRINTK(P9_DEBUG_VFS
,
933 "Failed to get acl values in mkdir %d\n", err
);
936 name
= (char *) dentry
->d_name
.name
;
937 err
= p9_client_mkdir_dotl(dfid
, name
, mode
, gid
, &qid
);
941 /* instantiate inode and assign the unopened fid to the dentry */
942 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
) {
943 fid
= p9_client_walk(dfid
, 1, &name
, 1);
946 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n",
952 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
954 err
= PTR_ERR(inode
);
955 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n",
959 d_set_d_op(dentry
, &v9fs_cached_dentry_operations
);
960 d_instantiate(dentry
, inode
);
961 err
= v9fs_fid_add(dentry
, fid
);
967 * Not in cached mode. No need to populate
968 * inode with stat. We need to get an inode
969 * so that we can set the acl with dentry
971 inode
= v9fs_get_inode(dir
->i_sb
, mode
);
973 err
= PTR_ERR(inode
);
976 d_set_d_op(dentry
, &v9fs_dentry_operations
);
977 d_instantiate(dentry
, inode
);
979 /* Now set the ACL based on the default value */
980 v9fs_set_create_acl(dentry
, dacl
, pacl
);
984 p9_client_clunk(fid
);
989 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
990 * @dir: inode that is being walked from
991 * @dentry: dentry that is being walked to?
992 * @nameidata: path data
996 static struct dentry
*v9fs_vfs_lookup(struct inode
*dir
, struct dentry
*dentry
,
997 struct nameidata
*nameidata
)
999 struct super_block
*sb
;
1000 struct v9fs_session_info
*v9ses
;
1001 struct p9_fid
*dfid
, *fid
;
1002 struct inode
*inode
;
1006 P9_DPRINTK(P9_DEBUG_VFS
, "dir: %p dentry: (%s) %p nameidata: %p\n",
1007 dir
, dentry
->d_name
.name
, dentry
, nameidata
);
1009 if (dentry
->d_name
.len
> NAME_MAX
)
1010 return ERR_PTR(-ENAMETOOLONG
);
1013 v9ses
= v9fs_inode2v9ses(dir
);
1014 /* We can walk d_parent because we hold the dir->i_mutex */
1015 dfid
= v9fs_fid_lookup(dentry
->d_parent
);
1017 return ERR_CAST(dfid
);
1019 name
= (char *) dentry
->d_name
.name
;
1020 fid
= p9_client_walk(dfid
, 1, &name
, 1);
1022 result
= PTR_ERR(fid
);
1023 if (result
== -ENOENT
) {
1028 return ERR_PTR(result
);
1031 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
1032 if (IS_ERR(inode
)) {
1033 result
= PTR_ERR(inode
);
1038 result
= v9fs_fid_add(dentry
, fid
);
1044 d_set_d_op(dentry
, &v9fs_cached_dentry_operations
);
1046 d_set_d_op(dentry
, &v9fs_dentry_operations
);
1048 d_add(dentry
, inode
);
1054 p9_client_clunk(fid
);
1056 return ERR_PTR(result
);
1060 * v9fs_vfs_unlink - VFS unlink hook to delete an inode
1061 * @i: inode that is being unlinked
1062 * @d: dentry that is being unlinked
1066 static int v9fs_vfs_unlink(struct inode
*i
, struct dentry
*d
)
1068 return v9fs_remove(i
, d
, 0);
1072 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
1073 * @i: inode that is being unlinked
1074 * @d: dentry that is being unlinked
1078 static int v9fs_vfs_rmdir(struct inode
*i
, struct dentry
*d
)
1080 return v9fs_remove(i
, d
, 1);
1084 * v9fs_vfs_rename - VFS hook to rename an inode
1085 * @old_dir: old dir inode
1086 * @old_dentry: old dentry
1087 * @new_dir: new dir inode
1088 * @new_dentry: new dentry
1093 v9fs_vfs_rename(struct inode
*old_dir
, struct dentry
*old_dentry
,
1094 struct inode
*new_dir
, struct dentry
*new_dentry
)
1096 struct inode
*old_inode
;
1097 struct v9fs_session_info
*v9ses
;
1098 struct p9_fid
*oldfid
;
1099 struct p9_fid
*olddirfid
;
1100 struct p9_fid
*newdirfid
;
1101 struct p9_wstat wstat
;
1104 P9_DPRINTK(P9_DEBUG_VFS
, "\n");
1106 old_inode
= old_dentry
->d_inode
;
1107 v9ses
= v9fs_inode2v9ses(old_inode
);
1108 oldfid
= v9fs_fid_lookup(old_dentry
);
1110 return PTR_ERR(oldfid
);
1112 olddirfid
= v9fs_fid_clone(old_dentry
->d_parent
);
1113 if (IS_ERR(olddirfid
)) {
1114 retval
= PTR_ERR(olddirfid
);
1118 newdirfid
= v9fs_fid_clone(new_dentry
->d_parent
);
1119 if (IS_ERR(newdirfid
)) {
1120 retval
= PTR_ERR(newdirfid
);
1124 down_write(&v9ses
->rename_sem
);
1125 if (v9fs_proto_dotl(v9ses
)) {
1126 retval
= p9_client_rename(oldfid
, newdirfid
,
1127 (char *) new_dentry
->d_name
.name
);
1128 if (retval
!= -ENOSYS
)
1131 if (old_dentry
->d_parent
!= new_dentry
->d_parent
) {
1133 * 9P .u can only handle file rename in the same directory
1136 P9_DPRINTK(P9_DEBUG_ERROR
,
1137 "old dir and new dir are different\n");
1141 v9fs_blank_wstat(&wstat
);
1142 wstat
.muid
= v9ses
->uname
;
1143 wstat
.name
= (char *) new_dentry
->d_name
.name
;
1144 retval
= p9_client_wstat(oldfid
, &wstat
);
1148 /* successful rename */
1149 d_move(old_dentry
, new_dentry
);
1150 up_write(&v9ses
->rename_sem
);
1151 p9_client_clunk(newdirfid
);
1154 p9_client_clunk(olddirfid
);
1161 * v9fs_vfs_getattr - retrieve file metadata
1162 * @mnt: mount information
1163 * @dentry: file to get attributes on
1164 * @stat: metadata structure to populate
1169 v9fs_vfs_getattr(struct vfsmount
*mnt
, struct dentry
*dentry
,
1173 struct v9fs_session_info
*v9ses
;
1175 struct p9_wstat
*st
;
1177 P9_DPRINTK(P9_DEBUG_VFS
, "dentry: %p\n", dentry
);
1179 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1180 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
)
1181 return simple_getattr(mnt
, dentry
, stat
);
1183 fid
= v9fs_fid_lookup(dentry
);
1185 return PTR_ERR(fid
);
1187 st
= p9_client_stat(fid
);
1191 v9fs_stat2inode(st
, dentry
->d_inode
, dentry
->d_inode
->i_sb
);
1192 generic_fillattr(dentry
->d_inode
, stat
);
1200 v9fs_vfs_getattr_dotl(struct vfsmount
*mnt
, struct dentry
*dentry
,
1204 struct v9fs_session_info
*v9ses
;
1206 struct p9_stat_dotl
*st
;
1208 P9_DPRINTK(P9_DEBUG_VFS
, "dentry: %p\n", dentry
);
1210 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1211 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
)
1212 return simple_getattr(mnt
, dentry
, stat
);
1214 fid
= v9fs_fid_lookup(dentry
);
1216 return PTR_ERR(fid
);
1218 /* Ask for all the fields in stat structure. Server will return
1219 * whatever it supports
1222 st
= p9_client_getattr_dotl(fid
, P9_STATS_ALL
);
1226 v9fs_stat2inode_dotl(st
, dentry
->d_inode
);
1227 generic_fillattr(dentry
->d_inode
, stat
);
1228 /* Change block size to what the server returned */
1229 stat
->blksize
= st
->st_blksize
;
1236 * v9fs_vfs_setattr - set file metadata
1237 * @dentry: file whose metadata to set
1238 * @iattr: metadata assignment structure
1242 static int v9fs_vfs_setattr(struct dentry
*dentry
, struct iattr
*iattr
)
1245 struct v9fs_session_info
*v9ses
;
1247 struct p9_wstat wstat
;
1249 P9_DPRINTK(P9_DEBUG_VFS
, "\n");
1251 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1252 fid
= v9fs_fid_lookup(dentry
);
1254 return PTR_ERR(fid
);
1256 v9fs_blank_wstat(&wstat
);
1257 if (iattr
->ia_valid
& ATTR_MODE
)
1258 wstat
.mode
= unixmode2p9mode(v9ses
, iattr
->ia_mode
);
1260 if (iattr
->ia_valid
& ATTR_MTIME
)
1261 wstat
.mtime
= iattr
->ia_mtime
.tv_sec
;
1263 if (iattr
->ia_valid
& ATTR_ATIME
)
1264 wstat
.atime
= iattr
->ia_atime
.tv_sec
;
1266 if (iattr
->ia_valid
& ATTR_SIZE
)
1267 wstat
.length
= iattr
->ia_size
;
1269 if (v9fs_proto_dotu(v9ses
)) {
1270 if (iattr
->ia_valid
& ATTR_UID
)
1271 wstat
.n_uid
= iattr
->ia_uid
;
1273 if (iattr
->ia_valid
& ATTR_GID
)
1274 wstat
.n_gid
= iattr
->ia_gid
;
1277 retval
= p9_client_wstat(fid
, &wstat
);
1281 if ((iattr
->ia_valid
& ATTR_SIZE
) &&
1282 iattr
->ia_size
!= i_size_read(dentry
->d_inode
)) {
1283 retval
= vmtruncate(dentry
->d_inode
, iattr
->ia_size
);
1288 setattr_copy(dentry
->d_inode
, iattr
);
1289 mark_inode_dirty(dentry
->d_inode
);
1294 * v9fs_vfs_setattr_dotl - set file metadata
1295 * @dentry: file whose metadata to set
1296 * @iattr: metadata assignment structure
1300 int v9fs_vfs_setattr_dotl(struct dentry
*dentry
, struct iattr
*iattr
)
1303 struct v9fs_session_info
*v9ses
;
1305 struct p9_iattr_dotl p9attr
;
1307 P9_DPRINTK(P9_DEBUG_VFS
, "\n");
1309 retval
= inode_change_ok(dentry
->d_inode
, iattr
);
1313 p9attr
.valid
= iattr
->ia_valid
;
1314 p9attr
.mode
= iattr
->ia_mode
;
1315 p9attr
.uid
= iattr
->ia_uid
;
1316 p9attr
.gid
= iattr
->ia_gid
;
1317 p9attr
.size
= iattr
->ia_size
;
1318 p9attr
.atime_sec
= iattr
->ia_atime
.tv_sec
;
1319 p9attr
.atime_nsec
= iattr
->ia_atime
.tv_nsec
;
1320 p9attr
.mtime_sec
= iattr
->ia_mtime
.tv_sec
;
1321 p9attr
.mtime_nsec
= iattr
->ia_mtime
.tv_nsec
;
1324 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1325 fid
= v9fs_fid_lookup(dentry
);
1327 return PTR_ERR(fid
);
1329 retval
= p9_client_setattr(fid
, &p9attr
);
1333 if ((iattr
->ia_valid
& ATTR_SIZE
) &&
1334 iattr
->ia_size
!= i_size_read(dentry
->d_inode
)) {
1335 retval
= vmtruncate(dentry
->d_inode
, iattr
->ia_size
);
1340 setattr_copy(dentry
->d_inode
, iattr
);
1341 mark_inode_dirty(dentry
->d_inode
);
1342 if (iattr
->ia_valid
& ATTR_MODE
) {
1343 /* We also want to update ACL when we update mode bits */
1344 retval
= v9fs_acl_chmod(dentry
);
1352 * v9fs_stat2inode - populate an inode structure with mistat info
1353 * @stat: Plan 9 metadata (mistat) structure
1354 * @inode: inode to populate
1355 * @sb: superblock of filesystem
1360 v9fs_stat2inode(struct p9_wstat
*stat
, struct inode
*inode
,
1361 struct super_block
*sb
)
1365 unsigned int i_nlink
;
1366 struct v9fs_session_info
*v9ses
= sb
->s_fs_info
;
1370 inode
->i_atime
.tv_sec
= stat
->atime
;
1371 inode
->i_mtime
.tv_sec
= stat
->mtime
;
1372 inode
->i_ctime
.tv_sec
= stat
->mtime
;
1374 inode
->i_uid
= v9ses
->dfltuid
;
1375 inode
->i_gid
= v9ses
->dfltgid
;
1377 if (v9fs_proto_dotu(v9ses
)) {
1378 inode
->i_uid
= stat
->n_uid
;
1379 inode
->i_gid
= stat
->n_gid
;
1381 if ((S_ISREG(inode
->i_mode
)) || (S_ISDIR(inode
->i_mode
))) {
1382 if (v9fs_proto_dotu(v9ses
) && (stat
->extension
[0] != '\0')) {
1384 * Hadlink support got added later to
1385 * to the .u extension. So there can be
1386 * server out there that doesn't support
1387 * this even with .u extension. So check
1388 * for non NULL stat->extension
1390 strncpy(ext
, stat
->extension
, sizeof(ext
));
1391 /* HARDLINKCOUNT %u */
1392 sscanf(ext
, "%13s %u", tag_name
, &i_nlink
);
1393 if (!strncmp(tag_name
, "HARDLINKCOUNT", 13))
1394 inode
->i_nlink
= i_nlink
;
1397 inode
->i_mode
= p9mode2unixmode(v9ses
, stat
->mode
);
1398 if ((S_ISBLK(inode
->i_mode
)) || (S_ISCHR(inode
->i_mode
))) {
1403 strncpy(ext
, stat
->extension
, sizeof(ext
));
1404 sscanf(ext
, "%c %u %u", &type
, &major
, &minor
);
1407 inode
->i_mode
&= ~S_IFBLK
;
1408 inode
->i_mode
|= S_IFCHR
;
1413 P9_DPRINTK(P9_DEBUG_ERROR
,
1414 "Unknown special type %c %s\n", type
,
1417 inode
->i_rdev
= MKDEV(major
, minor
);
1418 init_special_inode(inode
, inode
->i_mode
, inode
->i_rdev
);
1422 i_size_write(inode
, stat
->length
);
1424 /* not real number of blocks, but 512 byte ones ... */
1425 inode
->i_blocks
= (i_size_read(inode
) + 512 - 1) >> 9;
1429 * v9fs_stat2inode_dotl - populate an inode structure with stat info
1430 * @stat: stat structure
1431 * @inode: inode to populate
1432 * @sb: superblock of filesystem
1437 v9fs_stat2inode_dotl(struct p9_stat_dotl
*stat
, struct inode
*inode
)
1440 if ((stat
->st_result_mask
& P9_STATS_BASIC
) == P9_STATS_BASIC
) {
1441 inode
->i_atime
.tv_sec
= stat
->st_atime_sec
;
1442 inode
->i_atime
.tv_nsec
= stat
->st_atime_nsec
;
1443 inode
->i_mtime
.tv_sec
= stat
->st_mtime_sec
;
1444 inode
->i_mtime
.tv_nsec
= stat
->st_mtime_nsec
;
1445 inode
->i_ctime
.tv_sec
= stat
->st_ctime_sec
;
1446 inode
->i_ctime
.tv_nsec
= stat
->st_ctime_nsec
;
1447 inode
->i_uid
= stat
->st_uid
;
1448 inode
->i_gid
= stat
->st_gid
;
1449 inode
->i_nlink
= stat
->st_nlink
;
1450 inode
->i_mode
= stat
->st_mode
;
1451 inode
->i_rdev
= new_decode_dev(stat
->st_rdev
);
1453 if ((S_ISBLK(inode
->i_mode
)) || (S_ISCHR(inode
->i_mode
)))
1454 init_special_inode(inode
, inode
->i_mode
, inode
->i_rdev
);
1456 i_size_write(inode
, stat
->st_size
);
1457 inode
->i_blocks
= stat
->st_blocks
;
1459 if (stat
->st_result_mask
& P9_STATS_ATIME
) {
1460 inode
->i_atime
.tv_sec
= stat
->st_atime_sec
;
1461 inode
->i_atime
.tv_nsec
= stat
->st_atime_nsec
;
1463 if (stat
->st_result_mask
& P9_STATS_MTIME
) {
1464 inode
->i_mtime
.tv_sec
= stat
->st_mtime_sec
;
1465 inode
->i_mtime
.tv_nsec
= stat
->st_mtime_nsec
;
1467 if (stat
->st_result_mask
& P9_STATS_CTIME
) {
1468 inode
->i_ctime
.tv_sec
= stat
->st_ctime_sec
;
1469 inode
->i_ctime
.tv_nsec
= stat
->st_ctime_nsec
;
1471 if (stat
->st_result_mask
& P9_STATS_UID
)
1472 inode
->i_uid
= stat
->st_uid
;
1473 if (stat
->st_result_mask
& P9_STATS_GID
)
1474 inode
->i_gid
= stat
->st_gid
;
1475 if (stat
->st_result_mask
& P9_STATS_NLINK
)
1476 inode
->i_nlink
= stat
->st_nlink
;
1477 if (stat
->st_result_mask
& P9_STATS_MODE
) {
1478 inode
->i_mode
= stat
->st_mode
;
1479 if ((S_ISBLK(inode
->i_mode
)) ||
1480 (S_ISCHR(inode
->i_mode
)))
1481 init_special_inode(inode
, inode
->i_mode
,
1484 if (stat
->st_result_mask
& P9_STATS_RDEV
)
1485 inode
->i_rdev
= new_decode_dev(stat
->st_rdev
);
1486 if (stat
->st_result_mask
& P9_STATS_SIZE
)
1487 i_size_write(inode
, stat
->st_size
);
1488 if (stat
->st_result_mask
& P9_STATS_BLOCKS
)
1489 inode
->i_blocks
= stat
->st_blocks
;
1491 if (stat
->st_result_mask
& P9_STATS_GEN
)
1492 inode
->i_generation
= stat
->st_gen
;
1494 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
1495 * because the inode structure does not have fields for them.
1500 * v9fs_qid2ino - convert qid into inode number
1503 * BUG: potential for inode number collisions?
1506 ino_t
v9fs_qid2ino(struct p9_qid
*qid
)
1508 u64 path
= qid
->path
+ 2;
1511 if (sizeof(ino_t
) == sizeof(path
))
1512 memcpy(&i
, &path
, sizeof(ino_t
));
1514 i
= (ino_t
) (path
^ (path
>> 32));
1520 * v9fs_readlink - read a symlink's location (internal version)
1521 * @dentry: dentry for symlink
1522 * @buffer: buffer to load symlink location into
1523 * @buflen: length of buffer
1527 static int v9fs_readlink(struct dentry
*dentry
, char *buffer
, int buflen
)
1531 struct v9fs_session_info
*v9ses
;
1533 struct p9_wstat
*st
;
1535 P9_DPRINTK(P9_DEBUG_VFS
, " %s\n", dentry
->d_name
.name
);
1537 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1538 fid
= v9fs_fid_lookup(dentry
);
1540 return PTR_ERR(fid
);
1542 if (!v9fs_proto_dotu(v9ses
))
1545 st
= p9_client_stat(fid
);
1549 if (!(st
->mode
& P9_DMSYMLINK
)) {
1554 /* copy extension buffer into buffer */
1555 strncpy(buffer
, st
->extension
, buflen
);
1557 P9_DPRINTK(P9_DEBUG_VFS
,
1558 "%s -> %s (%s)\n", dentry
->d_name
.name
, st
->extension
, buffer
);
1560 retval
= strnlen(buffer
, buflen
);
1568 * v9fs_vfs_follow_link - follow a symlink path
1569 * @dentry: dentry for symlink
1574 static void *v9fs_vfs_follow_link(struct dentry
*dentry
, struct nameidata
*nd
)
1577 char *link
= __getname();
1579 P9_DPRINTK(P9_DEBUG_VFS
, "%s n", dentry
->d_name
.name
);
1582 link
= ERR_PTR(-ENOMEM
);
1584 len
= v9fs_readlink(dentry
, link
, PATH_MAX
);
1588 link
= ERR_PTR(len
);
1590 link
[min(len
, PATH_MAX
-1)] = 0;
1592 nd_set_link(nd
, link
);
1598 * v9fs_vfs_put_link - release a symlink path
1599 * @dentry: dentry for symlink
1606 v9fs_vfs_put_link(struct dentry
*dentry
, struct nameidata
*nd
, void *p
)
1608 char *s
= nd_get_link(nd
);
1610 P9_DPRINTK(P9_DEBUG_VFS
, " %s %s\n", dentry
->d_name
.name
,
1611 IS_ERR(s
) ? "<error>" : s
);
1617 * v9fs_vfs_mkspecial - create a special file
1618 * @dir: inode to create special file in
1619 * @dentry: dentry to create
1620 * @mode: mode to create special file
1621 * @extension: 9p2000.u format extension string representing special file
1625 static int v9fs_vfs_mkspecial(struct inode
*dir
, struct dentry
*dentry
,
1626 int mode
, const char *extension
)
1629 struct v9fs_session_info
*v9ses
;
1632 v9ses
= v9fs_inode2v9ses(dir
);
1633 if (!v9fs_proto_dotu(v9ses
)) {
1634 P9_DPRINTK(P9_DEBUG_ERROR
, "not extended\n");
1638 perm
= unixmode2p9mode(v9ses
, mode
);
1639 fid
= v9fs_create(v9ses
, dir
, dentry
, (char *) extension
, perm
,
1642 return PTR_ERR(fid
);
1644 p9_client_clunk(fid
);
1649 * v9fs_vfs_symlink_dotl - helper function to create symlinks
1650 * @dir: directory inode containing symlink
1651 * @dentry: dentry for symlink
1652 * @symname: symlink data
1654 * See Also: 9P2000.L RFC for more information
1659 v9fs_vfs_symlink_dotl(struct inode
*dir
, struct dentry
*dentry
,
1660 const char *symname
)
1662 struct v9fs_session_info
*v9ses
;
1663 struct p9_fid
*dfid
;
1664 struct p9_fid
*fid
= NULL
;
1665 struct inode
*inode
;
1671 name
= (char *) dentry
->d_name
.name
;
1672 P9_DPRINTK(P9_DEBUG_VFS
, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n",
1673 dir
->i_ino
, name
, symname
);
1674 v9ses
= v9fs_inode2v9ses(dir
);
1676 dfid
= v9fs_fid_lookup(dentry
->d_parent
);
1678 err
= PTR_ERR(dfid
);
1679 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
1683 gid
= v9fs_get_fsgid_for_create(dir
);
1685 /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
1686 err
= p9_client_symlink(dfid
, name
, (char *)symname
, gid
, &qid
);
1689 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_symlink failed %d\n", err
);
1694 /* Now walk from the parent so we can get an unopened fid. */
1695 fid
= p9_client_walk(dfid
, 1, &name
, 1);
1698 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n",
1704 /* instantiate inode and assign the unopened fid to dentry */
1705 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
1706 if (IS_ERR(inode
)) {
1707 err
= PTR_ERR(inode
);
1708 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n",
1712 d_set_d_op(dentry
, &v9fs_cached_dentry_operations
);
1713 d_instantiate(dentry
, inode
);
1714 err
= v9fs_fid_add(dentry
, fid
);
1719 /* Not in cached mode. No need to populate inode with stat */
1720 inode
= v9fs_get_inode(dir
->i_sb
, S_IFLNK
);
1721 if (IS_ERR(inode
)) {
1722 err
= PTR_ERR(inode
);
1725 d_set_d_op(dentry
, &v9fs_dentry_operations
);
1726 d_instantiate(dentry
, inode
);
1731 p9_client_clunk(fid
);
1737 * v9fs_vfs_symlink - helper function to create symlinks
1738 * @dir: directory inode containing symlink
1739 * @dentry: dentry for symlink
1740 * @symname: symlink data
1742 * See Also: 9P2000.u RFC for more information
1747 v9fs_vfs_symlink(struct inode
*dir
, struct dentry
*dentry
, const char *symname
)
1749 P9_DPRINTK(P9_DEBUG_VFS
, " %lu,%s,%s\n", dir
->i_ino
,
1750 dentry
->d_name
.name
, symname
);
1752 return v9fs_vfs_mkspecial(dir
, dentry
, S_IFLNK
, symname
);
1756 * v9fs_vfs_link - create a hardlink
1757 * @old_dentry: dentry for file to link to
1758 * @dir: inode destination for new link
1759 * @dentry: dentry for link
1764 v9fs_vfs_link(struct dentry
*old_dentry
, struct inode
*dir
,
1765 struct dentry
*dentry
)
1768 struct p9_fid
*oldfid
;
1771 P9_DPRINTK(P9_DEBUG_VFS
,
1772 " %lu,%s,%s\n", dir
->i_ino
, dentry
->d_name
.name
,
1773 old_dentry
->d_name
.name
);
1775 oldfid
= v9fs_fid_clone(old_dentry
);
1777 return PTR_ERR(oldfid
);
1780 if (unlikely(!name
)) {
1785 sprintf(name
, "%d\n", oldfid
->fid
);
1786 retval
= v9fs_vfs_mkspecial(dir
, dentry
, P9_DMLINK
, name
);
1790 p9_client_clunk(oldfid
);
1795 * v9fs_vfs_link_dotl - create a hardlink for dotl
1796 * @old_dentry: dentry for file to link to
1797 * @dir: inode destination for new link
1798 * @dentry: dentry for link
1803 v9fs_vfs_link_dotl(struct dentry
*old_dentry
, struct inode
*dir
,
1804 struct dentry
*dentry
)
1807 struct p9_fid
*dfid
, *oldfid
;
1809 struct v9fs_session_info
*v9ses
;
1810 struct dentry
*dir_dentry
;
1812 P9_DPRINTK(P9_DEBUG_VFS
, "dir ino: %lu, old_name: %s, new_name: %s\n",
1813 dir
->i_ino
, old_dentry
->d_name
.name
,
1814 dentry
->d_name
.name
);
1816 v9ses
= v9fs_inode2v9ses(dir
);
1817 dir_dentry
= v9fs_dentry_from_dir_inode(dir
);
1818 dfid
= v9fs_fid_lookup(dir_dentry
);
1820 return PTR_ERR(dfid
);
1822 oldfid
= v9fs_fid_lookup(old_dentry
);
1824 return PTR_ERR(oldfid
);
1826 name
= (char *) dentry
->d_name
.name
;
1828 err
= p9_client_link(dfid
, oldfid
, (char *)dentry
->d_name
.name
);
1831 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_link failed %d\n", err
);
1835 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
) {
1836 /* Get the latest stat info from server. */
1838 struct p9_stat_dotl
*st
;
1840 fid
= v9fs_fid_lookup(old_dentry
);
1842 return PTR_ERR(fid
);
1844 st
= p9_client_getattr_dotl(fid
, P9_STATS_BASIC
);
1848 v9fs_stat2inode_dotl(st
, old_dentry
->d_inode
);
1852 /* Caching disabled. No need to get upto date stat info.
1853 * This dentry will be released immediately. So, just hold the
1856 ihold(old_dentry
->d_inode
);
1859 d_set_d_op(dentry
, old_dentry
->d_op
);
1860 d_instantiate(dentry
, old_dentry
->d_inode
);
1866 * v9fs_vfs_mknod - create a special file
1867 * @dir: inode destination for new link
1868 * @dentry: dentry for file
1869 * @mode: mode for creation
1870 * @rdev: device associated with special file
1875 v9fs_vfs_mknod(struct inode
*dir
, struct dentry
*dentry
, int mode
, dev_t rdev
)
1880 P9_DPRINTK(P9_DEBUG_VFS
,
1881 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir
->i_ino
,
1882 dentry
->d_name
.name
, mode
, MAJOR(rdev
), MINOR(rdev
));
1884 if (!new_valid_dev(rdev
))
1890 /* build extension */
1892 sprintf(name
, "b %u %u", MAJOR(rdev
), MINOR(rdev
));
1893 else if (S_ISCHR(mode
))
1894 sprintf(name
, "c %u %u", MAJOR(rdev
), MINOR(rdev
));
1895 else if (S_ISFIFO(mode
))
1897 else if (S_ISSOCK(mode
))
1904 retval
= v9fs_vfs_mkspecial(dir
, dentry
, mode
, name
);
1911 * v9fs_vfs_mknod_dotl - create a special file
1912 * @dir: inode destination for new link
1913 * @dentry: dentry for file
1914 * @mode: mode for creation
1915 * @rdev: device associated with special file
1919 v9fs_vfs_mknod_dotl(struct inode
*dir
, struct dentry
*dentry
, int omode
,
1925 struct v9fs_session_info
*v9ses
;
1926 struct p9_fid
*fid
= NULL
, *dfid
= NULL
;
1927 struct inode
*inode
;
1930 struct dentry
*dir_dentry
;
1931 struct posix_acl
*dacl
= NULL
, *pacl
= NULL
;
1933 P9_DPRINTK(P9_DEBUG_VFS
,
1934 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir
->i_ino
,
1935 dentry
->d_name
.name
, omode
, MAJOR(rdev
), MINOR(rdev
));
1937 if (!new_valid_dev(rdev
))
1940 v9ses
= v9fs_inode2v9ses(dir
);
1941 dir_dentry
= v9fs_dentry_from_dir_inode(dir
);
1942 dfid
= v9fs_fid_lookup(dir_dentry
);
1944 err
= PTR_ERR(dfid
);
1945 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
1950 gid
= v9fs_get_fsgid_for_create(dir
);
1952 /* Update mode based on ACL value */
1953 err
= v9fs_acl_mode(dir
, &mode
, &dacl
, &pacl
);
1955 P9_DPRINTK(P9_DEBUG_VFS
,
1956 "Failed to get acl values in mknod %d\n", err
);
1959 name
= (char *) dentry
->d_name
.name
;
1961 err
= p9_client_mknod_dotl(dfid
, name
, mode
, rdev
, gid
, &qid
);
1965 /* instantiate inode and assign the unopened fid to the dentry */
1966 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
) {
1967 fid
= p9_client_walk(dfid
, 1, &name
, 1);
1970 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n",
1976 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
1977 if (IS_ERR(inode
)) {
1978 err
= PTR_ERR(inode
);
1979 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n",
1983 d_set_d_op(dentry
, &v9fs_cached_dentry_operations
);
1984 d_instantiate(dentry
, inode
);
1985 err
= v9fs_fid_add(dentry
, fid
);
1991 * Not in cached mode. No need to populate inode with stat.
1992 * socket syscall returns a fd, so we need instantiate
1994 inode
= v9fs_get_inode(dir
->i_sb
, mode
);
1995 if (IS_ERR(inode
)) {
1996 err
= PTR_ERR(inode
);
1999 d_set_d_op(dentry
, &v9fs_dentry_operations
);
2000 d_instantiate(dentry
, inode
);
2002 /* Now set the ACL based on the default value */
2003 v9fs_set_create_acl(dentry
, dacl
, pacl
);
2006 p9_client_clunk(fid
);
2011 v9fs_vfs_readlink_dotl(struct dentry
*dentry
, char *buffer
, int buflen
)
2015 char *target
= NULL
;
2017 P9_DPRINTK(P9_DEBUG_VFS
, " %s\n", dentry
->d_name
.name
);
2019 fid
= v9fs_fid_lookup(dentry
);
2021 return PTR_ERR(fid
);
2023 retval
= p9_client_readlink(fid
, &target
);
2027 strncpy(buffer
, target
, buflen
);
2028 P9_DPRINTK(P9_DEBUG_VFS
, "%s -> %s\n", dentry
->d_name
.name
, buffer
);
2030 retval
= strnlen(buffer
, buflen
);
2035 * v9fs_vfs_follow_link_dotl - follow a symlink path
2036 * @dentry: dentry for symlink
2042 v9fs_vfs_follow_link_dotl(struct dentry
*dentry
, struct nameidata
*nd
)
2045 char *link
= __getname();
2047 P9_DPRINTK(P9_DEBUG_VFS
, "%s n", dentry
->d_name
.name
);
2050 link
= ERR_PTR(-ENOMEM
);
2052 len
= v9fs_vfs_readlink_dotl(dentry
, link
, PATH_MAX
);
2055 link
= ERR_PTR(len
);
2057 link
[min(len
, PATH_MAX
-1)] = 0;
2059 nd_set_link(nd
, link
);
2064 static const struct inode_operations v9fs_dir_inode_operations_dotu
= {
2065 .create
= v9fs_vfs_create
,
2066 .lookup
= v9fs_vfs_lookup
,
2067 .symlink
= v9fs_vfs_symlink
,
2068 .link
= v9fs_vfs_link
,
2069 .unlink
= v9fs_vfs_unlink
,
2070 .mkdir
= v9fs_vfs_mkdir
,
2071 .rmdir
= v9fs_vfs_rmdir
,
2072 .mknod
= v9fs_vfs_mknod
,
2073 .rename
= v9fs_vfs_rename
,
2074 .getattr
= v9fs_vfs_getattr
,
2075 .setattr
= v9fs_vfs_setattr
,
2078 static const struct inode_operations v9fs_dir_inode_operations_dotl
= {
2079 .create
= v9fs_vfs_create_dotl
,
2080 .lookup
= v9fs_vfs_lookup
,
2081 .link
= v9fs_vfs_link_dotl
,
2082 .symlink
= v9fs_vfs_symlink_dotl
,
2083 .unlink
= v9fs_vfs_unlink
,
2084 .mkdir
= v9fs_vfs_mkdir_dotl
,
2085 .rmdir
= v9fs_vfs_rmdir
,
2086 .mknod
= v9fs_vfs_mknod_dotl
,
2087 .rename
= v9fs_vfs_rename
,
2088 .getattr
= v9fs_vfs_getattr_dotl
,
2089 .setattr
= v9fs_vfs_setattr_dotl
,
2090 .setxattr
= generic_setxattr
,
2091 .getxattr
= generic_getxattr
,
2092 .removexattr
= generic_removexattr
,
2093 .listxattr
= v9fs_listxattr
,
2094 .check_acl
= v9fs_check_acl
,
2097 static const struct inode_operations v9fs_dir_inode_operations
= {
2098 .create
= v9fs_vfs_create
,
2099 .lookup
= v9fs_vfs_lookup
,
2100 .unlink
= v9fs_vfs_unlink
,
2101 .mkdir
= v9fs_vfs_mkdir
,
2102 .rmdir
= v9fs_vfs_rmdir
,
2103 .mknod
= v9fs_vfs_mknod
,
2104 .rename
= v9fs_vfs_rename
,
2105 .getattr
= v9fs_vfs_getattr
,
2106 .setattr
= v9fs_vfs_setattr
,
2109 static const struct inode_operations v9fs_file_inode_operations
= {
2110 .getattr
= v9fs_vfs_getattr
,
2111 .setattr
= v9fs_vfs_setattr
,
2114 static const struct inode_operations v9fs_file_inode_operations_dotl
= {
2115 .getattr
= v9fs_vfs_getattr_dotl
,
2116 .setattr
= v9fs_vfs_setattr_dotl
,
2117 .setxattr
= generic_setxattr
,
2118 .getxattr
= generic_getxattr
,
2119 .removexattr
= generic_removexattr
,
2120 .listxattr
= v9fs_listxattr
,
2121 .check_acl
= v9fs_check_acl
,
2124 static const struct inode_operations v9fs_symlink_inode_operations
= {
2125 .readlink
= generic_readlink
,
2126 .follow_link
= v9fs_vfs_follow_link
,
2127 .put_link
= v9fs_vfs_put_link
,
2128 .getattr
= v9fs_vfs_getattr
,
2129 .setattr
= v9fs_vfs_setattr
,
2132 static const struct inode_operations v9fs_symlink_inode_operations_dotl
= {
2133 .readlink
= v9fs_vfs_readlink_dotl
,
2134 .follow_link
= v9fs_vfs_follow_link_dotl
,
2135 .put_link
= v9fs_vfs_put_link
,
2136 .getattr
= v9fs_vfs_getattr_dotl
,
2137 .setattr
= v9fs_vfs_setattr_dotl
,
2138 .setxattr
= generic_setxattr
,
2139 .getxattr
= generic_getxattr
,
2140 .removexattr
= generic_removexattr
,
2141 .listxattr
= v9fs_listxattr
,