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
, struct p9_qid
*qid
, umode_t mode
, dev_t rdev
)
262 struct v9fs_inode
*v9inode
= V9FS_I(inode
);
264 memcpy(&v9inode
->qid
, qid
, sizeof(struct p9_qid
));
266 inode_init_owner(&nop_mnt_idmap
, inode
, NULL
, mode
);
268 inode
->i_rdev
= rdev
;
269 simple_inode_init_ts(inode
);
270 inode
->i_mapping
->a_ops
= &v9fs_addr_operations
;
271 inode
->i_private
= NULL
;
273 switch (mode
& S_IFMT
) {
278 if (v9fs_proto_dotl(v9ses
)) {
279 inode
->i_op
= &v9fs_file_inode_operations_dotl
;
280 } else if (v9fs_proto_dotu(v9ses
)) {
281 inode
->i_op
= &v9fs_file_inode_operations
;
283 p9_debug(P9_DEBUG_ERROR
,
284 "special files without extended mode\n");
288 init_special_inode(inode
, inode
->i_mode
, inode
->i_rdev
);
291 if (v9fs_proto_dotl(v9ses
)) {
292 inode
->i_op
= &v9fs_file_inode_operations_dotl
;
293 inode
->i_fop
= &v9fs_file_operations_dotl
;
295 inode
->i_op
= &v9fs_file_inode_operations
;
296 inode
->i_fop
= &v9fs_file_operations
;
301 if (!v9fs_proto_dotu(v9ses
) && !v9fs_proto_dotl(v9ses
)) {
302 p9_debug(P9_DEBUG_ERROR
,
303 "extended modes used with legacy protocol\n");
308 if (v9fs_proto_dotl(v9ses
))
309 inode
->i_op
= &v9fs_symlink_inode_operations_dotl
;
311 inode
->i_op
= &v9fs_symlink_inode_operations
;
316 if (v9fs_proto_dotl(v9ses
))
317 inode
->i_op
= &v9fs_dir_inode_operations_dotl
;
318 else if (v9fs_proto_dotu(v9ses
))
319 inode
->i_op
= &v9fs_dir_inode_operations_dotu
;
321 inode
->i_op
= &v9fs_dir_inode_operations
;
323 if (v9fs_proto_dotl(v9ses
))
324 inode
->i_fop
= &v9fs_dir_operations_dotl
;
326 inode
->i_fop
= &v9fs_dir_operations
;
330 p9_debug(P9_DEBUG_ERROR
, "BAD mode 0x%hx S_IFMT 0x%x\n",
331 mode
, mode
& S_IFMT
);
341 * v9fs_evict_inode - Remove an inode from the inode cache
342 * @inode: inode to release
345 void v9fs_evict_inode(struct inode
*inode
)
347 struct v9fs_inode __maybe_unused
*v9inode
= V9FS_I(inode
);
348 __le32 __maybe_unused version
;
350 if (!is_bad_inode(inode
)) {
351 netfs_wait_for_outstanding_io(inode
);
352 truncate_inode_pages_final(&inode
->i_data
);
354 version
= cpu_to_le32(v9inode
->qid
.version
);
355 netfs_clear_inode_writeback(inode
, &version
);
358 filemap_fdatawrite(&inode
->i_data
);
360 #ifdef CONFIG_9P_FSCACHE
361 if (v9fs_inode_cookie(v9inode
))
362 fscache_relinquish_cookie(v9fs_inode_cookie(v9inode
), false);
369 v9fs_fid_iget(struct super_block
*sb
, struct p9_fid
*fid
, bool new)
376 struct v9fs_session_info
*v9ses
= sb
->s_fs_info
;
378 inode
= iget_locked(sb
, QID2INO(&fid
->qid
));
379 if (unlikely(!inode
))
380 return ERR_PTR(-ENOMEM
);
381 if (!(inode
->i_state
& I_NEW
)) {
385 p9_debug(P9_DEBUG_VFS
, "WARNING: Inode collision %ld\n",
388 remove_inode_hash(inode
);
389 inode
= iget_locked(sb
, QID2INO(&fid
->qid
));
390 WARN_ON(!(inode
->i_state
& I_NEW
));
395 * initialize the inode with the stat info
396 * FIXME!! we may need support for stale inodes
399 st
= p9_client_stat(fid
);
401 retval
= PTR_ERR(st
);
405 umode
= p9mode2unixmode(v9ses
, st
, &rdev
);
406 retval
= v9fs_init_inode(v9ses
, inode
, &fid
->qid
, umode
, rdev
);
407 v9fs_stat2inode(st
, inode
, sb
, 0);
413 v9fs_set_netfs_context(inode
);
414 v9fs_cache_inode_get_cookie(inode
);
415 unlock_new_inode(inode
);
420 return ERR_PTR(retval
);
424 * v9fs_at_to_dotl_flags- convert Linux specific AT flags to
426 * @flags: flags to convert
428 static int v9fs_at_to_dotl_flags(int flags
)
432 if (flags
& AT_REMOVEDIR
)
433 rflags
|= P9_DOTL_AT_REMOVEDIR
;
439 * v9fs_dec_count - helper functon to drop i_nlink.
441 * If a directory had nlink <= 2 (including . and ..), then we should not drop
442 * the link count, which indicates the underlying exported fs doesn't maintain
443 * nlink accurately. e.g.
444 * - overlayfs sets nlink to 1 for merged dir
445 * - ext4 (with dir_nlink feature enabled) sets nlink to 1 if a dir has more
446 * than EXT4_LINK_MAX (65000) links.
448 * @inode: inode whose nlink is being dropped
450 static void v9fs_dec_count(struct inode
*inode
)
452 if (!S_ISDIR(inode
->i_mode
) || inode
->i_nlink
> 2) {
453 if (inode
->i_nlink
) {
456 p9_debug(P9_DEBUG_VFS
,
457 "WARNING: unexpected i_nlink zero %d inode %ld\n",
458 inode
->i_nlink
, inode
->i_ino
);
464 * v9fs_remove - helper function to remove files and directories
465 * @dir: directory inode that is being deleted
466 * @dentry: dentry that is being deleted
467 * @flags: removing a directory
471 static int v9fs_remove(struct inode
*dir
, struct dentry
*dentry
, int flags
)
474 int retval
= -EOPNOTSUPP
;
475 struct p9_fid
*v9fid
, *dfid
;
476 struct v9fs_session_info
*v9ses
;
478 p9_debug(P9_DEBUG_VFS
, "inode: %p dentry: %p rmdir: %x\n",
481 v9ses
= v9fs_inode2v9ses(dir
);
482 inode
= d_inode(dentry
);
483 dfid
= v9fs_parent_fid(dentry
);
485 retval
= PTR_ERR(dfid
);
486 p9_debug(P9_DEBUG_VFS
, "fid lookup failed %d\n", retval
);
489 if (v9fs_proto_dotl(v9ses
))
490 retval
= p9_client_unlinkat(dfid
, dentry
->d_name
.name
,
491 v9fs_at_to_dotl_flags(flags
));
493 if (retval
== -EOPNOTSUPP
) {
494 /* Try the one based on path */
495 v9fid
= v9fs_fid_clone(dentry
);
497 return PTR_ERR(v9fid
);
498 retval
= p9_client_remove(v9fid
);
502 * directories on unlink should have zero
505 if (flags
& AT_REMOVEDIR
) {
509 v9fs_dec_count(inode
);
511 if (inode
->i_nlink
<= 0) /* no more refs unhash it */
512 remove_inode_hash(inode
);
514 v9fs_invalidate_inode_attr(inode
);
515 v9fs_invalidate_inode_attr(dir
);
517 /* invalidate all fids associated with dentry */
518 /* NOTE: This will not include open fids */
519 dentry
->d_op
->d_release(dentry
);
525 * v9fs_create - Create a file
526 * @v9ses: session information
527 * @dir: directory that dentry is being created in
528 * @dentry: dentry that is being created
529 * @extension: 9p2000.u extension string to support devices, etc.
530 * @perm: create permissions
534 static struct p9_fid
*
535 v9fs_create(struct v9fs_session_info
*v9ses
, struct inode
*dir
,
536 struct dentry
*dentry
, char *extension
, u32 perm
, u8 mode
)
539 const unsigned char *name
;
540 struct p9_fid
*dfid
, *ofid
= NULL
, *fid
= NULL
;
543 p9_debug(P9_DEBUG_VFS
, "name %pd\n", dentry
);
545 name
= dentry
->d_name
.name
;
546 dfid
= v9fs_parent_fid(dentry
);
549 p9_debug(P9_DEBUG_VFS
, "fid lookup failed %d\n", err
);
553 /* clone a fid to use for creation */
554 ofid
= clone_fid(dfid
);
557 p9_debug(P9_DEBUG_VFS
, "p9_client_walk failed %d\n", err
);
561 err
= p9_client_fcreate(ofid
, name
, perm
, mode
, extension
);
563 p9_debug(P9_DEBUG_VFS
, "p9_client_fcreate failed %d\n", err
);
567 if (!(perm
& P9_DMLINK
)) {
568 /* now walk from the parent so we can get unopened fid */
569 fid
= p9_client_walk(dfid
, 1, &name
, 1);
572 p9_debug(P9_DEBUG_VFS
,
573 "p9_client_walk failed %d\n", err
);
577 * instantiate inode and assign the unopened fid to the dentry
579 inode
= v9fs_get_inode_from_fid(v9ses
, fid
, dir
->i_sb
, true);
581 err
= PTR_ERR(inode
);
582 p9_debug(P9_DEBUG_VFS
,
583 "inode creation failed %d\n", err
);
586 v9fs_fid_add(dentry
, &fid
);
587 d_instantiate(dentry
, inode
);
599 * v9fs_vfs_create - VFS hook to create a regular file
600 * @idmap: idmap of the mount
601 * @dir: The parent directory
602 * @dentry: The name of file to be created
603 * @mode: The UNIX file mode to set
604 * @excl: True if the file must not yet exist
606 * open(.., O_CREAT) is handled in v9fs_vfs_atomic_open(). This is only called
612 v9fs_vfs_create(struct mnt_idmap
*idmap
, struct inode
*dir
,
613 struct dentry
*dentry
, umode_t mode
, bool excl
)
615 struct v9fs_session_info
*v9ses
= v9fs_inode2v9ses(dir
);
616 u32 perm
= unixmode2p9mode(v9ses
, mode
);
620 fid
= v9fs_create(v9ses
, dir
, dentry
, NULL
, perm
, P9_ORDWR
);
624 v9fs_invalidate_inode_attr(dir
);
631 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
632 * @idmap: idmap of the mount
633 * @dir: inode that is being unlinked
634 * @dentry: dentry that is being unlinked
635 * @mode: mode for new directory
639 static int v9fs_vfs_mkdir(struct mnt_idmap
*idmap
, struct inode
*dir
,
640 struct dentry
*dentry
, umode_t mode
)
645 struct v9fs_session_info
*v9ses
;
647 p9_debug(P9_DEBUG_VFS
, "name %pd\n", dentry
);
649 v9ses
= v9fs_inode2v9ses(dir
);
650 perm
= unixmode2p9mode(v9ses
, mode
| S_IFDIR
);
651 fid
= v9fs_create(v9ses
, dir
, dentry
, NULL
, perm
, P9_OREAD
);
657 v9fs_invalidate_inode_attr(dir
);
667 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
668 * @dir: inode that is being walked from
669 * @dentry: dentry that is being walked to?
670 * @flags: lookup flags (unused)
674 struct dentry
*v9fs_vfs_lookup(struct inode
*dir
, struct dentry
*dentry
,
678 struct v9fs_session_info
*v9ses
;
679 struct p9_fid
*dfid
, *fid
;
681 const unsigned char *name
;
683 p9_debug(P9_DEBUG_VFS
, "dir: %p dentry: (%pd) %p flags: %x\n",
684 dir
, dentry
, dentry
, flags
);
686 if (dentry
->d_name
.len
> NAME_MAX
)
687 return ERR_PTR(-ENAMETOOLONG
);
689 v9ses
= v9fs_inode2v9ses(dir
);
690 /* We can walk d_parent because we hold the dir->i_mutex */
691 dfid
= v9fs_parent_fid(dentry
);
693 return ERR_CAST(dfid
);
696 * Make sure we don't use a wrong inode due to parallel
697 * unlink. For cached mode create calls request for new
698 * inode. But with cache disabled, lookup should do this.
700 name
= dentry
->d_name
.name
;
701 fid
= p9_client_walk(dfid
, 1, &name
, 1);
703 if (fid
== ERR_PTR(-ENOENT
))
705 else if (IS_ERR(fid
))
706 inode
= ERR_CAST(fid
);
708 inode
= v9fs_get_inode_from_fid(v9ses
, fid
, dir
->i_sb
, false);
710 * If we had a rename on the server and a parallel lookup
711 * for the new name, then make sure we instantiate with
712 * the new name. ie look up for a/b, while on server somebody
713 * moved b under k and client parallely did a lookup for
716 res
= d_splice_alias(inode
, dentry
);
719 v9fs_fid_add(dentry
, &fid
);
720 else if (!IS_ERR(res
))
721 v9fs_fid_add(res
, &fid
);
729 v9fs_vfs_atomic_open(struct inode
*dir
, struct dentry
*dentry
,
730 struct file
*file
, unsigned int flags
, umode_t mode
)
734 struct v9fs_inode __maybe_unused
*v9inode
;
735 struct v9fs_session_info
*v9ses
;
737 struct dentry
*res
= NULL
;
741 if (d_in_lookup(dentry
)) {
742 res
= v9fs_vfs_lookup(dir
, dentry
, 0);
751 if (!(flags
& O_CREAT
) || d_really_is_positive(dentry
))
752 return finish_no_open(file
, res
);
754 v9ses
= v9fs_inode2v9ses(dir
);
755 perm
= unixmode2p9mode(v9ses
, mode
);
756 p9_omode
= v9fs_uflags2omode(flags
, v9fs_proto_dotu(v9ses
));
758 if ((v9ses
->cache
& CACHE_WRITEBACK
) && (p9_omode
& P9_OWRITE
)) {
759 p9_omode
= (p9_omode
& ~P9_OWRITE
) | P9_ORDWR
;
760 p9_debug(P9_DEBUG_CACHE
,
761 "write-only file with writeback enabled, creating w/ O_RDWR\n");
763 fid
= v9fs_create(v9ses
, dir
, dentry
, NULL
, perm
, p9_omode
);
769 v9fs_invalidate_inode_attr(dir
);
770 inode
= d_inode(dentry
);
771 v9inode
= V9FS_I(inode
);
772 err
= finish_open(file
, dentry
, generic_file_open
);
776 file
->private_data
= fid
;
777 #ifdef CONFIG_9P_FSCACHE
778 if (v9ses
->cache
& CACHE_FSCACHE
)
779 fscache_use_cookie(v9fs_inode_cookie(v9inode
),
780 file
->f_mode
& FMODE_WRITE
);
783 v9fs_fid_add_modes(fid
, v9ses
->flags
, v9ses
->cache
, file
->f_flags
);
784 v9fs_open_fid_add(inode
, &fid
);
786 file
->f_mode
|= FMODE_CREATED
;
797 * v9fs_vfs_unlink - VFS unlink hook to delete an inode
798 * @i: inode that is being unlinked
799 * @d: dentry that is being unlinked
803 int v9fs_vfs_unlink(struct inode
*i
, struct dentry
*d
)
805 return v9fs_remove(i
, d
, 0);
809 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
810 * @i: inode that is being unlinked
811 * @d: dentry that is being unlinked
815 int v9fs_vfs_rmdir(struct inode
*i
, struct dentry
*d
)
817 return v9fs_remove(i
, d
, AT_REMOVEDIR
);
821 * v9fs_vfs_rename - VFS hook to rename an inode
822 * @idmap: The idmap of the mount
823 * @old_dir: old dir inode
824 * @old_dentry: old dentry
825 * @new_dir: new dir inode
826 * @new_dentry: new dentry
827 * @flags: RENAME_* flags
832 v9fs_vfs_rename(struct mnt_idmap
*idmap
, struct inode
*old_dir
,
833 struct dentry
*old_dentry
, struct inode
*new_dir
,
834 struct dentry
*new_dentry
, unsigned int flags
)
837 struct inode
*old_inode
;
838 struct inode
*new_inode
;
839 struct v9fs_session_info
*v9ses
;
840 struct p9_fid
*oldfid
= NULL
, *dfid
= NULL
;
841 struct p9_fid
*olddirfid
= NULL
;
842 struct p9_fid
*newdirfid
= NULL
;
843 struct p9_wstat wstat
;
848 p9_debug(P9_DEBUG_VFS
, "\n");
849 old_inode
= d_inode(old_dentry
);
850 new_inode
= d_inode(new_dentry
);
851 v9ses
= v9fs_inode2v9ses(old_inode
);
852 oldfid
= v9fs_fid_lookup(old_dentry
);
854 return PTR_ERR(oldfid
);
856 dfid
= v9fs_parent_fid(old_dentry
);
857 olddirfid
= clone_fid(dfid
);
861 if (IS_ERR(olddirfid
)) {
862 retval
= PTR_ERR(olddirfid
);
866 dfid
= v9fs_parent_fid(new_dentry
);
867 newdirfid
= clone_fid(dfid
);
871 if (IS_ERR(newdirfid
)) {
872 retval
= PTR_ERR(newdirfid
);
876 down_write(&v9ses
->rename_sem
);
877 if (v9fs_proto_dotl(v9ses
)) {
878 retval
= p9_client_renameat(olddirfid
, old_dentry
->d_name
.name
,
879 newdirfid
, new_dentry
->d_name
.name
);
880 if (retval
== -EOPNOTSUPP
)
881 retval
= p9_client_rename(oldfid
, newdirfid
,
882 new_dentry
->d_name
.name
);
883 if (retval
!= -EOPNOTSUPP
)
886 if (old_dentry
->d_parent
!= new_dentry
->d_parent
) {
888 * 9P .u can only handle file rename in the same directory
891 p9_debug(P9_DEBUG_ERROR
, "old dir and new dir are different\n");
895 v9fs_blank_wstat(&wstat
);
896 wstat
.muid
= v9ses
->uname
;
897 wstat
.name
= new_dentry
->d_name
.name
;
898 retval
= p9_client_wstat(oldfid
, &wstat
);
903 if (S_ISDIR(new_inode
->i_mode
))
904 clear_nlink(new_inode
);
906 v9fs_dec_count(new_inode
);
908 if (S_ISDIR(old_inode
->i_mode
)) {
911 v9fs_dec_count(old_dir
);
913 v9fs_invalidate_inode_attr(old_inode
);
914 v9fs_invalidate_inode_attr(old_dir
);
915 v9fs_invalidate_inode_attr(new_dir
);
917 /* successful rename */
918 d_move(old_dentry
, new_dentry
);
920 up_write(&v9ses
->rename_sem
);
923 p9_fid_put(newdirfid
);
924 p9_fid_put(olddirfid
);
930 * v9fs_vfs_getattr - retrieve file metadata
931 * @idmap: idmap of the mount
932 * @path: Object to query
933 * @stat: metadata structure to populate
934 * @request_mask: Mask of STATX_xxx flags indicating the caller's interests
935 * @flags: AT_STATX_xxx setting
940 v9fs_vfs_getattr(struct mnt_idmap
*idmap
, const struct path
*path
,
941 struct kstat
*stat
, u32 request_mask
, unsigned int flags
)
943 struct dentry
*dentry
= path
->dentry
;
944 struct inode
*inode
= d_inode(dentry
);
945 struct v9fs_session_info
*v9ses
;
949 p9_debug(P9_DEBUG_VFS
, "dentry: %p\n", dentry
);
950 v9ses
= v9fs_dentry2v9ses(dentry
);
951 if (v9ses
->cache
& (CACHE_META
|CACHE_LOOSE
)) {
952 generic_fillattr(&nop_mnt_idmap
, request_mask
, inode
, stat
);
954 } else if (v9ses
->cache
& CACHE_WRITEBACK
) {
955 if (S_ISREG(inode
->i_mode
)) {
956 int retval
= filemap_fdatawrite(inode
->i_mapping
);
959 p9_debug(P9_DEBUG_ERROR
,
960 "flushing writeback during getattr returned %d\n", retval
);
963 fid
= v9fs_fid_lookup(dentry
);
967 st
= p9_client_stat(fid
);
972 v9fs_stat2inode(st
, d_inode(dentry
), dentry
->d_sb
, 0);
973 generic_fillattr(&nop_mnt_idmap
, request_mask
, d_inode(dentry
), stat
);
981 * v9fs_vfs_setattr - set file metadata
982 * @idmap: idmap of the mount
983 * @dentry: file whose metadata to set
984 * @iattr: metadata assignment structure
988 static int v9fs_vfs_setattr(struct mnt_idmap
*idmap
,
989 struct dentry
*dentry
, struct iattr
*iattr
)
991 int retval
, use_dentry
= 0;
992 struct inode
*inode
= d_inode(dentry
);
993 struct v9fs_session_info
*v9ses
;
994 struct p9_fid
*fid
= NULL
;
995 struct p9_wstat wstat
;
997 p9_debug(P9_DEBUG_VFS
, "\n");
998 retval
= setattr_prepare(&nop_mnt_idmap
, dentry
, iattr
);
1002 v9ses
= v9fs_dentry2v9ses(dentry
);
1003 if (iattr
->ia_valid
& ATTR_FILE
) {
1004 fid
= iattr
->ia_file
->private_data
;
1008 fid
= v9fs_fid_lookup(dentry
);
1012 return PTR_ERR(fid
);
1014 v9fs_blank_wstat(&wstat
);
1015 if (iattr
->ia_valid
& ATTR_MODE
)
1016 wstat
.mode
= unixmode2p9mode(v9ses
, iattr
->ia_mode
);
1018 if (iattr
->ia_valid
& ATTR_MTIME
)
1019 wstat
.mtime
= iattr
->ia_mtime
.tv_sec
;
1021 if (iattr
->ia_valid
& ATTR_ATIME
)
1022 wstat
.atime
= iattr
->ia_atime
.tv_sec
;
1024 if (iattr
->ia_valid
& ATTR_SIZE
)
1025 wstat
.length
= iattr
->ia_size
;
1027 if (v9fs_proto_dotu(v9ses
)) {
1028 if (iattr
->ia_valid
& ATTR_UID
)
1029 wstat
.n_uid
= iattr
->ia_uid
;
1031 if (iattr
->ia_valid
& ATTR_GID
)
1032 wstat
.n_gid
= iattr
->ia_gid
;
1035 /* Write all dirty data */
1036 if (d_is_reg(dentry
)) {
1037 retval
= filemap_fdatawrite(inode
->i_mapping
);
1039 p9_debug(P9_DEBUG_ERROR
,
1040 "flushing writeback during setattr returned %d\n", retval
);
1043 retval
= p9_client_wstat(fid
, &wstat
);
1051 if ((iattr
->ia_valid
& ATTR_SIZE
) &&
1052 iattr
->ia_size
!= i_size_read(inode
)) {
1053 truncate_setsize(inode
, iattr
->ia_size
);
1054 netfs_resize_file(netfs_inode(inode
), iattr
->ia_size
, true);
1056 #ifdef CONFIG_9P_FSCACHE
1057 if (v9ses
->cache
& CACHE_FSCACHE
) {
1058 struct v9fs_inode
*v9inode
= V9FS_I(inode
);
1060 fscache_resize_cookie(v9fs_inode_cookie(v9inode
), iattr
->ia_size
);
1065 v9fs_invalidate_inode_attr(inode
);
1067 setattr_copy(&nop_mnt_idmap
, inode
, iattr
);
1068 mark_inode_dirty(inode
);
1073 * v9fs_stat2inode - populate an inode structure with mistat info
1074 * @stat: Plan 9 metadata (mistat) structure
1075 * @inode: inode to populate
1076 * @sb: superblock of filesystem
1077 * @flags: control flags (e.g. V9FS_STAT2INODE_KEEP_ISIZE)
1082 v9fs_stat2inode(struct p9_wstat
*stat
, struct inode
*inode
,
1083 struct super_block
*sb
, unsigned int flags
)
1086 struct v9fs_session_info
*v9ses
= sb
->s_fs_info
;
1087 struct v9fs_inode
*v9inode
= V9FS_I(inode
);
1089 inode_set_atime(inode
, stat
->atime
, 0);
1090 inode_set_mtime(inode
, stat
->mtime
, 0);
1091 inode_set_ctime(inode
, stat
->mtime
, 0);
1093 inode
->i_uid
= v9ses
->dfltuid
;
1094 inode
->i_gid
= v9ses
->dfltgid
;
1096 if (v9fs_proto_dotu(v9ses
)) {
1097 inode
->i_uid
= stat
->n_uid
;
1098 inode
->i_gid
= stat
->n_gid
;
1100 if ((S_ISREG(inode
->i_mode
)) || (S_ISDIR(inode
->i_mode
))) {
1101 if (v9fs_proto_dotu(v9ses
)) {
1102 unsigned int i_nlink
;
1104 * Hadlink support got added later to the .u extension.
1105 * So there can be a server out there that doesn't
1106 * support this even with .u extension. That would
1107 * just leave us with stat->extension being an empty
1110 /* HARDLINKCOUNT %u */
1111 if (sscanf(stat
->extension
,
1112 " HARDLINKCOUNT %u", &i_nlink
) == 1)
1113 set_nlink(inode
, i_nlink
);
1116 mode
= p9mode2perm(v9ses
, stat
);
1117 mode
|= inode
->i_mode
& ~S_IALLUGO
;
1118 inode
->i_mode
= mode
;
1120 v9inode
->netfs
.remote_i_size
= stat
->length
;
1121 if (!(flags
& V9FS_STAT2INODE_KEEP_ISIZE
))
1122 v9fs_i_size_write(inode
, stat
->length
);
1123 /* not real number of blocks, but 512 byte ones ... */
1124 inode
->i_blocks
= (stat
->length
+ 512 - 1) >> 9;
1125 v9inode
->cache_validity
&= ~V9FS_INO_INVALID_ATTR
;
1129 * v9fs_vfs_get_link - follow a symlink path
1130 * @dentry: dentry for symlink
1131 * @inode: inode for symlink
1132 * @done: delayed call for when we are done with the return value
1135 static const char *v9fs_vfs_get_link(struct dentry
*dentry
,
1136 struct inode
*inode
,
1137 struct delayed_call
*done
)
1139 struct v9fs_session_info
*v9ses
;
1141 struct p9_wstat
*st
;
1145 return ERR_PTR(-ECHILD
);
1147 v9ses
= v9fs_dentry2v9ses(dentry
);
1148 if (!v9fs_proto_dotu(v9ses
))
1149 return ERR_PTR(-EBADF
);
1151 p9_debug(P9_DEBUG_VFS
, "%pd\n", dentry
);
1152 fid
= v9fs_fid_lookup(dentry
);
1155 return ERR_CAST(fid
);
1157 st
= p9_client_stat(fid
);
1160 return ERR_CAST(st
);
1162 if (!(st
->mode
& P9_DMSYMLINK
)) {
1165 return ERR_PTR(-EINVAL
);
1167 res
= st
->extension
;
1168 st
->extension
= NULL
;
1169 if (strlen(res
) >= PATH_MAX
)
1170 res
[PATH_MAX
- 1] = '\0';
1174 set_delayed_call(done
, kfree_link
, res
);
1179 * v9fs_vfs_mkspecial - create a special file
1180 * @dir: inode to create special file in
1181 * @dentry: dentry to create
1182 * @perm: mode to create special file
1183 * @extension: 9p2000.u format extension string representing special file
1187 static int v9fs_vfs_mkspecial(struct inode
*dir
, struct dentry
*dentry
,
1188 u32 perm
, const char *extension
)
1191 struct v9fs_session_info
*v9ses
;
1193 v9ses
= v9fs_inode2v9ses(dir
);
1194 if (!v9fs_proto_dotu(v9ses
)) {
1195 p9_debug(P9_DEBUG_ERROR
, "not extended\n");
1199 fid
= v9fs_create(v9ses
, dir
, dentry
, (char *) extension
, perm
,
1202 return PTR_ERR(fid
);
1204 v9fs_invalidate_inode_attr(dir
);
1210 * v9fs_vfs_symlink - helper function to create symlinks
1211 * @idmap: idmap of the mount
1212 * @dir: directory inode containing symlink
1213 * @dentry: dentry for symlink
1214 * @symname: symlink data
1216 * See Also: 9P2000.u RFC for more information
1221 v9fs_vfs_symlink(struct mnt_idmap
*idmap
, struct inode
*dir
,
1222 struct dentry
*dentry
, const char *symname
)
1224 p9_debug(P9_DEBUG_VFS
, " %lu,%pd,%s\n",
1225 dir
->i_ino
, dentry
, symname
);
1227 return v9fs_vfs_mkspecial(dir
, dentry
, P9_DMSYMLINK
, symname
);
1230 #define U32_MAX_DIGITS 10
1233 * v9fs_vfs_link - create a hardlink
1234 * @old_dentry: dentry for file to link to
1235 * @dir: inode destination for new link
1236 * @dentry: dentry for link
1241 v9fs_vfs_link(struct dentry
*old_dentry
, struct inode
*dir
,
1242 struct dentry
*dentry
)
1245 char name
[1 + U32_MAX_DIGITS
+ 2]; /* sign + number + \n + \0 */
1246 struct p9_fid
*oldfid
;
1248 p9_debug(P9_DEBUG_VFS
, " %lu,%pd,%pd\n",
1249 dir
->i_ino
, dentry
, old_dentry
);
1251 oldfid
= v9fs_fid_clone(old_dentry
);
1253 return PTR_ERR(oldfid
);
1255 sprintf(name
, "%d\n", oldfid
->fid
);
1256 retval
= v9fs_vfs_mkspecial(dir
, dentry
, P9_DMLINK
, name
);
1258 v9fs_refresh_inode(oldfid
, d_inode(old_dentry
));
1259 v9fs_invalidate_inode_attr(dir
);
1266 * v9fs_vfs_mknod - create a special file
1267 * @idmap: idmap of the mount
1268 * @dir: inode destination for new link
1269 * @dentry: dentry for file
1270 * @mode: mode for creation
1271 * @rdev: device associated with special file
1276 v9fs_vfs_mknod(struct mnt_idmap
*idmap
, struct inode
*dir
,
1277 struct dentry
*dentry
, umode_t mode
, dev_t rdev
)
1279 struct v9fs_session_info
*v9ses
= v9fs_inode2v9ses(dir
);
1281 char name
[2 + U32_MAX_DIGITS
+ 1 + U32_MAX_DIGITS
+ 1];
1284 p9_debug(P9_DEBUG_VFS
, " %lu,%pd mode: %x MAJOR: %u MINOR: %u\n",
1285 dir
->i_ino
, dentry
, mode
,
1286 MAJOR(rdev
), MINOR(rdev
));
1288 /* build extension */
1290 sprintf(name
, "b %u %u", MAJOR(rdev
), MINOR(rdev
));
1291 else if (S_ISCHR(mode
))
1292 sprintf(name
, "c %u %u", MAJOR(rdev
), MINOR(rdev
));
1296 perm
= unixmode2p9mode(v9ses
, mode
);
1297 retval
= v9fs_vfs_mkspecial(dir
, dentry
, perm
, name
);
1302 int v9fs_refresh_inode(struct p9_fid
*fid
, struct inode
*inode
)
1306 struct p9_wstat
*st
;
1307 struct v9fs_session_info
*v9ses
;
1310 v9ses
= v9fs_inode2v9ses(inode
);
1311 st
= p9_client_stat(fid
);
1315 * Don't update inode if the file type is different
1317 umode
= p9mode2unixmode(v9ses
, st
, &rdev
);
1318 if (inode_wrong_type(inode
, umode
))
1322 * We don't want to refresh inode->i_size,
1323 * because we may have cached data
1325 flags
= (v9ses
->cache
& CACHE_LOOSE
) ?
1326 V9FS_STAT2INODE_KEEP_ISIZE
: 0;
1327 v9fs_stat2inode(st
, inode
, inode
->i_sb
, flags
);
1334 static const struct inode_operations v9fs_dir_inode_operations_dotu
= {
1335 .create
= v9fs_vfs_create
,
1336 .lookup
= v9fs_vfs_lookup
,
1337 .atomic_open
= v9fs_vfs_atomic_open
,
1338 .symlink
= v9fs_vfs_symlink
,
1339 .link
= v9fs_vfs_link
,
1340 .unlink
= v9fs_vfs_unlink
,
1341 .mkdir
= v9fs_vfs_mkdir
,
1342 .rmdir
= v9fs_vfs_rmdir
,
1343 .mknod
= v9fs_vfs_mknod
,
1344 .rename
= v9fs_vfs_rename
,
1345 .getattr
= v9fs_vfs_getattr
,
1346 .setattr
= v9fs_vfs_setattr
,
1349 static const struct inode_operations v9fs_dir_inode_operations
= {
1350 .create
= v9fs_vfs_create
,
1351 .lookup
= v9fs_vfs_lookup
,
1352 .atomic_open
= v9fs_vfs_atomic_open
,
1353 .unlink
= v9fs_vfs_unlink
,
1354 .mkdir
= v9fs_vfs_mkdir
,
1355 .rmdir
= v9fs_vfs_rmdir
,
1356 .mknod
= v9fs_vfs_mknod
,
1357 .rename
= v9fs_vfs_rename
,
1358 .getattr
= v9fs_vfs_getattr
,
1359 .setattr
= v9fs_vfs_setattr
,
1362 static const struct inode_operations v9fs_file_inode_operations
= {
1363 .getattr
= v9fs_vfs_getattr
,
1364 .setattr
= v9fs_vfs_setattr
,
1367 static const struct inode_operations v9fs_symlink_inode_operations
= {
1368 .get_link
= v9fs_vfs_get_link
,
1369 .getattr
= v9fs_vfs_getattr
,
1370 .setattr
= v9fs_vfs_setattr
,