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 <net/9p/9p.h>
40 #include <net/9p/client.h>
48 static const struct inode_operations v9fs_dir_inode_operations
;
49 static const struct inode_operations v9fs_dir_inode_operations_dotu
;
50 static const struct inode_operations v9fs_dir_inode_operations_dotl
;
51 static const struct inode_operations v9fs_file_inode_operations
;
52 static const struct inode_operations v9fs_file_inode_operations_dotl
;
53 static const struct inode_operations v9fs_symlink_inode_operations
;
54 static const struct inode_operations v9fs_symlink_inode_operations_dotl
;
57 * unixmode2p9mode - convert unix mode bits to plan 9
58 * @v9ses: v9fs session information
59 * @mode: mode to convert
63 static int unixmode2p9mode(struct v9fs_session_info
*v9ses
, int mode
)
69 if (v9fs_proto_dotu(v9ses
)) {
72 if (v9ses
->nodev
== 0) {
76 res
|= P9_DMNAMEDPIPE
;
83 if ((mode
& S_ISUID
) == S_ISUID
)
85 if ((mode
& S_ISGID
) == S_ISGID
)
87 if ((mode
& S_ISVTX
) == S_ISVTX
)
89 if ((mode
& P9_DMLINK
))
97 * p9mode2unixmode- convert plan9 mode bits to unix mode bits
98 * @v9ses: v9fs session information
99 * @mode: mode to convert
103 static int p9mode2unixmode(struct v9fs_session_info
*v9ses
, int mode
)
109 if ((mode
& P9_DMDIR
) == P9_DMDIR
)
111 else if ((mode
& P9_DMSYMLINK
) && (v9fs_proto_dotu(v9ses
)))
113 else if ((mode
& P9_DMSOCKET
) && (v9fs_proto_dotu(v9ses
))
114 && (v9ses
->nodev
== 0))
116 else if ((mode
& P9_DMNAMEDPIPE
) && (v9fs_proto_dotu(v9ses
))
117 && (v9ses
->nodev
== 0))
119 else if ((mode
& P9_DMDEVICE
) && (v9fs_proto_dotu(v9ses
))
120 && (v9ses
->nodev
== 0))
125 if (v9fs_proto_dotu(v9ses
)) {
126 if ((mode
& P9_DMSETUID
) == P9_DMSETUID
)
129 if ((mode
& P9_DMSETGID
) == P9_DMSETGID
)
132 if ((mode
& P9_DMSETVTX
) == P9_DMSETVTX
)
140 * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits
141 * @uflags: flags to convert
142 * @extended: if .u extensions are active
145 int v9fs_uflags2omode(int uflags
, int extended
)
165 if (uflags
& O_TRUNC
)
172 if (uflags
& O_APPEND
)
180 * v9fs_blank_wstat - helper function to setup a 9P stat structure
181 * @wstat: structure to initialize
186 v9fs_blank_wstat(struct p9_wstat
*wstat
)
190 wstat
->qid
.type
= ~0;
191 wstat
->qid
.version
= ~0;
192 *((long long *)&wstat
->qid
.path
) = ~0;
204 wstat
->extension
= NULL
;
207 #ifdef CONFIG_9P_FSCACHE
209 * v9fs_alloc_inode - helper function to allocate an inode
210 * This callback is executed before setting up the inode so that we
211 * can associate a vcookie with each inode.
215 struct inode
*v9fs_alloc_inode(struct super_block
*sb
)
217 struct v9fs_cookie
*vcookie
;
218 vcookie
= (struct v9fs_cookie
*)kmem_cache_alloc(vcookie_cache
,
223 vcookie
->fscache
= NULL
;
225 spin_lock_init(&vcookie
->lock
);
226 return &vcookie
->inode
;
230 * v9fs_destroy_inode - destroy an inode
234 void v9fs_destroy_inode(struct inode
*inode
)
236 kmem_cache_free(vcookie_cache
, v9fs_inode2cookie(inode
));
241 * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
242 * new file system object. This checks the S_ISGID to determine the owning
243 * group of the new file system object.
246 static gid_t
v9fs_get_fsgid_for_create(struct inode
*dir_inode
)
248 BUG_ON(dir_inode
== NULL
);
250 if (dir_inode
->i_mode
& S_ISGID
) {
251 /* set_gid bit is set.*/
252 return dir_inode
->i_gid
;
254 return current_fsgid();
258 * v9fs_dentry_from_dir_inode - helper function to get the dentry from
263 static struct dentry
*v9fs_dentry_from_dir_inode(struct inode
*inode
)
265 struct dentry
*dentry
;
267 spin_lock(&dcache_lock
);
268 /* Directory should have only one entry. */
269 BUG_ON(S_ISDIR(inode
->i_mode
) && !list_is_singular(&inode
->i_dentry
));
270 dentry
= list_entry(inode
->i_dentry
.next
, struct dentry
, d_alias
);
271 spin_unlock(&dcache_lock
);
276 * v9fs_get_inode - helper function to setup an inode
278 * @mode: mode to setup inode with
282 struct inode
*v9fs_get_inode(struct super_block
*sb
, int mode
)
286 struct v9fs_session_info
*v9ses
= sb
->s_fs_info
;
288 P9_DPRINTK(P9_DEBUG_VFS
, "super block: %p mode: %o\n", sb
, mode
);
290 inode
= new_inode(sb
);
292 P9_EPRINTK(KERN_WARNING
, "Problem allocating inode\n");
293 return ERR_PTR(-ENOMEM
);
296 inode_init_owner(inode
, NULL
, mode
);
299 inode
->i_atime
= inode
->i_mtime
= inode
->i_ctime
= CURRENT_TIME
;
300 inode
->i_mapping
->a_ops
= &v9fs_addr_operations
;
302 switch (mode
& S_IFMT
) {
307 if (v9fs_proto_dotl(v9ses
)) {
308 inode
->i_op
= &v9fs_file_inode_operations_dotl
;
309 inode
->i_fop
= &v9fs_file_operations_dotl
;
310 } else if (v9fs_proto_dotu(v9ses
)) {
311 inode
->i_op
= &v9fs_file_inode_operations
;
312 inode
->i_fop
= &v9fs_file_operations
;
314 P9_DPRINTK(P9_DEBUG_ERROR
,
315 "special files without extended mode\n");
319 init_special_inode(inode
, inode
->i_mode
, inode
->i_rdev
);
322 if (v9fs_proto_dotl(v9ses
)) {
323 inode
->i_op
= &v9fs_file_inode_operations_dotl
;
324 inode
->i_fop
= &v9fs_file_operations_dotl
;
326 inode
->i_op
= &v9fs_file_inode_operations
;
327 inode
->i_fop
= &v9fs_file_operations
;
333 if (!v9fs_proto_dotu(v9ses
) && !v9fs_proto_dotl(v9ses
)) {
334 P9_DPRINTK(P9_DEBUG_ERROR
, "extended modes used with "
335 "legacy protocol.\n");
340 if (v9fs_proto_dotl(v9ses
))
341 inode
->i_op
= &v9fs_symlink_inode_operations_dotl
;
343 inode
->i_op
= &v9fs_symlink_inode_operations
;
348 if (v9fs_proto_dotl(v9ses
))
349 inode
->i_op
= &v9fs_dir_inode_operations_dotl
;
350 else if (v9fs_proto_dotu(v9ses
))
351 inode
->i_op
= &v9fs_dir_inode_operations_dotu
;
353 inode
->i_op
= &v9fs_dir_inode_operations
;
355 if (v9fs_proto_dotl(v9ses
))
356 inode
->i_fop
= &v9fs_dir_operations_dotl
;
358 inode
->i_fop
= &v9fs_dir_operations
;
362 P9_DPRINTK(P9_DEBUG_ERROR
, "BAD mode 0x%x S_IFMT 0x%x\n",
363 mode
, mode
& S_IFMT
);
376 static struct v9fs_fid*
377 v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry)
381 struct v9fs_fid *ret;
382 struct v9fs_fcall *fcall;
384 nfid = v9fs_get_idpool(&v9ses->fidpool);
386 eprintk(KERN_WARNING, "no free fids available\n");
387 return ERR_PTR(-ENOSPC);
390 err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name,
394 if (fcall && fcall->id == RWALK)
397 PRINT_FCALL_ERROR("walk error", fcall);
398 v9fs_put_idpool(nfid, &v9ses->fidpool);
404 ret = v9fs_fid_create(v9ses, nfid);
410 err = v9fs_fid_insert(ret, dentry);
412 v9fs_fid_destroy(ret);
419 v9fs_t_clunk(v9ses, nfid);
429 * v9fs_clear_inode - release an inode
430 * @inode: inode to release
433 void v9fs_clear_inode(struct inode
*inode
)
435 filemap_fdatawrite(inode
->i_mapping
);
437 #ifdef CONFIG_9P_FSCACHE
438 v9fs_cache_inode_put_cookie(inode
);
442 static struct inode
*
443 v9fs_inode(struct v9fs_session_info
*v9ses
, struct p9_fid
*fid
,
444 struct super_block
*sb
)
447 struct inode
*ret
= NULL
;
450 st
= p9_client_stat(fid
);
454 umode
= p9mode2unixmode(v9ses
, st
->mode
);
455 ret
= v9fs_get_inode(sb
, umode
);
461 v9fs_stat2inode(st
, ret
, sb
);
462 ret
->i_ino
= v9fs_qid2ino(&st
->qid
);
464 #ifdef CONFIG_9P_FSCACHE
465 v9fs_vcookie_set_qid(ret
, &st
->qid
);
466 v9fs_cache_inode_get_cookie(ret
);
477 static struct inode
*
478 v9fs_inode_dotl(struct v9fs_session_info
*v9ses
, struct p9_fid
*fid
,
479 struct super_block
*sb
)
481 struct inode
*ret
= NULL
;
483 struct p9_stat_dotl
*st
;
485 st
= p9_client_getattr_dotl(fid
, P9_STATS_BASIC
);
489 ret
= v9fs_get_inode(sb
, st
->st_mode
);
495 v9fs_stat2inode_dotl(st
, ret
);
496 ret
->i_ino
= v9fs_qid2ino(&st
->qid
);
497 #ifdef CONFIG_9P_FSCACHE
498 v9fs_vcookie_set_qid(ret
, &st
->qid
);
499 v9fs_cache_inode_get_cookie(ret
);
509 * v9fs_inode_from_fid - Helper routine to populate an inode by
510 * issuing a attribute request
511 * @v9ses: session information
512 * @fid: fid to issue attribute request for
513 * @sb: superblock on which to create inode
516 static inline struct inode
*
517 v9fs_inode_from_fid(struct v9fs_session_info
*v9ses
, struct p9_fid
*fid
,
518 struct super_block
*sb
)
520 if (v9fs_proto_dotl(v9ses
))
521 return v9fs_inode_dotl(v9ses
, fid
, sb
);
523 return v9fs_inode(v9ses
, fid
, sb
);
527 * v9fs_remove - helper function to remove files and directories
528 * @dir: directory inode that is being deleted
529 * @file: dentry that is being deleted
530 * @rmdir: removing a directory
534 static int v9fs_remove(struct inode
*dir
, struct dentry
*file
, int rmdir
)
537 struct inode
*file_inode
;
538 struct p9_fid
*v9fid
;
540 P9_DPRINTK(P9_DEBUG_VFS
, "inode: %p dentry: %p rmdir: %d\n", dir
, file
,
543 file_inode
= file
->d_inode
;
544 v9fid
= v9fs_fid_clone(file
);
546 return PTR_ERR(v9fid
);
548 retval
= p9_client_remove(v9fid
);
550 drop_nlink(file_inode
);
555 v9fs_open_created(struct inode
*inode
, struct file
*file
)
562 * v9fs_create - Create a file
563 * @v9ses: session information
564 * @dir: directory that dentry is being created in
565 * @dentry: dentry that is being created
566 * @extension: 9p2000.u extension string to support devices, etc.
567 * @perm: create permissions
571 static struct p9_fid
*
572 v9fs_create(struct v9fs_session_info
*v9ses
, struct inode
*dir
,
573 struct dentry
*dentry
, char *extension
, u32 perm
, u8 mode
)
577 struct p9_fid
*dfid
, *ofid
, *fid
;
580 P9_DPRINTK(P9_DEBUG_VFS
, "name %s\n", dentry
->d_name
.name
);
585 name
= (char *) dentry
->d_name
.name
;
586 dfid
= v9fs_fid_lookup(dentry
->d_parent
);
589 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
593 /* clone a fid to use for creation */
594 ofid
= p9_client_walk(dfid
, 0, NULL
, 1);
597 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
601 err
= p9_client_fcreate(ofid
, name
, perm
, mode
, extension
);
603 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_fcreate failed %d\n", err
);
607 /* now walk from the parent so we can get unopened fid */
608 fid
= p9_client_walk(dfid
, 1, &name
, 1);
611 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
616 /* instantiate inode and assign the unopened fid to the dentry */
617 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
619 err
= PTR_ERR(inode
);
620 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n", err
);
625 dentry
->d_op
= &v9fs_cached_dentry_operations
;
627 dentry
->d_op
= &v9fs_dentry_operations
;
629 d_instantiate(dentry
, inode
);
630 err
= v9fs_fid_add(dentry
, fid
);
638 p9_client_clunk(ofid
);
641 p9_client_clunk(fid
);
647 * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
648 * @dir: directory inode that is being created
649 * @dentry: dentry that is being deleted
650 * @mode: create permissions
651 * @nd: path information
656 v9fs_vfs_create_dotl(struct inode
*dir
, struct dentry
*dentry
, int mode
,
657 struct nameidata
*nd
)
663 struct v9fs_session_info
*v9ses
;
664 struct p9_fid
*fid
= NULL
;
665 struct p9_fid
*dfid
, *ofid
;
670 v9ses
= v9fs_inode2v9ses(dir
);
671 if (nd
&& nd
->flags
& LOOKUP_OPEN
)
672 flags
= nd
->intent
.open
.flags
- 1;
676 name
= (char *) dentry
->d_name
.name
;
677 P9_DPRINTK(P9_DEBUG_VFS
, "v9fs_vfs_create_dotl: name:%s flags:0x%x "
678 "mode:0x%x\n", name
, flags
, mode
);
680 dfid
= v9fs_fid_lookup(dentry
->d_parent
);
683 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
687 /* clone a fid to use for creation */
688 ofid
= p9_client_walk(dfid
, 0, NULL
, 1);
691 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
695 gid
= v9fs_get_fsgid_for_create(dir
);
696 err
= p9_client_create_dotl(ofid
, name
, flags
, mode
, gid
, &qid
);
698 P9_DPRINTK(P9_DEBUG_VFS
,
699 "p9_client_open_dotl failed in creat %d\n",
704 /* No need to populate the inode if we are not opening the file AND
705 * not in cached mode.
707 if (!v9ses
->cache
&& !(nd
&& nd
->flags
& LOOKUP_OPEN
)) {
708 /* Not in cached mode. No need to populate inode with stat */
709 dentry
->d_op
= &v9fs_dentry_operations
;
710 p9_client_clunk(ofid
);
711 d_instantiate(dentry
, NULL
);
715 /* Now walk from the parent so we can get an unopened fid. */
716 fid
= p9_client_walk(dfid
, 1, &name
, 1);
719 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
724 /* instantiate inode and assign the unopened fid to dentry */
725 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
727 err
= PTR_ERR(inode
);
728 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n", err
);
731 dentry
->d_op
= &v9fs_cached_dentry_operations
;
732 d_instantiate(dentry
, inode
);
733 err
= v9fs_fid_add(dentry
, fid
);
737 /* if we are opening a file, assign the open fid to the file */
738 if (nd
&& nd
->flags
& LOOKUP_OPEN
) {
739 filp
= lookup_instantiate_filp(nd
, dentry
, v9fs_open_created
);
741 p9_client_clunk(ofid
);
742 return PTR_ERR(filp
);
744 filp
->private_data
= ofid
;
746 p9_client_clunk(ofid
);
752 p9_client_clunk(ofid
);
754 p9_client_clunk(fid
);
759 * v9fs_vfs_create - VFS hook to create files
760 * @dir: directory inode that is being created
761 * @dentry: dentry that is being deleted
762 * @mode: create permissions
763 * @nd: path information
768 v9fs_vfs_create(struct inode
*dir
, struct dentry
*dentry
, int mode
,
769 struct nameidata
*nd
)
774 struct v9fs_session_info
*v9ses
;
780 v9ses
= v9fs_inode2v9ses(dir
);
781 perm
= unixmode2p9mode(v9ses
, mode
);
782 if (nd
&& nd
->flags
& LOOKUP_OPEN
)
783 flags
= nd
->intent
.open
.flags
- 1;
787 fid
= v9fs_create(v9ses
, dir
, dentry
, NULL
, perm
,
788 v9fs_uflags2omode(flags
,
789 v9fs_proto_dotu(v9ses
)));
796 /* if we are opening a file, assign the open fid to the file */
797 if (nd
&& nd
->flags
& LOOKUP_OPEN
) {
798 filp
= lookup_instantiate_filp(nd
, dentry
, v9fs_open_created
);
804 filp
->private_data
= fid
;
806 p9_client_clunk(fid
);
812 p9_client_clunk(fid
);
818 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
819 * @dir: inode that is being unlinked
820 * @dentry: dentry that is being unlinked
821 * @mode: mode for new directory
825 static int v9fs_vfs_mkdir(struct inode
*dir
, struct dentry
*dentry
, int mode
)
829 struct v9fs_session_info
*v9ses
;
832 P9_DPRINTK(P9_DEBUG_VFS
, "name %s\n", dentry
->d_name
.name
);
834 v9ses
= v9fs_inode2v9ses(dir
);
835 perm
= unixmode2p9mode(v9ses
, mode
| S_IFDIR
);
836 fid
= v9fs_create(v9ses
, dir
, dentry
, NULL
, perm
, P9_OREAD
);
843 p9_client_clunk(fid
);
850 * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
851 * @dir: inode that is being unlinked
852 * @dentry: dentry that is being unlinked
853 * @mode: mode for new directory
857 static int v9fs_vfs_mkdir_dotl(struct inode
*dir
, struct dentry
*dentry
,
861 struct v9fs_session_info
*v9ses
;
862 struct p9_fid
*fid
= NULL
, *dfid
= NULL
;
867 struct dentry
*dir_dentry
;
869 P9_DPRINTK(P9_DEBUG_VFS
, "name %s\n", dentry
->d_name
.name
);
871 v9ses
= v9fs_inode2v9ses(dir
);
874 dir_dentry
= v9fs_dentry_from_dir_inode(dir
);
875 dfid
= v9fs_fid_lookup(dir_dentry
);
878 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
883 gid
= v9fs_get_fsgid_for_create(dir
);
885 P9_DPRINTK(P9_DEBUG_VFS
, "v9fs_get_fsgid_for_create failed\n");
889 name
= (char *) dentry
->d_name
.name
;
890 err
= p9_client_mkdir_dotl(dfid
, name
, mode
, gid
, &qid
);
894 /* instantiate inode and assign the unopened fid to the dentry */
895 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
) {
896 fid
= p9_client_walk(dfid
, 1, &name
, 1);
899 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n",
905 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
907 err
= PTR_ERR(inode
);
908 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n",
912 dentry
->d_op
= &v9fs_cached_dentry_operations
;
913 d_instantiate(dentry
, inode
);
914 err
= v9fs_fid_add(dentry
, fid
);
921 p9_client_clunk(fid
);
926 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
927 * @dir: inode that is being walked from
928 * @dentry: dentry that is being walked to?
929 * @nameidata: path data
933 static struct dentry
*v9fs_vfs_lookup(struct inode
*dir
, struct dentry
*dentry
,
934 struct nameidata
*nameidata
)
936 struct super_block
*sb
;
937 struct v9fs_session_info
*v9ses
;
938 struct p9_fid
*dfid
, *fid
;
943 P9_DPRINTK(P9_DEBUG_VFS
, "dir: %p dentry: (%s) %p nameidata: %p\n",
944 dir
, dentry
->d_name
.name
, dentry
, nameidata
);
946 if (dentry
->d_name
.len
> NAME_MAX
)
947 return ERR_PTR(-ENAMETOOLONG
);
950 v9ses
= v9fs_inode2v9ses(dir
);
951 /* We can walk d_parent because we hold the dir->i_mutex */
952 dfid
= v9fs_fid_lookup(dentry
->d_parent
);
954 return ERR_CAST(dfid
);
956 name
= (char *) dentry
->d_name
.name
;
957 fid
= p9_client_walk(dfid
, 1, &name
, 1);
959 result
= PTR_ERR(fid
);
960 if (result
== -ENOENT
) {
965 return ERR_PTR(result
);
968 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
970 result
= PTR_ERR(inode
);
975 result
= v9fs_fid_add(dentry
, fid
);
981 dentry
->d_op
= &v9fs_cached_dentry_operations
;
983 dentry
->d_op
= &v9fs_dentry_operations
;
985 d_add(dentry
, inode
);
989 p9_client_clunk(fid
);
991 return ERR_PTR(result
);
995 * v9fs_vfs_unlink - VFS unlink hook to delete an inode
996 * @i: inode that is being unlinked
997 * @d: dentry that is being unlinked
1001 static int v9fs_vfs_unlink(struct inode
*i
, struct dentry
*d
)
1003 return v9fs_remove(i
, d
, 0);
1007 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
1008 * @i: inode that is being unlinked
1009 * @d: dentry that is being unlinked
1013 static int v9fs_vfs_rmdir(struct inode
*i
, struct dentry
*d
)
1015 return v9fs_remove(i
, d
, 1);
1019 * v9fs_vfs_rename - VFS hook to rename an inode
1020 * @old_dir: old dir inode
1021 * @old_dentry: old dentry
1022 * @new_dir: new dir inode
1023 * @new_dentry: new dentry
1028 v9fs_vfs_rename(struct inode
*old_dir
, struct dentry
*old_dentry
,
1029 struct inode
*new_dir
, struct dentry
*new_dentry
)
1031 struct inode
*old_inode
;
1032 struct v9fs_session_info
*v9ses
;
1033 struct p9_fid
*oldfid
;
1034 struct p9_fid
*olddirfid
;
1035 struct p9_fid
*newdirfid
;
1036 struct p9_wstat wstat
;
1039 P9_DPRINTK(P9_DEBUG_VFS
, "\n");
1041 old_inode
= old_dentry
->d_inode
;
1042 v9ses
= v9fs_inode2v9ses(old_inode
);
1043 oldfid
= v9fs_fid_lookup(old_dentry
);
1045 return PTR_ERR(oldfid
);
1047 olddirfid
= v9fs_fid_clone(old_dentry
->d_parent
);
1048 if (IS_ERR(olddirfid
)) {
1049 retval
= PTR_ERR(olddirfid
);
1053 newdirfid
= v9fs_fid_clone(new_dentry
->d_parent
);
1054 if (IS_ERR(newdirfid
)) {
1055 retval
= PTR_ERR(newdirfid
);
1059 down_write(&v9ses
->rename_sem
);
1060 if (v9fs_proto_dotl(v9ses
)) {
1061 retval
= p9_client_rename(oldfid
, newdirfid
,
1062 (char *) new_dentry
->d_name
.name
);
1063 if (retval
!= -ENOSYS
)
1066 if (old_dentry
->d_parent
!= new_dentry
->d_parent
) {
1068 * 9P .u can only handle file rename in the same directory
1071 P9_DPRINTK(P9_DEBUG_ERROR
,
1072 "old dir and new dir are different\n");
1076 v9fs_blank_wstat(&wstat
);
1077 wstat
.muid
= v9ses
->uname
;
1078 wstat
.name
= (char *) new_dentry
->d_name
.name
;
1079 retval
= p9_client_wstat(oldfid
, &wstat
);
1083 /* successful rename */
1084 d_move(old_dentry
, new_dentry
);
1085 up_write(&v9ses
->rename_sem
);
1086 p9_client_clunk(newdirfid
);
1089 p9_client_clunk(olddirfid
);
1096 * v9fs_vfs_getattr - retrieve file metadata
1097 * @mnt: mount information
1098 * @dentry: file to get attributes on
1099 * @stat: metadata structure to populate
1104 v9fs_vfs_getattr(struct vfsmount
*mnt
, struct dentry
*dentry
,
1108 struct v9fs_session_info
*v9ses
;
1110 struct p9_wstat
*st
;
1112 P9_DPRINTK(P9_DEBUG_VFS
, "dentry: %p\n", dentry
);
1114 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1115 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
)
1116 return simple_getattr(mnt
, dentry
, stat
);
1118 fid
= v9fs_fid_lookup(dentry
);
1120 return PTR_ERR(fid
);
1122 st
= p9_client_stat(fid
);
1126 v9fs_stat2inode(st
, dentry
->d_inode
, dentry
->d_inode
->i_sb
);
1127 generic_fillattr(dentry
->d_inode
, stat
);
1134 v9fs_vfs_getattr_dotl(struct vfsmount
*mnt
, struct dentry
*dentry
,
1138 struct v9fs_session_info
*v9ses
;
1140 struct p9_stat_dotl
*st
;
1142 P9_DPRINTK(P9_DEBUG_VFS
, "dentry: %p\n", dentry
);
1144 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1145 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
)
1146 return simple_getattr(mnt
, dentry
, stat
);
1148 fid
= v9fs_fid_lookup(dentry
);
1150 return PTR_ERR(fid
);
1152 /* Ask for all the fields in stat structure. Server will return
1153 * whatever it supports
1156 st
= p9_client_getattr_dotl(fid
, P9_STATS_ALL
);
1160 v9fs_stat2inode_dotl(st
, dentry
->d_inode
);
1161 generic_fillattr(dentry
->d_inode
, stat
);
1162 /* Change block size to what the server returned */
1163 stat
->blksize
= st
->st_blksize
;
1170 * v9fs_vfs_setattr - set file metadata
1171 * @dentry: file whose metadata to set
1172 * @iattr: metadata assignment structure
1176 static int v9fs_vfs_setattr(struct dentry
*dentry
, struct iattr
*iattr
)
1179 struct v9fs_session_info
*v9ses
;
1181 struct p9_wstat wstat
;
1183 P9_DPRINTK(P9_DEBUG_VFS
, "\n");
1185 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1186 fid
= v9fs_fid_lookup(dentry
);
1188 return PTR_ERR(fid
);
1190 v9fs_blank_wstat(&wstat
);
1191 if (iattr
->ia_valid
& ATTR_MODE
)
1192 wstat
.mode
= unixmode2p9mode(v9ses
, iattr
->ia_mode
);
1194 if (iattr
->ia_valid
& ATTR_MTIME
)
1195 wstat
.mtime
= iattr
->ia_mtime
.tv_sec
;
1197 if (iattr
->ia_valid
& ATTR_ATIME
)
1198 wstat
.atime
= iattr
->ia_atime
.tv_sec
;
1200 if (iattr
->ia_valid
& ATTR_SIZE
)
1201 wstat
.length
= iattr
->ia_size
;
1203 if (v9fs_proto_dotu(v9ses
)) {
1204 if (iattr
->ia_valid
& ATTR_UID
)
1205 wstat
.n_uid
= iattr
->ia_uid
;
1207 if (iattr
->ia_valid
& ATTR_GID
)
1208 wstat
.n_gid
= iattr
->ia_gid
;
1211 retval
= p9_client_wstat(fid
, &wstat
);
1213 retval
= inode_setattr(dentry
->d_inode
, iattr
);
1219 * v9fs_vfs_setattr_dotl - set file metadata
1220 * @dentry: file whose metadata to set
1221 * @iattr: metadata assignment structure
1225 static int v9fs_vfs_setattr_dotl(struct dentry
*dentry
, struct iattr
*iattr
)
1228 struct v9fs_session_info
*v9ses
;
1230 struct p9_iattr_dotl p9attr
;
1232 P9_DPRINTK(P9_DEBUG_VFS
, "\n");
1234 retval
= inode_change_ok(dentry
->d_inode
, iattr
);
1238 p9attr
.valid
= iattr
->ia_valid
;
1239 p9attr
.mode
= iattr
->ia_mode
;
1240 p9attr
.uid
= iattr
->ia_uid
;
1241 p9attr
.gid
= iattr
->ia_gid
;
1242 p9attr
.size
= iattr
->ia_size
;
1243 p9attr
.atime_sec
= iattr
->ia_atime
.tv_sec
;
1244 p9attr
.atime_nsec
= iattr
->ia_atime
.tv_nsec
;
1245 p9attr
.mtime_sec
= iattr
->ia_mtime
.tv_sec
;
1246 p9attr
.mtime_nsec
= iattr
->ia_mtime
.tv_nsec
;
1249 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1250 fid
= v9fs_fid_lookup(dentry
);
1252 return PTR_ERR(fid
);
1254 retval
= p9_client_setattr(fid
, &p9attr
);
1256 retval
= inode_setattr(dentry
->d_inode
, iattr
);
1262 * v9fs_stat2inode - populate an inode structure with mistat info
1263 * @stat: Plan 9 metadata (mistat) structure
1264 * @inode: inode to populate
1265 * @sb: superblock of filesystem
1270 v9fs_stat2inode(struct p9_wstat
*stat
, struct inode
*inode
,
1271 struct super_block
*sb
)
1275 unsigned int i_nlink
;
1276 struct v9fs_session_info
*v9ses
= sb
->s_fs_info
;
1280 inode
->i_atime
.tv_sec
= stat
->atime
;
1281 inode
->i_mtime
.tv_sec
= stat
->mtime
;
1282 inode
->i_ctime
.tv_sec
= stat
->mtime
;
1284 inode
->i_uid
= v9ses
->dfltuid
;
1285 inode
->i_gid
= v9ses
->dfltgid
;
1287 if (v9fs_proto_dotu(v9ses
)) {
1288 inode
->i_uid
= stat
->n_uid
;
1289 inode
->i_gid
= stat
->n_gid
;
1291 if ((S_ISREG(inode
->i_mode
)) || (S_ISDIR(inode
->i_mode
))) {
1292 if (v9fs_proto_dotu(v9ses
) && (stat
->extension
[0] != '\0')) {
1294 * Hadlink support got added later to
1295 * to the .u extension. So there can be
1296 * server out there that doesn't support
1297 * this even with .u extension. So check
1298 * for non NULL stat->extension
1300 strncpy(ext
, stat
->extension
, sizeof(ext
));
1301 /* HARDLINKCOUNT %u */
1302 sscanf(ext
, "%13s %u", tag_name
, &i_nlink
);
1303 if (!strncmp(tag_name
, "HARDLINKCOUNT", 13))
1304 inode
->i_nlink
= i_nlink
;
1307 inode
->i_mode
= p9mode2unixmode(v9ses
, stat
->mode
);
1308 if ((S_ISBLK(inode
->i_mode
)) || (S_ISCHR(inode
->i_mode
))) {
1313 strncpy(ext
, stat
->extension
, sizeof(ext
));
1314 sscanf(ext
, "%c %u %u", &type
, &major
, &minor
);
1317 inode
->i_mode
&= ~S_IFBLK
;
1318 inode
->i_mode
|= S_IFCHR
;
1323 P9_DPRINTK(P9_DEBUG_ERROR
,
1324 "Unknown special type %c %s\n", type
,
1327 inode
->i_rdev
= MKDEV(major
, minor
);
1328 init_special_inode(inode
, inode
->i_mode
, inode
->i_rdev
);
1332 i_size_write(inode
, stat
->length
);
1334 /* not real number of blocks, but 512 byte ones ... */
1335 inode
->i_blocks
= (i_size_read(inode
) + 512 - 1) >> 9;
1339 * v9fs_stat2inode_dotl - populate an inode structure with stat info
1340 * @stat: stat structure
1341 * @inode: inode to populate
1342 * @sb: superblock of filesystem
1347 v9fs_stat2inode_dotl(struct p9_stat_dotl
*stat
, struct inode
*inode
)
1350 if ((stat
->st_result_mask
& P9_STATS_BASIC
) == P9_STATS_BASIC
) {
1351 inode
->i_atime
.tv_sec
= stat
->st_atime_sec
;
1352 inode
->i_atime
.tv_nsec
= stat
->st_atime_nsec
;
1353 inode
->i_mtime
.tv_sec
= stat
->st_mtime_sec
;
1354 inode
->i_mtime
.tv_nsec
= stat
->st_mtime_nsec
;
1355 inode
->i_ctime
.tv_sec
= stat
->st_ctime_sec
;
1356 inode
->i_ctime
.tv_nsec
= stat
->st_ctime_nsec
;
1357 inode
->i_uid
= stat
->st_uid
;
1358 inode
->i_gid
= stat
->st_gid
;
1359 inode
->i_nlink
= stat
->st_nlink
;
1360 inode
->i_mode
= stat
->st_mode
;
1361 inode
->i_rdev
= new_decode_dev(stat
->st_rdev
);
1363 if ((S_ISBLK(inode
->i_mode
)) || (S_ISCHR(inode
->i_mode
)))
1364 init_special_inode(inode
, inode
->i_mode
, inode
->i_rdev
);
1366 i_size_write(inode
, stat
->st_size
);
1367 inode
->i_blocks
= stat
->st_blocks
;
1369 if (stat
->st_result_mask
& P9_STATS_ATIME
) {
1370 inode
->i_atime
.tv_sec
= stat
->st_atime_sec
;
1371 inode
->i_atime
.tv_nsec
= stat
->st_atime_nsec
;
1373 if (stat
->st_result_mask
& P9_STATS_MTIME
) {
1374 inode
->i_mtime
.tv_sec
= stat
->st_mtime_sec
;
1375 inode
->i_mtime
.tv_nsec
= stat
->st_mtime_nsec
;
1377 if (stat
->st_result_mask
& P9_STATS_CTIME
) {
1378 inode
->i_ctime
.tv_sec
= stat
->st_ctime_sec
;
1379 inode
->i_ctime
.tv_nsec
= stat
->st_ctime_nsec
;
1381 if (stat
->st_result_mask
& P9_STATS_UID
)
1382 inode
->i_uid
= stat
->st_uid
;
1383 if (stat
->st_result_mask
& P9_STATS_GID
)
1384 inode
->i_gid
= stat
->st_gid
;
1385 if (stat
->st_result_mask
& P9_STATS_NLINK
)
1386 inode
->i_nlink
= stat
->st_nlink
;
1387 if (stat
->st_result_mask
& P9_STATS_MODE
) {
1388 inode
->i_mode
= stat
->st_mode
;
1389 if ((S_ISBLK(inode
->i_mode
)) ||
1390 (S_ISCHR(inode
->i_mode
)))
1391 init_special_inode(inode
, inode
->i_mode
,
1394 if (stat
->st_result_mask
& P9_STATS_RDEV
)
1395 inode
->i_rdev
= new_decode_dev(stat
->st_rdev
);
1396 if (stat
->st_result_mask
& P9_STATS_SIZE
)
1397 i_size_write(inode
, stat
->st_size
);
1398 if (stat
->st_result_mask
& P9_STATS_BLOCKS
)
1399 inode
->i_blocks
= stat
->st_blocks
;
1401 if (stat
->st_result_mask
& P9_STATS_GEN
)
1402 inode
->i_generation
= stat
->st_gen
;
1404 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
1405 * because the inode structure does not have fields for them.
1410 * v9fs_qid2ino - convert qid into inode number
1413 * BUG: potential for inode number collisions?
1416 ino_t
v9fs_qid2ino(struct p9_qid
*qid
)
1418 u64 path
= qid
->path
+ 2;
1421 if (sizeof(ino_t
) == sizeof(path
))
1422 memcpy(&i
, &path
, sizeof(ino_t
));
1424 i
= (ino_t
) (path
^ (path
>> 32));
1430 * v9fs_readlink - read a symlink's location (internal version)
1431 * @dentry: dentry for symlink
1432 * @buffer: buffer to load symlink location into
1433 * @buflen: length of buffer
1437 static int v9fs_readlink(struct dentry
*dentry
, char *buffer
, int buflen
)
1441 struct v9fs_session_info
*v9ses
;
1443 struct p9_wstat
*st
;
1445 P9_DPRINTK(P9_DEBUG_VFS
, " %s\n", dentry
->d_name
.name
);
1447 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1448 fid
= v9fs_fid_lookup(dentry
);
1450 return PTR_ERR(fid
);
1452 if (!v9fs_proto_dotu(v9ses
) && !v9fs_proto_dotl(v9ses
))
1455 st
= p9_client_stat(fid
);
1459 if (!(st
->mode
& P9_DMSYMLINK
)) {
1464 /* copy extension buffer into buffer */
1465 strncpy(buffer
, st
->extension
, buflen
);
1467 P9_DPRINTK(P9_DEBUG_VFS
,
1468 "%s -> %s (%s)\n", dentry
->d_name
.name
, st
->extension
, buffer
);
1470 retval
= strnlen(buffer
, buflen
);
1477 * v9fs_vfs_follow_link - follow a symlink path
1478 * @dentry: dentry for symlink
1483 static void *v9fs_vfs_follow_link(struct dentry
*dentry
, struct nameidata
*nd
)
1486 char *link
= __getname();
1488 P9_DPRINTK(P9_DEBUG_VFS
, "%s n", dentry
->d_name
.name
);
1491 link
= ERR_PTR(-ENOMEM
);
1493 len
= v9fs_readlink(dentry
, link
, PATH_MAX
);
1497 link
= ERR_PTR(len
);
1499 link
[min(len
, PATH_MAX
-1)] = 0;
1501 nd_set_link(nd
, link
);
1507 * v9fs_vfs_put_link - release a symlink path
1508 * @dentry: dentry for symlink
1515 v9fs_vfs_put_link(struct dentry
*dentry
, struct nameidata
*nd
, void *p
)
1517 char *s
= nd_get_link(nd
);
1519 P9_DPRINTK(P9_DEBUG_VFS
, " %s %s\n", dentry
->d_name
.name
,
1520 IS_ERR(s
) ? "<error>" : s
);
1526 * v9fs_vfs_mkspecial - create a special file
1527 * @dir: inode to create special file in
1528 * @dentry: dentry to create
1529 * @mode: mode to create special file
1530 * @extension: 9p2000.u format extension string representing special file
1534 static int v9fs_vfs_mkspecial(struct inode
*dir
, struct dentry
*dentry
,
1535 int mode
, const char *extension
)
1538 struct v9fs_session_info
*v9ses
;
1541 v9ses
= v9fs_inode2v9ses(dir
);
1542 if (!v9fs_proto_dotu(v9ses
)) {
1543 P9_DPRINTK(P9_DEBUG_ERROR
, "not extended\n");
1547 perm
= unixmode2p9mode(v9ses
, mode
);
1548 fid
= v9fs_create(v9ses
, dir
, dentry
, (char *) extension
, perm
,
1551 return PTR_ERR(fid
);
1553 p9_client_clunk(fid
);
1558 * v9fs_vfs_symlink_dotl - helper function to create symlinks
1559 * @dir: directory inode containing symlink
1560 * @dentry: dentry for symlink
1561 * @symname: symlink data
1563 * See Also: 9P2000.L RFC for more information
1568 v9fs_vfs_symlink_dotl(struct inode
*dir
, struct dentry
*dentry
,
1569 const char *symname
)
1571 struct v9fs_session_info
*v9ses
;
1572 struct p9_fid
*dfid
;
1573 struct p9_fid
*fid
= NULL
;
1574 struct inode
*inode
;
1580 name
= (char *) dentry
->d_name
.name
;
1581 P9_DPRINTK(P9_DEBUG_VFS
, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n",
1582 dir
->i_ino
, name
, symname
);
1583 v9ses
= v9fs_inode2v9ses(dir
);
1585 dfid
= v9fs_fid_lookup(dentry
->d_parent
);
1587 err
= PTR_ERR(dfid
);
1588 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
1592 gid
= v9fs_get_fsgid_for_create(dir
);
1595 P9_DPRINTK(P9_DEBUG_VFS
, "v9fs_get_egid failed %d\n", gid
);
1599 /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
1600 err
= p9_client_symlink(dfid
, name
, (char *)symname
, gid
, &qid
);
1603 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_symlink failed %d\n", err
);
1608 /* Now walk from the parent so we can get an unopened fid. */
1609 fid
= p9_client_walk(dfid
, 1, &name
, 1);
1612 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n",
1618 /* instantiate inode and assign the unopened fid to dentry */
1619 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
1620 if (IS_ERR(inode
)) {
1621 err
= PTR_ERR(inode
);
1622 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n",
1626 dentry
->d_op
= &v9fs_cached_dentry_operations
;
1627 d_instantiate(dentry
, inode
);
1628 err
= v9fs_fid_add(dentry
, fid
);
1633 /* Not in cached mode. No need to populate inode with stat */
1634 inode
= v9fs_get_inode(dir
->i_sb
, S_IFLNK
);
1635 if (IS_ERR(inode
)) {
1636 err
= PTR_ERR(inode
);
1639 dentry
->d_op
= &v9fs_dentry_operations
;
1640 d_instantiate(dentry
, inode
);
1645 p9_client_clunk(fid
);
1651 * v9fs_vfs_symlink - helper function to create symlinks
1652 * @dir: directory inode containing symlink
1653 * @dentry: dentry for symlink
1654 * @symname: symlink data
1656 * See Also: 9P2000.u RFC for more information
1661 v9fs_vfs_symlink(struct inode
*dir
, struct dentry
*dentry
, const char *symname
)
1663 P9_DPRINTK(P9_DEBUG_VFS
, " %lu,%s,%s\n", dir
->i_ino
,
1664 dentry
->d_name
.name
, symname
);
1666 return v9fs_vfs_mkspecial(dir
, dentry
, S_IFLNK
, symname
);
1670 * v9fs_vfs_link - create a hardlink
1671 * @old_dentry: dentry for file to link to
1672 * @dir: inode destination for new link
1673 * @dentry: dentry for link
1678 v9fs_vfs_link(struct dentry
*old_dentry
, struct inode
*dir
,
1679 struct dentry
*dentry
)
1682 struct p9_fid
*oldfid
;
1685 P9_DPRINTK(P9_DEBUG_VFS
,
1686 " %lu,%s,%s\n", dir
->i_ino
, dentry
->d_name
.name
,
1687 old_dentry
->d_name
.name
);
1689 oldfid
= v9fs_fid_clone(old_dentry
);
1691 return PTR_ERR(oldfid
);
1694 if (unlikely(!name
)) {
1699 sprintf(name
, "%d\n", oldfid
->fid
);
1700 retval
= v9fs_vfs_mkspecial(dir
, dentry
, P9_DMLINK
, name
);
1704 p9_client_clunk(oldfid
);
1709 * v9fs_vfs_link_dotl - create a hardlink for dotl
1710 * @old_dentry: dentry for file to link to
1711 * @dir: inode destination for new link
1712 * @dentry: dentry for link
1717 v9fs_vfs_link_dotl(struct dentry
*old_dentry
, struct inode
*dir
,
1718 struct dentry
*dentry
)
1721 struct p9_fid
*dfid
, *oldfid
;
1723 struct v9fs_session_info
*v9ses
;
1724 struct dentry
*dir_dentry
;
1726 P9_DPRINTK(P9_DEBUG_VFS
, "dir ino: %lu, old_name: %s, new_name: %s\n",
1727 dir
->i_ino
, old_dentry
->d_name
.name
,
1728 dentry
->d_name
.name
);
1730 v9ses
= v9fs_inode2v9ses(dir
);
1731 dir_dentry
= v9fs_dentry_from_dir_inode(dir
);
1732 dfid
= v9fs_fid_lookup(dir_dentry
);
1734 return PTR_ERR(dfid
);
1736 oldfid
= v9fs_fid_lookup(old_dentry
);
1738 return PTR_ERR(oldfid
);
1740 name
= (char *) dentry
->d_name
.name
;
1742 err
= p9_client_link(dfid
, oldfid
, (char *)dentry
->d_name
.name
);
1745 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_link failed %d\n", err
);
1749 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
) {
1750 /* Get the latest stat info from server. */
1752 struct p9_stat_dotl
*st
;
1754 fid
= v9fs_fid_lookup(old_dentry
);
1756 return PTR_ERR(fid
);
1758 st
= p9_client_getattr_dotl(fid
, P9_STATS_BASIC
);
1762 v9fs_stat2inode_dotl(st
, old_dentry
->d_inode
);
1766 /* Caching disabled. No need to get upto date stat info.
1767 * This dentry will be released immediately. So, just i_count++
1769 atomic_inc(&old_dentry
->d_inode
->i_count
);
1772 dentry
->d_op
= old_dentry
->d_op
;
1773 d_instantiate(dentry
, old_dentry
->d_inode
);
1779 * v9fs_vfs_mknod - create a special file
1780 * @dir: inode destination for new link
1781 * @dentry: dentry for file
1782 * @mode: mode for creation
1783 * @rdev: device associated with special file
1788 v9fs_vfs_mknod(struct inode
*dir
, struct dentry
*dentry
, int mode
, dev_t rdev
)
1793 P9_DPRINTK(P9_DEBUG_VFS
,
1794 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir
->i_ino
,
1795 dentry
->d_name
.name
, mode
, MAJOR(rdev
), MINOR(rdev
));
1797 if (!new_valid_dev(rdev
))
1803 /* build extension */
1805 sprintf(name
, "b %u %u", MAJOR(rdev
), MINOR(rdev
));
1806 else if (S_ISCHR(mode
))
1807 sprintf(name
, "c %u %u", MAJOR(rdev
), MINOR(rdev
));
1808 else if (S_ISFIFO(mode
))
1810 else if (S_ISSOCK(mode
))
1817 retval
= v9fs_vfs_mkspecial(dir
, dentry
, mode
, name
);
1824 * v9fs_vfs_mknod_dotl - create a special file
1825 * @dir: inode destination for new link
1826 * @dentry: dentry for file
1827 * @mode: mode for creation
1828 * @rdev: device associated with special file
1832 v9fs_vfs_mknod_dotl(struct inode
*dir
, struct dentry
*dentry
, int mode
,
1837 struct v9fs_session_info
*v9ses
;
1838 struct p9_fid
*fid
= NULL
, *dfid
= NULL
;
1839 struct inode
*inode
;
1842 struct dentry
*dir_dentry
;
1844 P9_DPRINTK(P9_DEBUG_VFS
,
1845 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir
->i_ino
,
1846 dentry
->d_name
.name
, mode
, MAJOR(rdev
), MINOR(rdev
));
1848 if (!new_valid_dev(rdev
))
1851 v9ses
= v9fs_inode2v9ses(dir
);
1852 dir_dentry
= v9fs_dentry_from_dir_inode(dir
);
1853 dfid
= v9fs_fid_lookup(dir_dentry
);
1855 err
= PTR_ERR(dfid
);
1856 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
1861 gid
= v9fs_get_fsgid_for_create(dir
);
1863 P9_DPRINTK(P9_DEBUG_VFS
, "v9fs_get_fsgid_for_create failed\n");
1867 name
= (char *) dentry
->d_name
.name
;
1869 err
= p9_client_mknod_dotl(dfid
, name
, mode
, rdev
, gid
, &qid
);
1873 /* instantiate inode and assign the unopened fid to the dentry */
1874 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
) {
1875 fid
= p9_client_walk(dfid
, 1, &name
, 1);
1878 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n",
1884 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
1885 if (IS_ERR(inode
)) {
1886 err
= PTR_ERR(inode
);
1887 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n",
1891 dentry
->d_op
= &v9fs_cached_dentry_operations
;
1892 d_instantiate(dentry
, inode
);
1893 err
= v9fs_fid_add(dentry
, fid
);
1899 * Not in cached mode. No need to populate inode with stat.
1900 * socket syscall returns a fd, so we need instantiate
1902 inode
= v9fs_get_inode(dir
->i_sb
, mode
);
1903 if (IS_ERR(inode
)) {
1904 err
= PTR_ERR(inode
);
1907 dentry
->d_op
= &v9fs_dentry_operations
;
1908 d_instantiate(dentry
, inode
);
1913 p9_client_clunk(fid
);
1917 static const struct inode_operations v9fs_dir_inode_operations_dotu
= {
1918 .create
= v9fs_vfs_create
,
1919 .lookup
= v9fs_vfs_lookup
,
1920 .symlink
= v9fs_vfs_symlink
,
1921 .link
= v9fs_vfs_link
,
1922 .unlink
= v9fs_vfs_unlink
,
1923 .mkdir
= v9fs_vfs_mkdir
,
1924 .rmdir
= v9fs_vfs_rmdir
,
1925 .mknod
= v9fs_vfs_mknod_dotl
,
1926 .rename
= v9fs_vfs_rename
,
1927 .getattr
= v9fs_vfs_getattr
,
1928 .setattr
= v9fs_vfs_setattr
,
1931 static const struct inode_operations v9fs_dir_inode_operations_dotl
= {
1932 .create
= v9fs_vfs_create_dotl
,
1933 .lookup
= v9fs_vfs_lookup
,
1934 .link
= v9fs_vfs_link_dotl
,
1935 .symlink
= v9fs_vfs_symlink_dotl
,
1936 .unlink
= v9fs_vfs_unlink
,
1937 .mkdir
= v9fs_vfs_mkdir_dotl
,
1938 .rmdir
= v9fs_vfs_rmdir
,
1939 .mknod
= v9fs_vfs_mknod_dotl
,
1940 .rename
= v9fs_vfs_rename
,
1941 .getattr
= v9fs_vfs_getattr_dotl
,
1942 .setattr
= v9fs_vfs_setattr_dotl
,
1943 .setxattr
= generic_setxattr
,
1944 .getxattr
= generic_getxattr
,
1945 .removexattr
= generic_removexattr
,
1946 .listxattr
= v9fs_listxattr
,
1950 static const struct inode_operations v9fs_dir_inode_operations
= {
1951 .create
= v9fs_vfs_create
,
1952 .lookup
= v9fs_vfs_lookup
,
1953 .unlink
= v9fs_vfs_unlink
,
1954 .mkdir
= v9fs_vfs_mkdir
,
1955 .rmdir
= v9fs_vfs_rmdir
,
1956 .mknod
= v9fs_vfs_mknod
,
1957 .rename
= v9fs_vfs_rename
,
1958 .getattr
= v9fs_vfs_getattr
,
1959 .setattr
= v9fs_vfs_setattr
,
1962 static const struct inode_operations v9fs_file_inode_operations
= {
1963 .getattr
= v9fs_vfs_getattr
,
1964 .setattr
= v9fs_vfs_setattr
,
1967 static const struct inode_operations v9fs_file_inode_operations_dotl
= {
1968 .getattr
= v9fs_vfs_getattr_dotl
,
1969 .setattr
= v9fs_vfs_setattr_dotl
,
1970 .setxattr
= generic_setxattr
,
1971 .getxattr
= generic_getxattr
,
1972 .removexattr
= generic_removexattr
,
1973 .listxattr
= v9fs_listxattr
,
1976 static const struct inode_operations v9fs_symlink_inode_operations
= {
1977 .readlink
= generic_readlink
,
1978 .follow_link
= v9fs_vfs_follow_link
,
1979 .put_link
= v9fs_vfs_put_link
,
1980 .getattr
= v9fs_vfs_getattr
,
1981 .setattr
= v9fs_vfs_setattr
,
1984 static const struct inode_operations v9fs_symlink_inode_operations_dotl
= {
1985 .readlink
= generic_readlink
,
1986 .follow_link
= v9fs_vfs_follow_link
,
1987 .put_link
= v9fs_vfs_put_link
,
1988 .getattr
= v9fs_vfs_getattr_dotl
,
1989 .setattr
= v9fs_vfs_setattr_dotl
,
1990 .setxattr
= generic_setxattr
,
1991 .getxattr
= generic_getxattr
,
1992 .removexattr
= generic_removexattr
,
1993 .listxattr
= v9fs_listxattr
,