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_evict_inode(struct inode
*inode
)
435 truncate_inode_pages(inode
->i_mapping
, 0);
436 end_writeback(inode
);
437 filemap_fdatawrite(inode
->i_mapping
);
439 #ifdef CONFIG_9P_FSCACHE
440 v9fs_cache_inode_put_cookie(inode
);
444 static struct inode
*
445 v9fs_inode(struct v9fs_session_info
*v9ses
, struct p9_fid
*fid
,
446 struct super_block
*sb
)
449 struct inode
*ret
= NULL
;
452 st
= p9_client_stat(fid
);
456 umode
= p9mode2unixmode(v9ses
, st
->mode
);
457 ret
= v9fs_get_inode(sb
, umode
);
463 v9fs_stat2inode(st
, ret
, sb
);
464 ret
->i_ino
= v9fs_qid2ino(&st
->qid
);
466 #ifdef CONFIG_9P_FSCACHE
467 v9fs_vcookie_set_qid(ret
, &st
->qid
);
468 v9fs_cache_inode_get_cookie(ret
);
479 static struct inode
*
480 v9fs_inode_dotl(struct v9fs_session_info
*v9ses
, struct p9_fid
*fid
,
481 struct super_block
*sb
)
483 struct inode
*ret
= NULL
;
485 struct p9_stat_dotl
*st
;
487 st
= p9_client_getattr_dotl(fid
, P9_STATS_BASIC
);
491 ret
= v9fs_get_inode(sb
, st
->st_mode
);
497 v9fs_stat2inode_dotl(st
, ret
);
498 ret
->i_ino
= v9fs_qid2ino(&st
->qid
);
499 #ifdef CONFIG_9P_FSCACHE
500 v9fs_vcookie_set_qid(ret
, &st
->qid
);
501 v9fs_cache_inode_get_cookie(ret
);
511 * v9fs_inode_from_fid - Helper routine to populate an inode by
512 * issuing a attribute request
513 * @v9ses: session information
514 * @fid: fid to issue attribute request for
515 * @sb: superblock on which to create inode
518 static inline struct inode
*
519 v9fs_inode_from_fid(struct v9fs_session_info
*v9ses
, struct p9_fid
*fid
,
520 struct super_block
*sb
)
522 if (v9fs_proto_dotl(v9ses
))
523 return v9fs_inode_dotl(v9ses
, fid
, sb
);
525 return v9fs_inode(v9ses
, fid
, sb
);
529 * v9fs_remove - helper function to remove files and directories
530 * @dir: directory inode that is being deleted
531 * @file: dentry that is being deleted
532 * @rmdir: removing a directory
536 static int v9fs_remove(struct inode
*dir
, struct dentry
*file
, int rmdir
)
539 struct inode
*file_inode
;
540 struct p9_fid
*v9fid
;
542 P9_DPRINTK(P9_DEBUG_VFS
, "inode: %p dentry: %p rmdir: %d\n", dir
, file
,
545 file_inode
= file
->d_inode
;
546 v9fid
= v9fs_fid_clone(file
);
548 return PTR_ERR(v9fid
);
550 retval
= p9_client_remove(v9fid
);
552 drop_nlink(file_inode
);
557 v9fs_open_created(struct inode
*inode
, struct file
*file
)
564 * v9fs_create - Create a file
565 * @v9ses: session information
566 * @dir: directory that dentry is being created in
567 * @dentry: dentry that is being created
568 * @extension: 9p2000.u extension string to support devices, etc.
569 * @perm: create permissions
573 static struct p9_fid
*
574 v9fs_create(struct v9fs_session_info
*v9ses
, struct inode
*dir
,
575 struct dentry
*dentry
, char *extension
, u32 perm
, u8 mode
)
579 struct p9_fid
*dfid
, *ofid
, *fid
;
582 P9_DPRINTK(P9_DEBUG_VFS
, "name %s\n", dentry
->d_name
.name
);
587 name
= (char *) dentry
->d_name
.name
;
588 dfid
= v9fs_fid_lookup(dentry
->d_parent
);
591 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
595 /* clone a fid to use for creation */
596 ofid
= p9_client_walk(dfid
, 0, NULL
, 1);
599 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
603 err
= p9_client_fcreate(ofid
, name
, perm
, mode
, extension
);
605 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_fcreate failed %d\n", err
);
609 /* now walk from the parent so we can get unopened fid */
610 fid
= p9_client_walk(dfid
, 1, &name
, 1);
613 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
618 /* instantiate inode and assign the unopened fid to the dentry */
619 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
621 err
= PTR_ERR(inode
);
622 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n", err
);
627 dentry
->d_op
= &v9fs_cached_dentry_operations
;
629 dentry
->d_op
= &v9fs_dentry_operations
;
631 d_instantiate(dentry
, inode
);
632 err
= v9fs_fid_add(dentry
, fid
);
640 p9_client_clunk(ofid
);
643 p9_client_clunk(fid
);
649 * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
650 * @dir: directory inode that is being created
651 * @dentry: dentry that is being deleted
652 * @mode: create permissions
653 * @nd: path information
658 v9fs_vfs_create_dotl(struct inode
*dir
, struct dentry
*dentry
, int mode
,
659 struct nameidata
*nd
)
665 struct v9fs_session_info
*v9ses
;
666 struct p9_fid
*fid
= NULL
;
667 struct p9_fid
*dfid
, *ofid
;
672 v9ses
= v9fs_inode2v9ses(dir
);
673 if (nd
&& nd
->flags
& LOOKUP_OPEN
)
674 flags
= nd
->intent
.open
.flags
- 1;
678 name
= (char *) dentry
->d_name
.name
;
679 P9_DPRINTK(P9_DEBUG_VFS
, "v9fs_vfs_create_dotl: name:%s flags:0x%x "
680 "mode:0x%x\n", name
, flags
, mode
);
682 dfid
= v9fs_fid_lookup(dentry
->d_parent
);
685 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
689 /* clone a fid to use for creation */
690 ofid
= p9_client_walk(dfid
, 0, NULL
, 1);
693 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
697 gid
= v9fs_get_fsgid_for_create(dir
);
698 err
= p9_client_create_dotl(ofid
, name
, flags
, mode
, gid
, &qid
);
700 P9_DPRINTK(P9_DEBUG_VFS
,
701 "p9_client_open_dotl failed in creat %d\n",
706 /* No need to populate the inode if we are not opening the file AND
707 * not in cached mode.
709 if (!v9ses
->cache
&& !(nd
&& nd
->flags
& LOOKUP_OPEN
)) {
710 /* Not in cached mode. No need to populate inode with stat */
711 dentry
->d_op
= &v9fs_dentry_operations
;
712 p9_client_clunk(ofid
);
713 d_instantiate(dentry
, NULL
);
717 /* Now walk from the parent so we can get an unopened fid. */
718 fid
= p9_client_walk(dfid
, 1, &name
, 1);
721 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
726 /* instantiate inode and assign the unopened fid to dentry */
727 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
729 err
= PTR_ERR(inode
);
730 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n", err
);
734 dentry
->d_op
= &v9fs_cached_dentry_operations
;
736 dentry
->d_op
= &v9fs_dentry_operations
;
737 d_instantiate(dentry
, inode
);
738 err
= v9fs_fid_add(dentry
, fid
);
742 /* if we are opening a file, assign the open fid to the file */
743 if (nd
&& nd
->flags
& LOOKUP_OPEN
) {
744 filp
= lookup_instantiate_filp(nd
, dentry
, v9fs_open_created
);
746 p9_client_clunk(ofid
);
747 return PTR_ERR(filp
);
749 filp
->private_data
= ofid
;
751 p9_client_clunk(ofid
);
757 p9_client_clunk(ofid
);
759 p9_client_clunk(fid
);
764 * v9fs_vfs_create - VFS hook to create files
765 * @dir: directory inode that is being created
766 * @dentry: dentry that is being deleted
767 * @mode: create permissions
768 * @nd: path information
773 v9fs_vfs_create(struct inode
*dir
, struct dentry
*dentry
, int mode
,
774 struct nameidata
*nd
)
779 struct v9fs_session_info
*v9ses
;
785 v9ses
= v9fs_inode2v9ses(dir
);
786 perm
= unixmode2p9mode(v9ses
, mode
);
787 if (nd
&& nd
->flags
& LOOKUP_OPEN
)
788 flags
= nd
->intent
.open
.flags
- 1;
792 fid
= v9fs_create(v9ses
, dir
, dentry
, NULL
, perm
,
793 v9fs_uflags2omode(flags
,
794 v9fs_proto_dotu(v9ses
)));
801 /* if we are opening a file, assign the open fid to the file */
802 if (nd
&& nd
->flags
& LOOKUP_OPEN
) {
803 filp
= lookup_instantiate_filp(nd
, dentry
, v9fs_open_created
);
809 filp
->private_data
= fid
;
811 p9_client_clunk(fid
);
817 p9_client_clunk(fid
);
823 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
824 * @dir: inode that is being unlinked
825 * @dentry: dentry that is being unlinked
826 * @mode: mode for new directory
830 static int v9fs_vfs_mkdir(struct inode
*dir
, struct dentry
*dentry
, int mode
)
834 struct v9fs_session_info
*v9ses
;
837 P9_DPRINTK(P9_DEBUG_VFS
, "name %s\n", dentry
->d_name
.name
);
839 v9ses
= v9fs_inode2v9ses(dir
);
840 perm
= unixmode2p9mode(v9ses
, mode
| S_IFDIR
);
841 fid
= v9fs_create(v9ses
, dir
, dentry
, NULL
, perm
, P9_OREAD
);
848 p9_client_clunk(fid
);
855 * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
856 * @dir: inode that is being unlinked
857 * @dentry: dentry that is being unlinked
858 * @mode: mode for new directory
862 static int v9fs_vfs_mkdir_dotl(struct inode
*dir
, struct dentry
*dentry
,
866 struct v9fs_session_info
*v9ses
;
867 struct p9_fid
*fid
= NULL
, *dfid
= NULL
;
872 struct dentry
*dir_dentry
;
874 P9_DPRINTK(P9_DEBUG_VFS
, "name %s\n", dentry
->d_name
.name
);
876 v9ses
= v9fs_inode2v9ses(dir
);
879 dir_dentry
= v9fs_dentry_from_dir_inode(dir
);
880 dfid
= v9fs_fid_lookup(dir_dentry
);
883 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
888 gid
= v9fs_get_fsgid_for_create(dir
);
890 name
= (char *) dentry
->d_name
.name
;
891 err
= p9_client_mkdir_dotl(dfid
, name
, mode
, gid
, &qid
);
895 /* instantiate inode and assign the unopened fid to the dentry */
896 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
) {
897 fid
= p9_client_walk(dfid
, 1, &name
, 1);
900 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n",
906 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
908 err
= PTR_ERR(inode
);
909 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n",
913 dentry
->d_op
= &v9fs_cached_dentry_operations
;
914 d_instantiate(dentry
, inode
);
915 err
= v9fs_fid_add(dentry
, fid
);
922 p9_client_clunk(fid
);
927 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
928 * @dir: inode that is being walked from
929 * @dentry: dentry that is being walked to?
930 * @nameidata: path data
934 static struct dentry
*v9fs_vfs_lookup(struct inode
*dir
, struct dentry
*dentry
,
935 struct nameidata
*nameidata
)
937 struct super_block
*sb
;
938 struct v9fs_session_info
*v9ses
;
939 struct p9_fid
*dfid
, *fid
;
944 P9_DPRINTK(P9_DEBUG_VFS
, "dir: %p dentry: (%s) %p nameidata: %p\n",
945 dir
, dentry
->d_name
.name
, dentry
, nameidata
);
947 if (dentry
->d_name
.len
> NAME_MAX
)
948 return ERR_PTR(-ENAMETOOLONG
);
951 v9ses
= v9fs_inode2v9ses(dir
);
952 /* We can walk d_parent because we hold the dir->i_mutex */
953 dfid
= v9fs_fid_lookup(dentry
->d_parent
);
955 return ERR_CAST(dfid
);
957 name
= (char *) dentry
->d_name
.name
;
958 fid
= p9_client_walk(dfid
, 1, &name
, 1);
960 result
= PTR_ERR(fid
);
961 if (result
== -ENOENT
) {
966 return ERR_PTR(result
);
969 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
971 result
= PTR_ERR(inode
);
976 result
= v9fs_fid_add(dentry
, fid
);
982 dentry
->d_op
= &v9fs_cached_dentry_operations
;
984 dentry
->d_op
= &v9fs_dentry_operations
;
986 d_add(dentry
, inode
);
990 p9_client_clunk(fid
);
992 return ERR_PTR(result
);
996 * v9fs_vfs_unlink - VFS unlink hook to delete an inode
997 * @i: inode that is being unlinked
998 * @d: dentry that is being unlinked
1002 static int v9fs_vfs_unlink(struct inode
*i
, struct dentry
*d
)
1004 return v9fs_remove(i
, d
, 0);
1008 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
1009 * @i: inode that is being unlinked
1010 * @d: dentry that is being unlinked
1014 static int v9fs_vfs_rmdir(struct inode
*i
, struct dentry
*d
)
1016 return v9fs_remove(i
, d
, 1);
1020 * v9fs_vfs_rename - VFS hook to rename an inode
1021 * @old_dir: old dir inode
1022 * @old_dentry: old dentry
1023 * @new_dir: new dir inode
1024 * @new_dentry: new dentry
1029 v9fs_vfs_rename(struct inode
*old_dir
, struct dentry
*old_dentry
,
1030 struct inode
*new_dir
, struct dentry
*new_dentry
)
1032 struct inode
*old_inode
;
1033 struct v9fs_session_info
*v9ses
;
1034 struct p9_fid
*oldfid
;
1035 struct p9_fid
*olddirfid
;
1036 struct p9_fid
*newdirfid
;
1037 struct p9_wstat wstat
;
1040 P9_DPRINTK(P9_DEBUG_VFS
, "\n");
1042 old_inode
= old_dentry
->d_inode
;
1043 v9ses
= v9fs_inode2v9ses(old_inode
);
1044 oldfid
= v9fs_fid_lookup(old_dentry
);
1046 return PTR_ERR(oldfid
);
1048 olddirfid
= v9fs_fid_clone(old_dentry
->d_parent
);
1049 if (IS_ERR(olddirfid
)) {
1050 retval
= PTR_ERR(olddirfid
);
1054 newdirfid
= v9fs_fid_clone(new_dentry
->d_parent
);
1055 if (IS_ERR(newdirfid
)) {
1056 retval
= PTR_ERR(newdirfid
);
1060 down_write(&v9ses
->rename_sem
);
1061 if (v9fs_proto_dotl(v9ses
)) {
1062 retval
= p9_client_rename(oldfid
, newdirfid
,
1063 (char *) new_dentry
->d_name
.name
);
1064 if (retval
!= -ENOSYS
)
1067 if (old_dentry
->d_parent
!= new_dentry
->d_parent
) {
1069 * 9P .u can only handle file rename in the same directory
1072 P9_DPRINTK(P9_DEBUG_ERROR
,
1073 "old dir and new dir are different\n");
1077 v9fs_blank_wstat(&wstat
);
1078 wstat
.muid
= v9ses
->uname
;
1079 wstat
.name
= (char *) new_dentry
->d_name
.name
;
1080 retval
= p9_client_wstat(oldfid
, &wstat
);
1084 /* successful rename */
1085 d_move(old_dentry
, new_dentry
);
1086 up_write(&v9ses
->rename_sem
);
1087 p9_client_clunk(newdirfid
);
1090 p9_client_clunk(olddirfid
);
1097 * v9fs_vfs_getattr - retrieve file metadata
1098 * @mnt: mount information
1099 * @dentry: file to get attributes on
1100 * @stat: metadata structure to populate
1105 v9fs_vfs_getattr(struct vfsmount
*mnt
, struct dentry
*dentry
,
1109 struct v9fs_session_info
*v9ses
;
1111 struct p9_wstat
*st
;
1113 P9_DPRINTK(P9_DEBUG_VFS
, "dentry: %p\n", dentry
);
1115 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1116 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
)
1117 return simple_getattr(mnt
, dentry
, stat
);
1119 fid
= v9fs_fid_lookup(dentry
);
1121 return PTR_ERR(fid
);
1123 st
= p9_client_stat(fid
);
1127 v9fs_stat2inode(st
, dentry
->d_inode
, dentry
->d_inode
->i_sb
);
1128 generic_fillattr(dentry
->d_inode
, stat
);
1136 v9fs_vfs_getattr_dotl(struct vfsmount
*mnt
, struct dentry
*dentry
,
1140 struct v9fs_session_info
*v9ses
;
1142 struct p9_stat_dotl
*st
;
1144 P9_DPRINTK(P9_DEBUG_VFS
, "dentry: %p\n", dentry
);
1146 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1147 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
)
1148 return simple_getattr(mnt
, dentry
, stat
);
1150 fid
= v9fs_fid_lookup(dentry
);
1152 return PTR_ERR(fid
);
1154 /* Ask for all the fields in stat structure. Server will return
1155 * whatever it supports
1158 st
= p9_client_getattr_dotl(fid
, P9_STATS_ALL
);
1162 v9fs_stat2inode_dotl(st
, dentry
->d_inode
);
1163 generic_fillattr(dentry
->d_inode
, stat
);
1164 /* Change block size to what the server returned */
1165 stat
->blksize
= st
->st_blksize
;
1172 * v9fs_vfs_setattr - set file metadata
1173 * @dentry: file whose metadata to set
1174 * @iattr: metadata assignment structure
1178 static int v9fs_vfs_setattr(struct dentry
*dentry
, struct iattr
*iattr
)
1181 struct v9fs_session_info
*v9ses
;
1183 struct p9_wstat wstat
;
1185 P9_DPRINTK(P9_DEBUG_VFS
, "\n");
1187 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1188 fid
= v9fs_fid_lookup(dentry
);
1190 return PTR_ERR(fid
);
1192 v9fs_blank_wstat(&wstat
);
1193 if (iattr
->ia_valid
& ATTR_MODE
)
1194 wstat
.mode
= unixmode2p9mode(v9ses
, iattr
->ia_mode
);
1196 if (iattr
->ia_valid
& ATTR_MTIME
)
1197 wstat
.mtime
= iattr
->ia_mtime
.tv_sec
;
1199 if (iattr
->ia_valid
& ATTR_ATIME
)
1200 wstat
.atime
= iattr
->ia_atime
.tv_sec
;
1202 if (iattr
->ia_valid
& ATTR_SIZE
)
1203 wstat
.length
= iattr
->ia_size
;
1205 if (v9fs_proto_dotu(v9ses
)) {
1206 if (iattr
->ia_valid
& ATTR_UID
)
1207 wstat
.n_uid
= iattr
->ia_uid
;
1209 if (iattr
->ia_valid
& ATTR_GID
)
1210 wstat
.n_gid
= iattr
->ia_gid
;
1213 retval
= p9_client_wstat(fid
, &wstat
);
1217 if ((iattr
->ia_valid
& ATTR_SIZE
) &&
1218 iattr
->ia_size
!= i_size_read(dentry
->d_inode
)) {
1219 retval
= vmtruncate(dentry
->d_inode
, iattr
->ia_size
);
1224 setattr_copy(dentry
->d_inode
, iattr
);
1225 mark_inode_dirty(dentry
->d_inode
);
1230 * v9fs_vfs_setattr_dotl - set file metadata
1231 * @dentry: file whose metadata to set
1232 * @iattr: metadata assignment structure
1236 static int v9fs_vfs_setattr_dotl(struct dentry
*dentry
, struct iattr
*iattr
)
1239 struct v9fs_session_info
*v9ses
;
1241 struct p9_iattr_dotl p9attr
;
1243 P9_DPRINTK(P9_DEBUG_VFS
, "\n");
1245 retval
= inode_change_ok(dentry
->d_inode
, iattr
);
1249 p9attr
.valid
= iattr
->ia_valid
;
1250 p9attr
.mode
= iattr
->ia_mode
;
1251 p9attr
.uid
= iattr
->ia_uid
;
1252 p9attr
.gid
= iattr
->ia_gid
;
1253 p9attr
.size
= iattr
->ia_size
;
1254 p9attr
.atime_sec
= iattr
->ia_atime
.tv_sec
;
1255 p9attr
.atime_nsec
= iattr
->ia_atime
.tv_nsec
;
1256 p9attr
.mtime_sec
= iattr
->ia_mtime
.tv_sec
;
1257 p9attr
.mtime_nsec
= iattr
->ia_mtime
.tv_nsec
;
1260 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1261 fid
= v9fs_fid_lookup(dentry
);
1263 return PTR_ERR(fid
);
1265 retval
= p9_client_setattr(fid
, &p9attr
);
1269 if ((iattr
->ia_valid
& ATTR_SIZE
) &&
1270 iattr
->ia_size
!= i_size_read(dentry
->d_inode
)) {
1271 retval
= vmtruncate(dentry
->d_inode
, iattr
->ia_size
);
1276 setattr_copy(dentry
->d_inode
, iattr
);
1277 mark_inode_dirty(dentry
->d_inode
);
1282 * v9fs_stat2inode - populate an inode structure with mistat info
1283 * @stat: Plan 9 metadata (mistat) structure
1284 * @inode: inode to populate
1285 * @sb: superblock of filesystem
1290 v9fs_stat2inode(struct p9_wstat
*stat
, struct inode
*inode
,
1291 struct super_block
*sb
)
1295 unsigned int i_nlink
;
1296 struct v9fs_session_info
*v9ses
= sb
->s_fs_info
;
1300 inode
->i_atime
.tv_sec
= stat
->atime
;
1301 inode
->i_mtime
.tv_sec
= stat
->mtime
;
1302 inode
->i_ctime
.tv_sec
= stat
->mtime
;
1304 inode
->i_uid
= v9ses
->dfltuid
;
1305 inode
->i_gid
= v9ses
->dfltgid
;
1307 if (v9fs_proto_dotu(v9ses
)) {
1308 inode
->i_uid
= stat
->n_uid
;
1309 inode
->i_gid
= stat
->n_gid
;
1311 if ((S_ISREG(inode
->i_mode
)) || (S_ISDIR(inode
->i_mode
))) {
1312 if (v9fs_proto_dotu(v9ses
) && (stat
->extension
[0] != '\0')) {
1314 * Hadlink support got added later to
1315 * to the .u extension. So there can be
1316 * server out there that doesn't support
1317 * this even with .u extension. So check
1318 * for non NULL stat->extension
1320 strncpy(ext
, stat
->extension
, sizeof(ext
));
1321 /* HARDLINKCOUNT %u */
1322 sscanf(ext
, "%13s %u", tag_name
, &i_nlink
);
1323 if (!strncmp(tag_name
, "HARDLINKCOUNT", 13))
1324 inode
->i_nlink
= i_nlink
;
1327 inode
->i_mode
= p9mode2unixmode(v9ses
, stat
->mode
);
1328 if ((S_ISBLK(inode
->i_mode
)) || (S_ISCHR(inode
->i_mode
))) {
1333 strncpy(ext
, stat
->extension
, sizeof(ext
));
1334 sscanf(ext
, "%c %u %u", &type
, &major
, &minor
);
1337 inode
->i_mode
&= ~S_IFBLK
;
1338 inode
->i_mode
|= S_IFCHR
;
1343 P9_DPRINTK(P9_DEBUG_ERROR
,
1344 "Unknown special type %c %s\n", type
,
1347 inode
->i_rdev
= MKDEV(major
, minor
);
1348 init_special_inode(inode
, inode
->i_mode
, inode
->i_rdev
);
1352 i_size_write(inode
, stat
->length
);
1354 /* not real number of blocks, but 512 byte ones ... */
1355 inode
->i_blocks
= (i_size_read(inode
) + 512 - 1) >> 9;
1359 * v9fs_stat2inode_dotl - populate an inode structure with stat info
1360 * @stat: stat structure
1361 * @inode: inode to populate
1362 * @sb: superblock of filesystem
1367 v9fs_stat2inode_dotl(struct p9_stat_dotl
*stat
, struct inode
*inode
)
1370 if ((stat
->st_result_mask
& P9_STATS_BASIC
) == P9_STATS_BASIC
) {
1371 inode
->i_atime
.tv_sec
= stat
->st_atime_sec
;
1372 inode
->i_atime
.tv_nsec
= stat
->st_atime_nsec
;
1373 inode
->i_mtime
.tv_sec
= stat
->st_mtime_sec
;
1374 inode
->i_mtime
.tv_nsec
= stat
->st_mtime_nsec
;
1375 inode
->i_ctime
.tv_sec
= stat
->st_ctime_sec
;
1376 inode
->i_ctime
.tv_nsec
= stat
->st_ctime_nsec
;
1377 inode
->i_uid
= stat
->st_uid
;
1378 inode
->i_gid
= stat
->st_gid
;
1379 inode
->i_nlink
= stat
->st_nlink
;
1380 inode
->i_mode
= stat
->st_mode
;
1381 inode
->i_rdev
= new_decode_dev(stat
->st_rdev
);
1383 if ((S_ISBLK(inode
->i_mode
)) || (S_ISCHR(inode
->i_mode
)))
1384 init_special_inode(inode
, inode
->i_mode
, inode
->i_rdev
);
1386 i_size_write(inode
, stat
->st_size
);
1387 inode
->i_blocks
= stat
->st_blocks
;
1389 if (stat
->st_result_mask
& P9_STATS_ATIME
) {
1390 inode
->i_atime
.tv_sec
= stat
->st_atime_sec
;
1391 inode
->i_atime
.tv_nsec
= stat
->st_atime_nsec
;
1393 if (stat
->st_result_mask
& P9_STATS_MTIME
) {
1394 inode
->i_mtime
.tv_sec
= stat
->st_mtime_sec
;
1395 inode
->i_mtime
.tv_nsec
= stat
->st_mtime_nsec
;
1397 if (stat
->st_result_mask
& P9_STATS_CTIME
) {
1398 inode
->i_ctime
.tv_sec
= stat
->st_ctime_sec
;
1399 inode
->i_ctime
.tv_nsec
= stat
->st_ctime_nsec
;
1401 if (stat
->st_result_mask
& P9_STATS_UID
)
1402 inode
->i_uid
= stat
->st_uid
;
1403 if (stat
->st_result_mask
& P9_STATS_GID
)
1404 inode
->i_gid
= stat
->st_gid
;
1405 if (stat
->st_result_mask
& P9_STATS_NLINK
)
1406 inode
->i_nlink
= stat
->st_nlink
;
1407 if (stat
->st_result_mask
& P9_STATS_MODE
) {
1408 inode
->i_mode
= stat
->st_mode
;
1409 if ((S_ISBLK(inode
->i_mode
)) ||
1410 (S_ISCHR(inode
->i_mode
)))
1411 init_special_inode(inode
, inode
->i_mode
,
1414 if (stat
->st_result_mask
& P9_STATS_RDEV
)
1415 inode
->i_rdev
= new_decode_dev(stat
->st_rdev
);
1416 if (stat
->st_result_mask
& P9_STATS_SIZE
)
1417 i_size_write(inode
, stat
->st_size
);
1418 if (stat
->st_result_mask
& P9_STATS_BLOCKS
)
1419 inode
->i_blocks
= stat
->st_blocks
;
1421 if (stat
->st_result_mask
& P9_STATS_GEN
)
1422 inode
->i_generation
= stat
->st_gen
;
1424 /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
1425 * because the inode structure does not have fields for them.
1430 * v9fs_qid2ino - convert qid into inode number
1433 * BUG: potential for inode number collisions?
1436 ino_t
v9fs_qid2ino(struct p9_qid
*qid
)
1438 u64 path
= qid
->path
+ 2;
1441 if (sizeof(ino_t
) == sizeof(path
))
1442 memcpy(&i
, &path
, sizeof(ino_t
));
1444 i
= (ino_t
) (path
^ (path
>> 32));
1450 * v9fs_readlink - read a symlink's location (internal version)
1451 * @dentry: dentry for symlink
1452 * @buffer: buffer to load symlink location into
1453 * @buflen: length of buffer
1457 static int v9fs_readlink(struct dentry
*dentry
, char *buffer
, int buflen
)
1461 struct v9fs_session_info
*v9ses
;
1463 struct p9_wstat
*st
;
1465 P9_DPRINTK(P9_DEBUG_VFS
, " %s\n", dentry
->d_name
.name
);
1467 v9ses
= v9fs_inode2v9ses(dentry
->d_inode
);
1468 fid
= v9fs_fid_lookup(dentry
);
1470 return PTR_ERR(fid
);
1472 if (!v9fs_proto_dotu(v9ses
) && !v9fs_proto_dotl(v9ses
))
1475 st
= p9_client_stat(fid
);
1479 if (!(st
->mode
& P9_DMSYMLINK
)) {
1484 /* copy extension buffer into buffer */
1485 strncpy(buffer
, st
->extension
, buflen
);
1487 P9_DPRINTK(P9_DEBUG_VFS
,
1488 "%s -> %s (%s)\n", dentry
->d_name
.name
, st
->extension
, buffer
);
1490 retval
= strnlen(buffer
, buflen
);
1498 * v9fs_vfs_follow_link - follow a symlink path
1499 * @dentry: dentry for symlink
1504 static void *v9fs_vfs_follow_link(struct dentry
*dentry
, struct nameidata
*nd
)
1507 char *link
= __getname();
1509 P9_DPRINTK(P9_DEBUG_VFS
, "%s n", dentry
->d_name
.name
);
1512 link
= ERR_PTR(-ENOMEM
);
1514 len
= v9fs_readlink(dentry
, link
, PATH_MAX
);
1518 link
= ERR_PTR(len
);
1520 link
[min(len
, PATH_MAX
-1)] = 0;
1522 nd_set_link(nd
, link
);
1528 * v9fs_vfs_put_link - release a symlink path
1529 * @dentry: dentry for symlink
1536 v9fs_vfs_put_link(struct dentry
*dentry
, struct nameidata
*nd
, void *p
)
1538 char *s
= nd_get_link(nd
);
1540 P9_DPRINTK(P9_DEBUG_VFS
, " %s %s\n", dentry
->d_name
.name
,
1541 IS_ERR(s
) ? "<error>" : s
);
1547 * v9fs_vfs_mkspecial - create a special file
1548 * @dir: inode to create special file in
1549 * @dentry: dentry to create
1550 * @mode: mode to create special file
1551 * @extension: 9p2000.u format extension string representing special file
1555 static int v9fs_vfs_mkspecial(struct inode
*dir
, struct dentry
*dentry
,
1556 int mode
, const char *extension
)
1559 struct v9fs_session_info
*v9ses
;
1562 v9ses
= v9fs_inode2v9ses(dir
);
1563 if (!v9fs_proto_dotu(v9ses
)) {
1564 P9_DPRINTK(P9_DEBUG_ERROR
, "not extended\n");
1568 perm
= unixmode2p9mode(v9ses
, mode
);
1569 fid
= v9fs_create(v9ses
, dir
, dentry
, (char *) extension
, perm
,
1572 return PTR_ERR(fid
);
1574 p9_client_clunk(fid
);
1579 * v9fs_vfs_symlink_dotl - helper function to create symlinks
1580 * @dir: directory inode containing symlink
1581 * @dentry: dentry for symlink
1582 * @symname: symlink data
1584 * See Also: 9P2000.L RFC for more information
1589 v9fs_vfs_symlink_dotl(struct inode
*dir
, struct dentry
*dentry
,
1590 const char *symname
)
1592 struct v9fs_session_info
*v9ses
;
1593 struct p9_fid
*dfid
;
1594 struct p9_fid
*fid
= NULL
;
1595 struct inode
*inode
;
1601 name
= (char *) dentry
->d_name
.name
;
1602 P9_DPRINTK(P9_DEBUG_VFS
, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n",
1603 dir
->i_ino
, name
, symname
);
1604 v9ses
= v9fs_inode2v9ses(dir
);
1606 dfid
= v9fs_fid_lookup(dentry
->d_parent
);
1608 err
= PTR_ERR(dfid
);
1609 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
1613 gid
= v9fs_get_fsgid_for_create(dir
);
1615 /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
1616 err
= p9_client_symlink(dfid
, name
, (char *)symname
, gid
, &qid
);
1619 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_symlink failed %d\n", err
);
1624 /* Now walk from the parent so we can get an unopened fid. */
1625 fid
= p9_client_walk(dfid
, 1, &name
, 1);
1628 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n",
1634 /* instantiate inode and assign the unopened fid to dentry */
1635 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
1636 if (IS_ERR(inode
)) {
1637 err
= PTR_ERR(inode
);
1638 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n",
1642 dentry
->d_op
= &v9fs_cached_dentry_operations
;
1643 d_instantiate(dentry
, inode
);
1644 err
= v9fs_fid_add(dentry
, fid
);
1649 /* Not in cached mode. No need to populate inode with stat */
1650 inode
= v9fs_get_inode(dir
->i_sb
, S_IFLNK
);
1651 if (IS_ERR(inode
)) {
1652 err
= PTR_ERR(inode
);
1655 dentry
->d_op
= &v9fs_dentry_operations
;
1656 d_instantiate(dentry
, inode
);
1661 p9_client_clunk(fid
);
1667 * v9fs_vfs_symlink - helper function to create symlinks
1668 * @dir: directory inode containing symlink
1669 * @dentry: dentry for symlink
1670 * @symname: symlink data
1672 * See Also: 9P2000.u RFC for more information
1677 v9fs_vfs_symlink(struct inode
*dir
, struct dentry
*dentry
, const char *symname
)
1679 P9_DPRINTK(P9_DEBUG_VFS
, " %lu,%s,%s\n", dir
->i_ino
,
1680 dentry
->d_name
.name
, symname
);
1682 return v9fs_vfs_mkspecial(dir
, dentry
, S_IFLNK
, symname
);
1686 * v9fs_vfs_link - create a hardlink
1687 * @old_dentry: dentry for file to link to
1688 * @dir: inode destination for new link
1689 * @dentry: dentry for link
1694 v9fs_vfs_link(struct dentry
*old_dentry
, struct inode
*dir
,
1695 struct dentry
*dentry
)
1698 struct p9_fid
*oldfid
;
1701 P9_DPRINTK(P9_DEBUG_VFS
,
1702 " %lu,%s,%s\n", dir
->i_ino
, dentry
->d_name
.name
,
1703 old_dentry
->d_name
.name
);
1705 oldfid
= v9fs_fid_clone(old_dentry
);
1707 return PTR_ERR(oldfid
);
1710 if (unlikely(!name
)) {
1715 sprintf(name
, "%d\n", oldfid
->fid
);
1716 retval
= v9fs_vfs_mkspecial(dir
, dentry
, P9_DMLINK
, name
);
1720 p9_client_clunk(oldfid
);
1725 * v9fs_vfs_link_dotl - create a hardlink for dotl
1726 * @old_dentry: dentry for file to link to
1727 * @dir: inode destination for new link
1728 * @dentry: dentry for link
1733 v9fs_vfs_link_dotl(struct dentry
*old_dentry
, struct inode
*dir
,
1734 struct dentry
*dentry
)
1737 struct p9_fid
*dfid
, *oldfid
;
1739 struct v9fs_session_info
*v9ses
;
1740 struct dentry
*dir_dentry
;
1742 P9_DPRINTK(P9_DEBUG_VFS
, "dir ino: %lu, old_name: %s, new_name: %s\n",
1743 dir
->i_ino
, old_dentry
->d_name
.name
,
1744 dentry
->d_name
.name
);
1746 v9ses
= v9fs_inode2v9ses(dir
);
1747 dir_dentry
= v9fs_dentry_from_dir_inode(dir
);
1748 dfid
= v9fs_fid_lookup(dir_dentry
);
1750 return PTR_ERR(dfid
);
1752 oldfid
= v9fs_fid_lookup(old_dentry
);
1754 return PTR_ERR(oldfid
);
1756 name
= (char *) dentry
->d_name
.name
;
1758 err
= p9_client_link(dfid
, oldfid
, (char *)dentry
->d_name
.name
);
1761 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_link failed %d\n", err
);
1765 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
) {
1766 /* Get the latest stat info from server. */
1768 struct p9_stat_dotl
*st
;
1770 fid
= v9fs_fid_lookup(old_dentry
);
1772 return PTR_ERR(fid
);
1774 st
= p9_client_getattr_dotl(fid
, P9_STATS_BASIC
);
1778 v9fs_stat2inode_dotl(st
, old_dentry
->d_inode
);
1782 /* Caching disabled. No need to get upto date stat info.
1783 * This dentry will be released immediately. So, just hold the
1786 ihold(old_dentry
->d_inode
);
1789 dentry
->d_op
= old_dentry
->d_op
;
1790 d_instantiate(dentry
, old_dentry
->d_inode
);
1796 * v9fs_vfs_mknod - create a special file
1797 * @dir: inode destination for new link
1798 * @dentry: dentry for file
1799 * @mode: mode for creation
1800 * @rdev: device associated with special file
1805 v9fs_vfs_mknod(struct inode
*dir
, struct dentry
*dentry
, int mode
, dev_t rdev
)
1810 P9_DPRINTK(P9_DEBUG_VFS
,
1811 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir
->i_ino
,
1812 dentry
->d_name
.name
, mode
, MAJOR(rdev
), MINOR(rdev
));
1814 if (!new_valid_dev(rdev
))
1820 /* build extension */
1822 sprintf(name
, "b %u %u", MAJOR(rdev
), MINOR(rdev
));
1823 else if (S_ISCHR(mode
))
1824 sprintf(name
, "c %u %u", MAJOR(rdev
), MINOR(rdev
));
1825 else if (S_ISFIFO(mode
))
1827 else if (S_ISSOCK(mode
))
1834 retval
= v9fs_vfs_mkspecial(dir
, dentry
, mode
, name
);
1841 * v9fs_vfs_mknod_dotl - create a special file
1842 * @dir: inode destination for new link
1843 * @dentry: dentry for file
1844 * @mode: mode for creation
1845 * @rdev: device associated with special file
1849 v9fs_vfs_mknod_dotl(struct inode
*dir
, struct dentry
*dentry
, int mode
,
1854 struct v9fs_session_info
*v9ses
;
1855 struct p9_fid
*fid
= NULL
, *dfid
= NULL
;
1856 struct inode
*inode
;
1859 struct dentry
*dir_dentry
;
1861 P9_DPRINTK(P9_DEBUG_VFS
,
1862 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir
->i_ino
,
1863 dentry
->d_name
.name
, mode
, MAJOR(rdev
), MINOR(rdev
));
1865 if (!new_valid_dev(rdev
))
1868 v9ses
= v9fs_inode2v9ses(dir
);
1869 dir_dentry
= v9fs_dentry_from_dir_inode(dir
);
1870 dfid
= v9fs_fid_lookup(dir_dentry
);
1872 err
= PTR_ERR(dfid
);
1873 P9_DPRINTK(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
1878 gid
= v9fs_get_fsgid_for_create(dir
);
1880 name
= (char *) dentry
->d_name
.name
;
1882 err
= p9_client_mknod_dotl(dfid
, name
, mode
, rdev
, gid
, &qid
);
1886 /* instantiate inode and assign the unopened fid to the dentry */
1887 if (v9ses
->cache
== CACHE_LOOSE
|| v9ses
->cache
== CACHE_FSCACHE
) {
1888 fid
= p9_client_walk(dfid
, 1, &name
, 1);
1891 P9_DPRINTK(P9_DEBUG_VFS
, "p9_client_walk failed %d\n",
1897 inode
= v9fs_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
1898 if (IS_ERR(inode
)) {
1899 err
= PTR_ERR(inode
);
1900 P9_DPRINTK(P9_DEBUG_VFS
, "inode creation failed %d\n",
1904 dentry
->d_op
= &v9fs_cached_dentry_operations
;
1905 d_instantiate(dentry
, inode
);
1906 err
= v9fs_fid_add(dentry
, fid
);
1912 * Not in cached mode. No need to populate inode with stat.
1913 * socket syscall returns a fd, so we need instantiate
1915 inode
= v9fs_get_inode(dir
->i_sb
, mode
);
1916 if (IS_ERR(inode
)) {
1917 err
= PTR_ERR(inode
);
1920 dentry
->d_op
= &v9fs_dentry_operations
;
1921 d_instantiate(dentry
, inode
);
1926 p9_client_clunk(fid
);
1930 static const struct inode_operations v9fs_dir_inode_operations_dotu
= {
1931 .create
= v9fs_vfs_create
,
1932 .lookup
= v9fs_vfs_lookup
,
1933 .symlink
= v9fs_vfs_symlink
,
1934 .link
= v9fs_vfs_link
,
1935 .unlink
= v9fs_vfs_unlink
,
1936 .mkdir
= v9fs_vfs_mkdir
,
1937 .rmdir
= v9fs_vfs_rmdir
,
1938 .mknod
= v9fs_vfs_mknod
,
1939 .rename
= v9fs_vfs_rename
,
1940 .getattr
= v9fs_vfs_getattr
,
1941 .setattr
= v9fs_vfs_setattr
,
1944 static const struct inode_operations v9fs_dir_inode_operations_dotl
= {
1945 .create
= v9fs_vfs_create_dotl
,
1946 .lookup
= v9fs_vfs_lookup
,
1947 .link
= v9fs_vfs_link_dotl
,
1948 .symlink
= v9fs_vfs_symlink_dotl
,
1949 .unlink
= v9fs_vfs_unlink
,
1950 .mkdir
= v9fs_vfs_mkdir_dotl
,
1951 .rmdir
= v9fs_vfs_rmdir
,
1952 .mknod
= v9fs_vfs_mknod_dotl
,
1953 .rename
= v9fs_vfs_rename
,
1954 .getattr
= v9fs_vfs_getattr_dotl
,
1955 .setattr
= v9fs_vfs_setattr_dotl
,
1956 .setxattr
= generic_setxattr
,
1957 .getxattr
= generic_getxattr
,
1958 .removexattr
= generic_removexattr
,
1959 .listxattr
= v9fs_listxattr
,
1963 static const struct inode_operations v9fs_dir_inode_operations
= {
1964 .create
= v9fs_vfs_create
,
1965 .lookup
= v9fs_vfs_lookup
,
1966 .unlink
= v9fs_vfs_unlink
,
1967 .mkdir
= v9fs_vfs_mkdir
,
1968 .rmdir
= v9fs_vfs_rmdir
,
1969 .mknod
= v9fs_vfs_mknod
,
1970 .rename
= v9fs_vfs_rename
,
1971 .getattr
= v9fs_vfs_getattr
,
1972 .setattr
= v9fs_vfs_setattr
,
1975 static const struct inode_operations v9fs_file_inode_operations
= {
1976 .getattr
= v9fs_vfs_getattr
,
1977 .setattr
= v9fs_vfs_setattr
,
1980 static const struct inode_operations v9fs_file_inode_operations_dotl
= {
1981 .getattr
= v9fs_vfs_getattr_dotl
,
1982 .setattr
= v9fs_vfs_setattr_dotl
,
1983 .setxattr
= generic_setxattr
,
1984 .getxattr
= generic_getxattr
,
1985 .removexattr
= generic_removexattr
,
1986 .listxattr
= v9fs_listxattr
,
1989 static const struct inode_operations v9fs_symlink_inode_operations
= {
1990 .readlink
= generic_readlink
,
1991 .follow_link
= v9fs_vfs_follow_link
,
1992 .put_link
= v9fs_vfs_put_link
,
1993 .getattr
= v9fs_vfs_getattr
,
1994 .setattr
= v9fs_vfs_setattr
,
1997 static const struct inode_operations v9fs_symlink_inode_operations_dotl
= {
1998 .readlink
= generic_readlink
,
1999 .follow_link
= v9fs_vfs_follow_link
,
2000 .put_link
= v9fs_vfs_put_link
,
2001 .getattr
= v9fs_vfs_getattr_dotl
,
2002 .setattr
= v9fs_vfs_setattr_dotl
,
2003 .setxattr
= generic_setxattr
,
2004 .getxattr
= generic_getxattr
,
2005 .removexattr
= generic_removexattr
,
2006 .listxattr
= v9fs_listxattr
,