1 // SPDX-License-Identifier: GPL-2.0-only
3 * This file contains vfs inode ops for the 9P2000 protocol.
5 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
6 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11 #include <linux/module.h>
12 #include <linux/errno.h>
14 #include <linux/file.h>
15 #include <linux/pagemap.h>
16 #include <linux/stat.h>
17 #include <linux/string.h>
18 #include <linux/namei.h>
19 #include <linux/sched.h>
20 #include <linux/slab.h>
21 #include <linux/xattr.h>
22 #include <linux/posix_acl.h>
23 #include <net/9p/9p.h>
24 #include <net/9p/client.h>
33 static const struct inode_operations v9fs_dir_inode_operations
;
34 static const struct inode_operations v9fs_dir_inode_operations_dotu
;
35 static const struct inode_operations v9fs_file_inode_operations
;
36 static const struct inode_operations v9fs_symlink_inode_operations
;
39 * unixmode2p9mode - convert unix mode bits to plan 9
40 * @v9ses: v9fs session information
41 * @mode: mode to convert
45 static u32
unixmode2p9mode(struct v9fs_session_info
*v9ses
, umode_t mode
)
52 if (v9fs_proto_dotu(v9ses
)) {
53 if (v9ses
->nodev
== 0) {
57 res
|= P9_DMNAMEDPIPE
;
64 if ((mode
& S_ISUID
) == S_ISUID
)
66 if ((mode
& S_ISGID
) == S_ISGID
)
68 if ((mode
& S_ISVTX
) == S_ISVTX
)
75 * p9mode2perm- convert plan9 mode bits to unix permission bits
76 * @v9ses: v9fs session information
77 * @stat: p9_wstat from which mode need to be derived
80 static int p9mode2perm(struct v9fs_session_info
*v9ses
,
81 struct p9_wstat
*stat
)
84 int mode
= stat
->mode
;
86 res
= mode
& 0777; /* S_IRWXUGO */
87 if (v9fs_proto_dotu(v9ses
)) {
88 if ((mode
& P9_DMSETUID
) == P9_DMSETUID
)
91 if ((mode
& P9_DMSETGID
) == P9_DMSETGID
)
94 if ((mode
& P9_DMSETVTX
) == P9_DMSETVTX
)
101 * p9mode2unixmode- convert plan9 mode bits to unix mode bits
102 * @v9ses: v9fs session information
103 * @stat: p9_wstat from which mode need to be derived
104 * @rdev: major number, minor number in case of device files.
107 static umode_t
p9mode2unixmode(struct v9fs_session_info
*v9ses
,
108 struct p9_wstat
*stat
, dev_t
*rdev
)
111 u32 mode
= stat
->mode
;
114 res
= p9mode2perm(v9ses
, stat
);
116 if ((mode
& P9_DMDIR
) == P9_DMDIR
)
118 else if ((mode
& P9_DMSYMLINK
) && (v9fs_proto_dotu(v9ses
)))
120 else if ((mode
& P9_DMSOCKET
) && (v9fs_proto_dotu(v9ses
))
121 && (v9ses
->nodev
== 0))
123 else if ((mode
& P9_DMNAMEDPIPE
) && (v9fs_proto_dotu(v9ses
))
124 && (v9ses
->nodev
== 0))
126 else if ((mode
& P9_DMDEVICE
) && (v9fs_proto_dotu(v9ses
))
127 && (v9ses
->nodev
== 0)) {
129 int major
= -1, minor
= -1;
131 r
= sscanf(stat
->extension
, "%c %i %i", &type
, &major
, &minor
);
133 p9_debug(P9_DEBUG_ERROR
,
134 "invalid device string, umode will be bogus: %s\n",
146 p9_debug(P9_DEBUG_ERROR
, "Unknown special type %c %s\n",
147 type
, stat
->extension
);
149 *rdev
= MKDEV(major
, minor
);
157 * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits
158 * @uflags: flags to convert
159 * @extended: if .u extensions are active
162 int v9fs_uflags2omode(int uflags
, int extended
)
181 if (uflags
& O_TRUNC
)
188 if (uflags
& O_APPEND
)
196 * v9fs_blank_wstat - helper function to setup a 9P stat structure
197 * @wstat: structure to initialize
202 v9fs_blank_wstat(struct p9_wstat
*wstat
)
206 wstat
->qid
.type
= ~0;
207 wstat
->qid
.version
= ~0;
208 *((long long *)&wstat
->qid
.path
) = ~0;
217 wstat
->n_uid
= INVALID_UID
;
218 wstat
->n_gid
= INVALID_GID
;
219 wstat
->n_muid
= INVALID_UID
;
220 wstat
->extension
= NULL
;
224 * v9fs_alloc_inode - helper function to allocate an inode
225 * @sb: The superblock to allocate the inode from
227 struct inode
*v9fs_alloc_inode(struct super_block
*sb
)
229 struct v9fs_inode
*v9inode
;
231 v9inode
= alloc_inode_sb(sb
, v9fs_inode_cache
, GFP_KERNEL
);
234 v9inode
->cache_validity
= 0;
235 mutex_init(&v9inode
->v_mutex
);
236 return &v9inode
->netfs
.inode
;
240 * v9fs_free_inode - destroy an inode
241 * @inode: The inode to be freed
244 void v9fs_free_inode(struct inode
*inode
)
246 kmem_cache_free(v9fs_inode_cache
, V9FS_I(inode
));
250 * Set parameters for the netfs library
252 void v9fs_set_netfs_context(struct inode
*inode
)
254 struct v9fs_inode
*v9inode
= V9FS_I(inode
);
255 netfs_inode_init(&v9inode
->netfs
, &v9fs_req_ops
, true);
258 int v9fs_init_inode(struct v9fs_session_info
*v9ses
,
259 struct inode
*inode
, umode_t mode
, dev_t rdev
)
263 inode_init_owner(&nop_mnt_idmap
, inode
, NULL
, mode
);
265 inode
->i_rdev
= rdev
;
266 simple_inode_init_ts(inode
);
267 inode
->i_mapping
->a_ops
= &v9fs_addr_operations
;
268 inode
->i_private
= NULL
;
270 switch (mode
& S_IFMT
) {
275 if (v9fs_proto_dotl(v9ses
)) {
276 inode
->i_op
= &v9fs_file_inode_operations_dotl
;
277 } else if (v9fs_proto_dotu(v9ses
)) {
278 inode
->i_op
= &v9fs_file_inode_operations
;
280 p9_debug(P9_DEBUG_ERROR
,
281 "special files without extended mode\n");
285 init_special_inode(inode
, inode
->i_mode
, inode
->i_rdev
);
288 if (v9fs_proto_dotl(v9ses
)) {
289 inode
->i_op
= &v9fs_file_inode_operations_dotl
;
290 inode
->i_fop
= &v9fs_file_operations_dotl
;
292 inode
->i_op
= &v9fs_file_inode_operations
;
293 inode
->i_fop
= &v9fs_file_operations
;
298 if (!v9fs_proto_dotu(v9ses
) && !v9fs_proto_dotl(v9ses
)) {
299 p9_debug(P9_DEBUG_ERROR
,
300 "extended modes used with legacy protocol\n");
305 if (v9fs_proto_dotl(v9ses
))
306 inode
->i_op
= &v9fs_symlink_inode_operations_dotl
;
308 inode
->i_op
= &v9fs_symlink_inode_operations
;
313 if (v9fs_proto_dotl(v9ses
))
314 inode
->i_op
= &v9fs_dir_inode_operations_dotl
;
315 else if (v9fs_proto_dotu(v9ses
))
316 inode
->i_op
= &v9fs_dir_inode_operations_dotu
;
318 inode
->i_op
= &v9fs_dir_inode_operations
;
320 if (v9fs_proto_dotl(v9ses
))
321 inode
->i_fop
= &v9fs_dir_operations_dotl
;
323 inode
->i_fop
= &v9fs_dir_operations
;
327 p9_debug(P9_DEBUG_ERROR
, "BAD mode 0x%hx S_IFMT 0x%x\n",
328 mode
, mode
& S_IFMT
);
338 * v9fs_evict_inode - Remove an inode from the inode cache
339 * @inode: inode to release
342 void v9fs_evict_inode(struct inode
*inode
)
344 struct v9fs_inode __maybe_unused
*v9inode
= V9FS_I(inode
);
345 __le32 __maybe_unused version
;
347 if (!is_bad_inode(inode
)) {
348 netfs_wait_for_outstanding_io(inode
);
349 truncate_inode_pages_final(&inode
->i_data
);
351 version
= cpu_to_le32(v9inode
->qid
.version
);
352 netfs_clear_inode_writeback(inode
, &version
);
355 filemap_fdatawrite(&inode
->i_data
);
357 #ifdef CONFIG_9P_FSCACHE
358 if (v9fs_inode_cookie(v9inode
))
359 fscache_relinquish_cookie(v9fs_inode_cookie(v9inode
), false);
365 static int v9fs_test_inode(struct inode
*inode
, void *data
)
369 struct v9fs_inode
*v9inode
= V9FS_I(inode
);
370 struct p9_wstat
*st
= (struct p9_wstat
*)data
;
371 struct v9fs_session_info
*v9ses
= v9fs_inode2v9ses(inode
);
373 umode
= p9mode2unixmode(v9ses
, st
, &rdev
);
374 /* don't match inode of different type */
375 if (inode_wrong_type(inode
, umode
))
378 /* compare qid details */
379 if (memcmp(&v9inode
->qid
.version
,
380 &st
->qid
.version
, sizeof(v9inode
->qid
.version
)))
383 if (v9inode
->qid
.type
!= st
->qid
.type
)
386 if (v9inode
->qid
.path
!= st
->qid
.path
)
391 static int v9fs_test_new_inode(struct inode
*inode
, void *data
)
396 static int v9fs_set_inode(struct inode
*inode
, void *data
)
398 struct v9fs_inode
*v9inode
= V9FS_I(inode
);
399 struct p9_wstat
*st
= (struct p9_wstat
*)data
;
401 memcpy(&v9inode
->qid
, &st
->qid
, sizeof(st
->qid
));
405 static struct inode
*v9fs_qid_iget(struct super_block
*sb
,
414 struct v9fs_session_info
*v9ses
= sb
->s_fs_info
;
415 int (*test
)(struct inode
*inode
, void *data
);
418 test
= v9fs_test_new_inode
;
420 test
= v9fs_test_inode
;
422 inode
= iget5_locked(sb
, QID2INO(qid
), test
, v9fs_set_inode
, st
);
424 return ERR_PTR(-ENOMEM
);
425 if (!(inode
->i_state
& I_NEW
))
428 * initialize the inode with the stat info
429 * FIXME!! we may need support for stale inodes
432 inode
->i_ino
= QID2INO(qid
);
433 umode
= p9mode2unixmode(v9ses
, st
, &rdev
);
434 retval
= v9fs_init_inode(v9ses
, inode
, umode
, rdev
);
438 v9fs_stat2inode(st
, inode
, sb
, 0);
439 v9fs_set_netfs_context(inode
);
440 v9fs_cache_inode_get_cookie(inode
);
441 unlock_new_inode(inode
);
445 return ERR_PTR(retval
);
450 v9fs_inode_from_fid(struct v9fs_session_info
*v9ses
, struct p9_fid
*fid
,
451 struct super_block
*sb
, int new)
454 struct inode
*inode
= NULL
;
456 st
= p9_client_stat(fid
);
460 inode
= v9fs_qid_iget(sb
, &st
->qid
, st
, new);
467 * v9fs_at_to_dotl_flags- convert Linux specific AT flags to
469 * @flags: flags to convert
471 static int v9fs_at_to_dotl_flags(int flags
)
475 if (flags
& AT_REMOVEDIR
)
476 rflags
|= P9_DOTL_AT_REMOVEDIR
;
482 * v9fs_dec_count - helper functon to drop i_nlink.
484 * If a directory had nlink <= 2 (including . and ..), then we should not drop
485 * the link count, which indicates the underlying exported fs doesn't maintain
486 * nlink accurately. e.g.
487 * - overlayfs sets nlink to 1 for merged dir
488 * - ext4 (with dir_nlink feature enabled) sets nlink to 1 if a dir has more
489 * than EXT4_LINK_MAX (65000) links.
491 * @inode: inode whose nlink is being dropped
493 static void v9fs_dec_count(struct inode
*inode
)
495 if (!S_ISDIR(inode
->i_mode
) || inode
->i_nlink
> 2)
500 * v9fs_remove - helper function to remove files and directories
501 * @dir: directory inode that is being deleted
502 * @dentry: dentry that is being deleted
503 * @flags: removing a directory
507 static int v9fs_remove(struct inode
*dir
, struct dentry
*dentry
, int flags
)
510 int retval
= -EOPNOTSUPP
;
511 struct p9_fid
*v9fid
, *dfid
;
512 struct v9fs_session_info
*v9ses
;
514 p9_debug(P9_DEBUG_VFS
, "inode: %p dentry: %p rmdir: %x\n",
517 v9ses
= v9fs_inode2v9ses(dir
);
518 inode
= d_inode(dentry
);
519 dfid
= v9fs_parent_fid(dentry
);
521 retval
= PTR_ERR(dfid
);
522 p9_debug(P9_DEBUG_VFS
, "fid lookup failed %d\n", retval
);
525 if (v9fs_proto_dotl(v9ses
))
526 retval
= p9_client_unlinkat(dfid
, dentry
->d_name
.name
,
527 v9fs_at_to_dotl_flags(flags
));
529 if (retval
== -EOPNOTSUPP
) {
530 /* Try the one based on path */
531 v9fid
= v9fs_fid_clone(dentry
);
533 return PTR_ERR(v9fid
);
534 retval
= p9_client_remove(v9fid
);
538 * directories on unlink should have zero
541 if (flags
& AT_REMOVEDIR
) {
545 v9fs_dec_count(inode
);
547 v9fs_invalidate_inode_attr(inode
);
548 v9fs_invalidate_inode_attr(dir
);
550 /* invalidate all fids associated with dentry */
551 /* NOTE: This will not include open fids */
552 dentry
->d_op
->d_release(dentry
);
558 * v9fs_create - Create a file
559 * @v9ses: session information
560 * @dir: directory that dentry is being created in
561 * @dentry: dentry that is being created
562 * @extension: 9p2000.u extension string to support devices, etc.
563 * @perm: create permissions
567 static struct p9_fid
*
568 v9fs_create(struct v9fs_session_info
*v9ses
, struct inode
*dir
,
569 struct dentry
*dentry
, char *extension
, u32 perm
, u8 mode
)
572 const unsigned char *name
;
573 struct p9_fid
*dfid
, *ofid
= NULL
, *fid
= NULL
;
576 p9_debug(P9_DEBUG_VFS
, "name %pd\n", dentry
);
578 name
= dentry
->d_name
.name
;
579 dfid
= v9fs_parent_fid(dentry
);
582 p9_debug(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
586 /* clone a fid to use for creation */
587 ofid
= clone_fid(dfid
);
590 p9_debug(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
594 err
= p9_client_fcreate(ofid
, name
, perm
, mode
, extension
);
596 p9_debug(P9_DEBUG_VFS
, "p9_client_fcreate failed %d\n", err
);
600 if (!(perm
& P9_DMLINK
)) {
601 /* now walk from the parent so we can get unopened fid */
602 fid
= p9_client_walk(dfid
, 1, &name
, 1);
605 p9_debug(P9_DEBUG_VFS
,
606 "p9_client_walk failed %d\n", err
);
610 * instantiate inode and assign the unopened fid to the dentry
612 inode
= v9fs_get_new_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
614 err
= PTR_ERR(inode
);
615 p9_debug(P9_DEBUG_VFS
,
616 "inode creation failed %d\n", err
);
619 v9fs_fid_add(dentry
, &fid
);
620 d_instantiate(dentry
, inode
);
632 * v9fs_vfs_create - VFS hook to create a regular file
633 * @idmap: idmap of the mount
634 * @dir: The parent directory
635 * @dentry: The name of file to be created
636 * @mode: The UNIX file mode to set
637 * @excl: True if the file must not yet exist
639 * open(.., O_CREAT) is handled in v9fs_vfs_atomic_open(). This is only called
645 v9fs_vfs_create(struct mnt_idmap
*idmap
, struct inode
*dir
,
646 struct dentry
*dentry
, umode_t mode
, bool excl
)
648 struct v9fs_session_info
*v9ses
= v9fs_inode2v9ses(dir
);
649 u32 perm
= unixmode2p9mode(v9ses
, mode
);
653 fid
= v9fs_create(v9ses
, dir
, dentry
, NULL
, perm
, P9_ORDWR
);
657 v9fs_invalidate_inode_attr(dir
);
664 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
665 * @idmap: idmap of the mount
666 * @dir: inode that is being unlinked
667 * @dentry: dentry that is being unlinked
668 * @mode: mode for new directory
672 static int v9fs_vfs_mkdir(struct mnt_idmap
*idmap
, struct inode
*dir
,
673 struct dentry
*dentry
, umode_t mode
)
678 struct v9fs_session_info
*v9ses
;
680 p9_debug(P9_DEBUG_VFS
, "name %pd\n", dentry
);
682 v9ses
= v9fs_inode2v9ses(dir
);
683 perm
= unixmode2p9mode(v9ses
, mode
| S_IFDIR
);
684 fid
= v9fs_create(v9ses
, dir
, dentry
, NULL
, perm
, P9_OREAD
);
690 v9fs_invalidate_inode_attr(dir
);
700 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
701 * @dir: inode that is being walked from
702 * @dentry: dentry that is being walked to?
703 * @flags: lookup flags (unused)
707 struct dentry
*v9fs_vfs_lookup(struct inode
*dir
, struct dentry
*dentry
,
711 struct v9fs_session_info
*v9ses
;
712 struct p9_fid
*dfid
, *fid
;
714 const unsigned char *name
;
716 p9_debug(P9_DEBUG_VFS
, "dir: %p dentry: (%pd) %p flags: %x\n",
717 dir
, dentry
, dentry
, flags
);
719 if (dentry
->d_name
.len
> NAME_MAX
)
720 return ERR_PTR(-ENAMETOOLONG
);
722 v9ses
= v9fs_inode2v9ses(dir
);
723 /* We can walk d_parent because we hold the dir->i_mutex */
724 dfid
= v9fs_parent_fid(dentry
);
726 return ERR_CAST(dfid
);
729 * Make sure we don't use a wrong inode due to parallel
730 * unlink. For cached mode create calls request for new
731 * inode. But with cache disabled, lookup should do this.
733 name
= dentry
->d_name
.name
;
734 fid
= p9_client_walk(dfid
, 1, &name
, 1);
736 if (fid
== ERR_PTR(-ENOENT
))
738 else if (IS_ERR(fid
))
739 inode
= ERR_CAST(fid
);
740 else if (v9ses
->cache
& (CACHE_META
|CACHE_LOOSE
))
741 inode
= v9fs_get_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
743 inode
= v9fs_get_new_inode_from_fid(v9ses
, fid
, dir
->i_sb
);
745 * If we had a rename on the server and a parallel lookup
746 * for the new name, then make sure we instantiate with
747 * the new name. ie look up for a/b, while on server somebody
748 * moved b under k and client parallely did a lookup for
751 res
= d_splice_alias(inode
, dentry
);
754 v9fs_fid_add(dentry
, &fid
);
755 else if (!IS_ERR(res
))
756 v9fs_fid_add(res
, &fid
);
764 v9fs_vfs_atomic_open(struct inode
*dir
, struct dentry
*dentry
,
765 struct file
*file
, unsigned int flags
, umode_t mode
)
769 struct v9fs_inode __maybe_unused
*v9inode
;
770 struct v9fs_session_info
*v9ses
;
772 struct dentry
*res
= NULL
;
776 if (d_in_lookup(dentry
)) {
777 res
= v9fs_vfs_lookup(dir
, dentry
, 0);
786 if (!(flags
& O_CREAT
) || d_really_is_positive(dentry
))
787 return finish_no_open(file
, res
);
789 v9ses
= v9fs_inode2v9ses(dir
);
790 perm
= unixmode2p9mode(v9ses
, mode
);
791 p9_omode
= v9fs_uflags2omode(flags
, v9fs_proto_dotu(v9ses
));
793 if ((v9ses
->cache
& CACHE_WRITEBACK
) && (p9_omode
& P9_OWRITE
)) {
794 p9_omode
= (p9_omode
& ~P9_OWRITE
) | P9_ORDWR
;
795 p9_debug(P9_DEBUG_CACHE
,
796 "write-only file with writeback enabled, creating w/ O_RDWR\n");
798 fid
= v9fs_create(v9ses
, dir
, dentry
, NULL
, perm
, p9_omode
);
804 v9fs_invalidate_inode_attr(dir
);
805 inode
= d_inode(dentry
);
806 v9inode
= V9FS_I(inode
);
807 err
= finish_open(file
, dentry
, generic_file_open
);
811 file
->private_data
= fid
;
812 #ifdef CONFIG_9P_FSCACHE
813 if (v9ses
->cache
& CACHE_FSCACHE
)
814 fscache_use_cookie(v9fs_inode_cookie(v9inode
),
815 file
->f_mode
& FMODE_WRITE
);
818 v9fs_fid_add_modes(fid
, v9ses
->flags
, v9ses
->cache
, file
->f_flags
);
819 v9fs_open_fid_add(inode
, &fid
);
821 file
->f_mode
|= FMODE_CREATED
;
832 * v9fs_vfs_unlink - VFS unlink hook to delete an inode
833 * @i: inode that is being unlinked
834 * @d: dentry that is being unlinked
838 int v9fs_vfs_unlink(struct inode
*i
, struct dentry
*d
)
840 return v9fs_remove(i
, d
, 0);
844 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
845 * @i: inode that is being unlinked
846 * @d: dentry that is being unlinked
850 int v9fs_vfs_rmdir(struct inode
*i
, struct dentry
*d
)
852 return v9fs_remove(i
, d
, AT_REMOVEDIR
);
856 * v9fs_vfs_rename - VFS hook to rename an inode
857 * @idmap: The idmap of the mount
858 * @old_dir: old dir inode
859 * @old_dentry: old dentry
860 * @new_dir: new dir inode
861 * @new_dentry: new dentry
862 * @flags: RENAME_* flags
867 v9fs_vfs_rename(struct mnt_idmap
*idmap
, struct inode
*old_dir
,
868 struct dentry
*old_dentry
, struct inode
*new_dir
,
869 struct dentry
*new_dentry
, unsigned int flags
)
872 struct inode
*old_inode
;
873 struct inode
*new_inode
;
874 struct v9fs_session_info
*v9ses
;
875 struct p9_fid
*oldfid
= NULL
, *dfid
= NULL
;
876 struct p9_fid
*olddirfid
= NULL
;
877 struct p9_fid
*newdirfid
= NULL
;
878 struct p9_wstat wstat
;
883 p9_debug(P9_DEBUG_VFS
, "\n");
884 old_inode
= d_inode(old_dentry
);
885 new_inode
= d_inode(new_dentry
);
886 v9ses
= v9fs_inode2v9ses(old_inode
);
887 oldfid
= v9fs_fid_lookup(old_dentry
);
889 return PTR_ERR(oldfid
);
891 dfid
= v9fs_parent_fid(old_dentry
);
892 olddirfid
= clone_fid(dfid
);
896 if (IS_ERR(olddirfid
)) {
897 retval
= PTR_ERR(olddirfid
);
901 dfid
= v9fs_parent_fid(new_dentry
);
902 newdirfid
= clone_fid(dfid
);
906 if (IS_ERR(newdirfid
)) {
907 retval
= PTR_ERR(newdirfid
);
911 down_write(&v9ses
->rename_sem
);
912 if (v9fs_proto_dotl(v9ses
)) {
913 retval
= p9_client_renameat(olddirfid
, old_dentry
->d_name
.name
,
914 newdirfid
, new_dentry
->d_name
.name
);
915 if (retval
== -EOPNOTSUPP
)
916 retval
= p9_client_rename(oldfid
, newdirfid
,
917 new_dentry
->d_name
.name
);
918 if (retval
!= -EOPNOTSUPP
)
921 if (old_dentry
->d_parent
!= new_dentry
->d_parent
) {
923 * 9P .u can only handle file rename in the same directory
926 p9_debug(P9_DEBUG_ERROR
, "old dir and new dir are different\n");
930 v9fs_blank_wstat(&wstat
);
931 wstat
.muid
= v9ses
->uname
;
932 wstat
.name
= new_dentry
->d_name
.name
;
933 retval
= p9_client_wstat(oldfid
, &wstat
);
938 if (S_ISDIR(new_inode
->i_mode
))
939 clear_nlink(new_inode
);
941 v9fs_dec_count(new_inode
);
943 if (S_ISDIR(old_inode
->i_mode
)) {
946 v9fs_dec_count(old_dir
);
948 v9fs_invalidate_inode_attr(old_inode
);
949 v9fs_invalidate_inode_attr(old_dir
);
950 v9fs_invalidate_inode_attr(new_dir
);
952 /* successful rename */
953 d_move(old_dentry
, new_dentry
);
955 up_write(&v9ses
->rename_sem
);
958 p9_fid_put(newdirfid
);
959 p9_fid_put(olddirfid
);
965 * v9fs_vfs_getattr - retrieve file metadata
966 * @idmap: idmap of the mount
967 * @path: Object to query
968 * @stat: metadata structure to populate
969 * @request_mask: Mask of STATX_xxx flags indicating the caller's interests
970 * @flags: AT_STATX_xxx setting
975 v9fs_vfs_getattr(struct mnt_idmap
*idmap
, const struct path
*path
,
976 struct kstat
*stat
, u32 request_mask
, unsigned int flags
)
978 struct dentry
*dentry
= path
->dentry
;
979 struct inode
*inode
= d_inode(dentry
);
980 struct v9fs_session_info
*v9ses
;
984 p9_debug(P9_DEBUG_VFS
, "dentry: %p\n", dentry
);
985 v9ses
= v9fs_dentry2v9ses(dentry
);
986 if (v9ses
->cache
& (CACHE_META
|CACHE_LOOSE
)) {
987 generic_fillattr(&nop_mnt_idmap
, request_mask
, inode
, stat
);
989 } else if (v9ses
->cache
& CACHE_WRITEBACK
) {
990 if (S_ISREG(inode
->i_mode
)) {
991 int retval
= filemap_fdatawrite(inode
->i_mapping
);
994 p9_debug(P9_DEBUG_ERROR
,
995 "flushing writeback during getattr returned %d\n", retval
);
998 fid
= v9fs_fid_lookup(dentry
);
1000 return PTR_ERR(fid
);
1002 st
= p9_client_stat(fid
);
1007 v9fs_stat2inode(st
, d_inode(dentry
), dentry
->d_sb
, 0);
1008 generic_fillattr(&nop_mnt_idmap
, request_mask
, d_inode(dentry
), stat
);
1016 * v9fs_vfs_setattr - set file metadata
1017 * @idmap: idmap of the mount
1018 * @dentry: file whose metadata to set
1019 * @iattr: metadata assignment structure
1023 static int v9fs_vfs_setattr(struct mnt_idmap
*idmap
,
1024 struct dentry
*dentry
, struct iattr
*iattr
)
1026 int retval
, use_dentry
= 0;
1027 struct inode
*inode
= d_inode(dentry
);
1028 struct v9fs_session_info
*v9ses
;
1029 struct p9_fid
*fid
= NULL
;
1030 struct p9_wstat wstat
;
1032 p9_debug(P9_DEBUG_VFS
, "\n");
1033 retval
= setattr_prepare(&nop_mnt_idmap
, dentry
, iattr
);
1037 v9ses
= v9fs_dentry2v9ses(dentry
);
1038 if (iattr
->ia_valid
& ATTR_FILE
) {
1039 fid
= iattr
->ia_file
->private_data
;
1043 fid
= v9fs_fid_lookup(dentry
);
1047 return PTR_ERR(fid
);
1049 v9fs_blank_wstat(&wstat
);
1050 if (iattr
->ia_valid
& ATTR_MODE
)
1051 wstat
.mode
= unixmode2p9mode(v9ses
, iattr
->ia_mode
);
1053 if (iattr
->ia_valid
& ATTR_MTIME
)
1054 wstat
.mtime
= iattr
->ia_mtime
.tv_sec
;
1056 if (iattr
->ia_valid
& ATTR_ATIME
)
1057 wstat
.atime
= iattr
->ia_atime
.tv_sec
;
1059 if (iattr
->ia_valid
& ATTR_SIZE
)
1060 wstat
.length
= iattr
->ia_size
;
1062 if (v9fs_proto_dotu(v9ses
)) {
1063 if (iattr
->ia_valid
& ATTR_UID
)
1064 wstat
.n_uid
= iattr
->ia_uid
;
1066 if (iattr
->ia_valid
& ATTR_GID
)
1067 wstat
.n_gid
= iattr
->ia_gid
;
1070 /* Write all dirty data */
1071 if (d_is_reg(dentry
)) {
1072 retval
= filemap_fdatawrite(inode
->i_mapping
);
1074 p9_debug(P9_DEBUG_ERROR
,
1075 "flushing writeback during setattr returned %d\n", retval
);
1078 retval
= p9_client_wstat(fid
, &wstat
);
1086 if ((iattr
->ia_valid
& ATTR_SIZE
) &&
1087 iattr
->ia_size
!= i_size_read(inode
)) {
1088 truncate_setsize(inode
, iattr
->ia_size
);
1089 netfs_resize_file(netfs_inode(inode
), iattr
->ia_size
, true);
1091 #ifdef CONFIG_9P_FSCACHE
1092 if (v9ses
->cache
& CACHE_FSCACHE
) {
1093 struct v9fs_inode
*v9inode
= V9FS_I(inode
);
1095 fscache_resize_cookie(v9fs_inode_cookie(v9inode
), iattr
->ia_size
);
1100 v9fs_invalidate_inode_attr(inode
);
1102 setattr_copy(&nop_mnt_idmap
, inode
, iattr
);
1103 mark_inode_dirty(inode
);
1108 * v9fs_stat2inode - populate an inode structure with mistat info
1109 * @stat: Plan 9 metadata (mistat) structure
1110 * @inode: inode to populate
1111 * @sb: superblock of filesystem
1112 * @flags: control flags (e.g. V9FS_STAT2INODE_KEEP_ISIZE)
1117 v9fs_stat2inode(struct p9_wstat
*stat
, struct inode
*inode
,
1118 struct super_block
*sb
, unsigned int flags
)
1121 struct v9fs_session_info
*v9ses
= sb
->s_fs_info
;
1122 struct v9fs_inode
*v9inode
= V9FS_I(inode
);
1124 inode_set_atime(inode
, stat
->atime
, 0);
1125 inode_set_mtime(inode
, stat
->mtime
, 0);
1126 inode_set_ctime(inode
, stat
->mtime
, 0);
1128 inode
->i_uid
= v9ses
->dfltuid
;
1129 inode
->i_gid
= v9ses
->dfltgid
;
1131 if (v9fs_proto_dotu(v9ses
)) {
1132 inode
->i_uid
= stat
->n_uid
;
1133 inode
->i_gid
= stat
->n_gid
;
1135 if ((S_ISREG(inode
->i_mode
)) || (S_ISDIR(inode
->i_mode
))) {
1136 if (v9fs_proto_dotu(v9ses
)) {
1137 unsigned int i_nlink
;
1139 * Hadlink support got added later to the .u extension.
1140 * So there can be a server out there that doesn't
1141 * support this even with .u extension. That would
1142 * just leave us with stat->extension being an empty
1145 /* HARDLINKCOUNT %u */
1146 if (sscanf(stat
->extension
,
1147 " HARDLINKCOUNT %u", &i_nlink
) == 1)
1148 set_nlink(inode
, i_nlink
);
1151 mode
= p9mode2perm(v9ses
, stat
);
1152 mode
|= inode
->i_mode
& ~S_IALLUGO
;
1153 inode
->i_mode
= mode
;
1155 v9inode
->netfs
.remote_i_size
= stat
->length
;
1156 if (!(flags
& V9FS_STAT2INODE_KEEP_ISIZE
))
1157 v9fs_i_size_write(inode
, stat
->length
);
1158 /* not real number of blocks, but 512 byte ones ... */
1159 inode
->i_blocks
= (stat
->length
+ 512 - 1) >> 9;
1160 v9inode
->cache_validity
&= ~V9FS_INO_INVALID_ATTR
;
1164 * v9fs_vfs_get_link - follow a symlink path
1165 * @dentry: dentry for symlink
1166 * @inode: inode for symlink
1167 * @done: delayed call for when we are done with the return value
1170 static const char *v9fs_vfs_get_link(struct dentry
*dentry
,
1171 struct inode
*inode
,
1172 struct delayed_call
*done
)
1174 struct v9fs_session_info
*v9ses
;
1176 struct p9_wstat
*st
;
1180 return ERR_PTR(-ECHILD
);
1182 v9ses
= v9fs_dentry2v9ses(dentry
);
1183 if (!v9fs_proto_dotu(v9ses
))
1184 return ERR_PTR(-EBADF
);
1186 p9_debug(P9_DEBUG_VFS
, "%pd\n", dentry
);
1187 fid
= v9fs_fid_lookup(dentry
);
1190 return ERR_CAST(fid
);
1192 st
= p9_client_stat(fid
);
1195 return ERR_CAST(st
);
1197 if (!(st
->mode
& P9_DMSYMLINK
)) {
1200 return ERR_PTR(-EINVAL
);
1202 res
= st
->extension
;
1203 st
->extension
= NULL
;
1204 if (strlen(res
) >= PATH_MAX
)
1205 res
[PATH_MAX
- 1] = '\0';
1209 set_delayed_call(done
, kfree_link
, res
);
1214 * v9fs_vfs_mkspecial - create a special file
1215 * @dir: inode to create special file in
1216 * @dentry: dentry to create
1217 * @perm: mode to create special file
1218 * @extension: 9p2000.u format extension string representing special file
1222 static int v9fs_vfs_mkspecial(struct inode
*dir
, struct dentry
*dentry
,
1223 u32 perm
, const char *extension
)
1226 struct v9fs_session_info
*v9ses
;
1228 v9ses
= v9fs_inode2v9ses(dir
);
1229 if (!v9fs_proto_dotu(v9ses
)) {
1230 p9_debug(P9_DEBUG_ERROR
, "not extended\n");
1234 fid
= v9fs_create(v9ses
, dir
, dentry
, (char *) extension
, perm
,
1237 return PTR_ERR(fid
);
1239 v9fs_invalidate_inode_attr(dir
);
1245 * v9fs_vfs_symlink - helper function to create symlinks
1246 * @idmap: idmap of the mount
1247 * @dir: directory inode containing symlink
1248 * @dentry: dentry for symlink
1249 * @symname: symlink data
1251 * See Also: 9P2000.u RFC for more information
1256 v9fs_vfs_symlink(struct mnt_idmap
*idmap
, struct inode
*dir
,
1257 struct dentry
*dentry
, const char *symname
)
1259 p9_debug(P9_DEBUG_VFS
, " %lu,%pd,%s\n",
1260 dir
->i_ino
, dentry
, symname
);
1262 return v9fs_vfs_mkspecial(dir
, dentry
, P9_DMSYMLINK
, symname
);
1265 #define U32_MAX_DIGITS 10
1268 * v9fs_vfs_link - create a hardlink
1269 * @old_dentry: dentry for file to link to
1270 * @dir: inode destination for new link
1271 * @dentry: dentry for link
1276 v9fs_vfs_link(struct dentry
*old_dentry
, struct inode
*dir
,
1277 struct dentry
*dentry
)
1280 char name
[1 + U32_MAX_DIGITS
+ 2]; /* sign + number + \n + \0 */
1281 struct p9_fid
*oldfid
;
1283 p9_debug(P9_DEBUG_VFS
, " %lu,%pd,%pd\n",
1284 dir
->i_ino
, dentry
, old_dentry
);
1286 oldfid
= v9fs_fid_clone(old_dentry
);
1288 return PTR_ERR(oldfid
);
1290 sprintf(name
, "%d\n", oldfid
->fid
);
1291 retval
= v9fs_vfs_mkspecial(dir
, dentry
, P9_DMLINK
, name
);
1293 v9fs_refresh_inode(oldfid
, d_inode(old_dentry
));
1294 v9fs_invalidate_inode_attr(dir
);
1301 * v9fs_vfs_mknod - create a special file
1302 * @idmap: idmap of the mount
1303 * @dir: inode destination for new link
1304 * @dentry: dentry for file
1305 * @mode: mode for creation
1306 * @rdev: device associated with special file
1311 v9fs_vfs_mknod(struct mnt_idmap
*idmap
, struct inode
*dir
,
1312 struct dentry
*dentry
, umode_t mode
, dev_t rdev
)
1314 struct v9fs_session_info
*v9ses
= v9fs_inode2v9ses(dir
);
1316 char name
[2 + U32_MAX_DIGITS
+ 1 + U32_MAX_DIGITS
+ 1];
1319 p9_debug(P9_DEBUG_VFS
, " %lu,%pd mode: %x MAJOR: %u MINOR: %u\n",
1320 dir
->i_ino
, dentry
, mode
,
1321 MAJOR(rdev
), MINOR(rdev
));
1323 /* build extension */
1325 sprintf(name
, "b %u %u", MAJOR(rdev
), MINOR(rdev
));
1326 else if (S_ISCHR(mode
))
1327 sprintf(name
, "c %u %u", MAJOR(rdev
), MINOR(rdev
));
1331 perm
= unixmode2p9mode(v9ses
, mode
);
1332 retval
= v9fs_vfs_mkspecial(dir
, dentry
, perm
, name
);
1337 int v9fs_refresh_inode(struct p9_fid
*fid
, struct inode
*inode
)
1341 struct p9_wstat
*st
;
1342 struct v9fs_session_info
*v9ses
;
1345 v9ses
= v9fs_inode2v9ses(inode
);
1346 st
= p9_client_stat(fid
);
1350 * Don't update inode if the file type is different
1352 umode
= p9mode2unixmode(v9ses
, st
, &rdev
);
1353 if (inode_wrong_type(inode
, umode
))
1357 * We don't want to refresh inode->i_size,
1358 * because we may have cached data
1360 flags
= (v9ses
->cache
& CACHE_LOOSE
) ?
1361 V9FS_STAT2INODE_KEEP_ISIZE
: 0;
1362 v9fs_stat2inode(st
, inode
, inode
->i_sb
, flags
);
1369 static const struct inode_operations v9fs_dir_inode_operations_dotu
= {
1370 .create
= v9fs_vfs_create
,
1371 .lookup
= v9fs_vfs_lookup
,
1372 .atomic_open
= v9fs_vfs_atomic_open
,
1373 .symlink
= v9fs_vfs_symlink
,
1374 .link
= v9fs_vfs_link
,
1375 .unlink
= v9fs_vfs_unlink
,
1376 .mkdir
= v9fs_vfs_mkdir
,
1377 .rmdir
= v9fs_vfs_rmdir
,
1378 .mknod
= v9fs_vfs_mknod
,
1379 .rename
= v9fs_vfs_rename
,
1380 .getattr
= v9fs_vfs_getattr
,
1381 .setattr
= v9fs_vfs_setattr
,
1384 static const struct inode_operations v9fs_dir_inode_operations
= {
1385 .create
= v9fs_vfs_create
,
1386 .lookup
= v9fs_vfs_lookup
,
1387 .atomic_open
= v9fs_vfs_atomic_open
,
1388 .unlink
= v9fs_vfs_unlink
,
1389 .mkdir
= v9fs_vfs_mkdir
,
1390 .rmdir
= v9fs_vfs_rmdir
,
1391 .mknod
= v9fs_vfs_mknod
,
1392 .rename
= v9fs_vfs_rename
,
1393 .getattr
= v9fs_vfs_getattr
,
1394 .setattr
= v9fs_vfs_setattr
,
1397 static const struct inode_operations v9fs_file_inode_operations
= {
1398 .getattr
= v9fs_vfs_getattr
,
1399 .setattr
= v9fs_vfs_setattr
,
1402 static const struct inode_operations v9fs_symlink_inode_operations
= {
1403 .get_link
= v9fs_vfs_get_link
,
1404 .getattr
= v9fs_vfs_getattr
,
1405 .setattr
= v9fs_vfs_setattr
,