18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/fs/9p/vfs_inode_dotl.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * This file contains vfs inode ops for the 9P2000.L protocol. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 88c2ecf20Sopenharmony_ci * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci#include <linux/errno.h> 138c2ecf20Sopenharmony_ci#include <linux/fs.h> 148c2ecf20Sopenharmony_ci#include <linux/file.h> 158c2ecf20Sopenharmony_ci#include <linux/pagemap.h> 168c2ecf20Sopenharmony_ci#include <linux/stat.h> 178c2ecf20Sopenharmony_ci#include <linux/string.h> 188c2ecf20Sopenharmony_ci#include <linux/inet.h> 198c2ecf20Sopenharmony_ci#include <linux/namei.h> 208c2ecf20Sopenharmony_ci#include <linux/idr.h> 218c2ecf20Sopenharmony_ci#include <linux/sched.h> 228c2ecf20Sopenharmony_ci#include <linux/slab.h> 238c2ecf20Sopenharmony_ci#include <linux/xattr.h> 248c2ecf20Sopenharmony_ci#include <linux/posix_acl.h> 258c2ecf20Sopenharmony_ci#include <net/9p/9p.h> 268c2ecf20Sopenharmony_ci#include <net/9p/client.h> 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#include "v9fs.h" 298c2ecf20Sopenharmony_ci#include "v9fs_vfs.h" 308c2ecf20Sopenharmony_ci#include "fid.h" 318c2ecf20Sopenharmony_ci#include "cache.h" 328c2ecf20Sopenharmony_ci#include "xattr.h" 338c2ecf20Sopenharmony_ci#include "acl.h" 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic int 368c2ecf20Sopenharmony_civ9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, 378c2ecf20Sopenharmony_ci dev_t rdev); 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci/** 408c2ecf20Sopenharmony_ci * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a 418c2ecf20Sopenharmony_ci * new file system object. This checks the S_ISGID to determine the owning 428c2ecf20Sopenharmony_ci * group of the new file system object. 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistatic kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci BUG_ON(dir_inode == NULL); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci if (dir_inode->i_mode & S_ISGID) { 508c2ecf20Sopenharmony_ci /* set_gid bit is set.*/ 518c2ecf20Sopenharmony_ci return dir_inode->i_gid; 528c2ecf20Sopenharmony_ci } 538c2ecf20Sopenharmony_ci return current_fsgid(); 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic int v9fs_test_inode_dotl(struct inode *inode, void *data) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci struct v9fs_inode *v9inode = V9FS_I(inode); 598c2ecf20Sopenharmony_ci struct p9_stat_dotl *st = (struct p9_stat_dotl *)data; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* don't match inode of different type */ 628c2ecf20Sopenharmony_ci if (inode_wrong_type(inode, st->st_mode)) 638c2ecf20Sopenharmony_ci return 0; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci if (inode->i_generation != st->st_gen) 668c2ecf20Sopenharmony_ci return 0; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci /* compare qid details */ 698c2ecf20Sopenharmony_ci if (memcmp(&v9inode->qid.version, 708c2ecf20Sopenharmony_ci &st->qid.version, sizeof(v9inode->qid.version))) 718c2ecf20Sopenharmony_ci return 0; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci if (v9inode->qid.type != st->qid.type) 748c2ecf20Sopenharmony_ci return 0; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci if (v9inode->qid.path != st->qid.path) 778c2ecf20Sopenharmony_ci return 0; 788c2ecf20Sopenharmony_ci return 1; 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci/* Always get a new inode */ 828c2ecf20Sopenharmony_cistatic int v9fs_test_new_inode_dotl(struct inode *inode, void *data) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci return 0; 858c2ecf20Sopenharmony_ci} 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_cistatic int v9fs_set_inode_dotl(struct inode *inode, void *data) 888c2ecf20Sopenharmony_ci{ 898c2ecf20Sopenharmony_ci struct v9fs_inode *v9inode = V9FS_I(inode); 908c2ecf20Sopenharmony_ci struct p9_stat_dotl *st = (struct p9_stat_dotl *)data; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci memcpy(&v9inode->qid, &st->qid, sizeof(st->qid)); 938c2ecf20Sopenharmony_ci inode->i_generation = st->st_gen; 948c2ecf20Sopenharmony_ci return 0; 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_cistatic struct inode *v9fs_qid_iget_dotl(struct super_block *sb, 988c2ecf20Sopenharmony_ci struct p9_qid *qid, 998c2ecf20Sopenharmony_ci struct p9_fid *fid, 1008c2ecf20Sopenharmony_ci struct p9_stat_dotl *st, 1018c2ecf20Sopenharmony_ci int new) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci int retval; 1048c2ecf20Sopenharmony_ci unsigned long i_ino; 1058c2ecf20Sopenharmony_ci struct inode *inode; 1068c2ecf20Sopenharmony_ci struct v9fs_session_info *v9ses = sb->s_fs_info; 1078c2ecf20Sopenharmony_ci int (*test)(struct inode *, void *); 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci if (new) 1108c2ecf20Sopenharmony_ci test = v9fs_test_new_inode_dotl; 1118c2ecf20Sopenharmony_ci else 1128c2ecf20Sopenharmony_ci test = v9fs_test_inode_dotl; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci i_ino = v9fs_qid2ino(qid); 1158c2ecf20Sopenharmony_ci inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st); 1168c2ecf20Sopenharmony_ci if (!inode) 1178c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 1188c2ecf20Sopenharmony_ci if (!(inode->i_state & I_NEW)) 1198c2ecf20Sopenharmony_ci return inode; 1208c2ecf20Sopenharmony_ci /* 1218c2ecf20Sopenharmony_ci * initialize the inode with the stat info 1228c2ecf20Sopenharmony_ci * FIXME!! we may need support for stale inodes 1238c2ecf20Sopenharmony_ci * later. 1248c2ecf20Sopenharmony_ci */ 1258c2ecf20Sopenharmony_ci inode->i_ino = i_ino; 1268c2ecf20Sopenharmony_ci retval = v9fs_init_inode(v9ses, inode, 1278c2ecf20Sopenharmony_ci st->st_mode, new_decode_dev(st->st_rdev)); 1288c2ecf20Sopenharmony_ci if (retval) 1298c2ecf20Sopenharmony_ci goto error; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci v9fs_stat2inode_dotl(st, inode, 0); 1328c2ecf20Sopenharmony_ci v9fs_cache_inode_get_cookie(inode); 1338c2ecf20Sopenharmony_ci retval = v9fs_get_acl(inode, fid); 1348c2ecf20Sopenharmony_ci if (retval) 1358c2ecf20Sopenharmony_ci goto error; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci unlock_new_inode(inode); 1388c2ecf20Sopenharmony_ci return inode; 1398c2ecf20Sopenharmony_cierror: 1408c2ecf20Sopenharmony_ci iget_failed(inode); 1418c2ecf20Sopenharmony_ci return ERR_PTR(retval); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_cistruct inode * 1468c2ecf20Sopenharmony_civ9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, 1478c2ecf20Sopenharmony_ci struct super_block *sb, int new) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci struct p9_stat_dotl *st; 1508c2ecf20Sopenharmony_ci struct inode *inode = NULL; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN); 1538c2ecf20Sopenharmony_ci if (IS_ERR(st)) 1548c2ecf20Sopenharmony_ci return ERR_CAST(st); 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new); 1578c2ecf20Sopenharmony_ci kfree(st); 1588c2ecf20Sopenharmony_ci return inode; 1598c2ecf20Sopenharmony_ci} 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistruct dotl_openflag_map { 1628c2ecf20Sopenharmony_ci int open_flag; 1638c2ecf20Sopenharmony_ci int dotl_flag; 1648c2ecf20Sopenharmony_ci}; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_cistatic int v9fs_mapped_dotl_flags(int flags) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci int i; 1698c2ecf20Sopenharmony_ci int rflags = 0; 1708c2ecf20Sopenharmony_ci struct dotl_openflag_map dotl_oflag_map[] = { 1718c2ecf20Sopenharmony_ci { O_CREAT, P9_DOTL_CREATE }, 1728c2ecf20Sopenharmony_ci { O_EXCL, P9_DOTL_EXCL }, 1738c2ecf20Sopenharmony_ci { O_NOCTTY, P9_DOTL_NOCTTY }, 1748c2ecf20Sopenharmony_ci { O_APPEND, P9_DOTL_APPEND }, 1758c2ecf20Sopenharmony_ci { O_NONBLOCK, P9_DOTL_NONBLOCK }, 1768c2ecf20Sopenharmony_ci { O_DSYNC, P9_DOTL_DSYNC }, 1778c2ecf20Sopenharmony_ci { FASYNC, P9_DOTL_FASYNC }, 1788c2ecf20Sopenharmony_ci { O_DIRECT, P9_DOTL_DIRECT }, 1798c2ecf20Sopenharmony_ci { O_LARGEFILE, P9_DOTL_LARGEFILE }, 1808c2ecf20Sopenharmony_ci { O_DIRECTORY, P9_DOTL_DIRECTORY }, 1818c2ecf20Sopenharmony_ci { O_NOFOLLOW, P9_DOTL_NOFOLLOW }, 1828c2ecf20Sopenharmony_ci { O_NOATIME, P9_DOTL_NOATIME }, 1838c2ecf20Sopenharmony_ci { O_CLOEXEC, P9_DOTL_CLOEXEC }, 1848c2ecf20Sopenharmony_ci { O_SYNC, P9_DOTL_SYNC}, 1858c2ecf20Sopenharmony_ci }; 1868c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) { 1878c2ecf20Sopenharmony_ci if (flags & dotl_oflag_map[i].open_flag) 1888c2ecf20Sopenharmony_ci rflags |= dotl_oflag_map[i].dotl_flag; 1898c2ecf20Sopenharmony_ci } 1908c2ecf20Sopenharmony_ci return rflags; 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci/** 1948c2ecf20Sopenharmony_ci * v9fs_open_to_dotl_flags- convert Linux specific open flags to 1958c2ecf20Sopenharmony_ci * plan 9 open flag. 1968c2ecf20Sopenharmony_ci * @flags: flags to convert 1978c2ecf20Sopenharmony_ci */ 1988c2ecf20Sopenharmony_ciint v9fs_open_to_dotl_flags(int flags) 1998c2ecf20Sopenharmony_ci{ 2008c2ecf20Sopenharmony_ci int rflags = 0; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci /* 2038c2ecf20Sopenharmony_ci * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY 2048c2ecf20Sopenharmony_ci * and P9_DOTL_NOACCESS 2058c2ecf20Sopenharmony_ci */ 2068c2ecf20Sopenharmony_ci rflags |= flags & O_ACCMODE; 2078c2ecf20Sopenharmony_ci rflags |= v9fs_mapped_dotl_flags(flags); 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci return rflags; 2108c2ecf20Sopenharmony_ci} 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci/** 2138c2ecf20Sopenharmony_ci * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol. 2148c2ecf20Sopenharmony_ci * @dir: directory inode that is being created 2158c2ecf20Sopenharmony_ci * @dentry: dentry that is being deleted 2168c2ecf20Sopenharmony_ci * @omode: create permissions 2178c2ecf20Sopenharmony_ci * 2188c2ecf20Sopenharmony_ci */ 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic int 2218c2ecf20Sopenharmony_civ9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, 2228c2ecf20Sopenharmony_ci bool excl) 2238c2ecf20Sopenharmony_ci{ 2248c2ecf20Sopenharmony_ci return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0); 2258c2ecf20Sopenharmony_ci} 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_cistatic int 2288c2ecf20Sopenharmony_civ9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, 2298c2ecf20Sopenharmony_ci struct file *file, unsigned flags, umode_t omode) 2308c2ecf20Sopenharmony_ci{ 2318c2ecf20Sopenharmony_ci int err = 0; 2328c2ecf20Sopenharmony_ci kgid_t gid; 2338c2ecf20Sopenharmony_ci umode_t mode; 2348c2ecf20Sopenharmony_ci const unsigned char *name = NULL; 2358c2ecf20Sopenharmony_ci struct p9_qid qid; 2368c2ecf20Sopenharmony_ci struct inode *inode; 2378c2ecf20Sopenharmony_ci struct p9_fid *fid = NULL; 2388c2ecf20Sopenharmony_ci struct v9fs_inode *v9inode; 2398c2ecf20Sopenharmony_ci struct p9_fid *dfid, *ofid, *inode_fid; 2408c2ecf20Sopenharmony_ci struct v9fs_session_info *v9ses; 2418c2ecf20Sopenharmony_ci struct posix_acl *pacl = NULL, *dacl = NULL; 2428c2ecf20Sopenharmony_ci struct dentry *res = NULL; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci if (d_in_lookup(dentry)) { 2458c2ecf20Sopenharmony_ci res = v9fs_vfs_lookup(dir, dentry, 0); 2468c2ecf20Sopenharmony_ci if (IS_ERR(res)) 2478c2ecf20Sopenharmony_ci return PTR_ERR(res); 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci if (res) 2508c2ecf20Sopenharmony_ci dentry = res; 2518c2ecf20Sopenharmony_ci } 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci /* Only creates */ 2548c2ecf20Sopenharmony_ci if (!(flags & O_CREAT) || d_really_is_positive(dentry)) 2558c2ecf20Sopenharmony_ci return finish_no_open(file, res); 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci v9ses = v9fs_inode2v9ses(dir); 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci name = dentry->d_name.name; 2608c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%hx\n", 2618c2ecf20Sopenharmony_ci name, flags, omode); 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci dfid = v9fs_parent_fid(dentry); 2648c2ecf20Sopenharmony_ci if (IS_ERR(dfid)) { 2658c2ecf20Sopenharmony_ci err = PTR_ERR(dfid); 2668c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 2678c2ecf20Sopenharmony_ci goto out; 2688c2ecf20Sopenharmony_ci } 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci /* clone a fid to use for creation */ 2718c2ecf20Sopenharmony_ci ofid = clone_fid(dfid); 2728c2ecf20Sopenharmony_ci if (IS_ERR(ofid)) { 2738c2ecf20Sopenharmony_ci err = PTR_ERR(ofid); 2748c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 2758c2ecf20Sopenharmony_ci goto out; 2768c2ecf20Sopenharmony_ci } 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci gid = v9fs_get_fsgid_for_create(dir); 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci mode = omode; 2818c2ecf20Sopenharmony_ci /* Update mode based on ACL value */ 2828c2ecf20Sopenharmony_ci err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); 2838c2ecf20Sopenharmony_ci if (err) { 2848c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d\n", 2858c2ecf20Sopenharmony_ci err); 2868c2ecf20Sopenharmony_ci goto error; 2878c2ecf20Sopenharmony_ci } 2888c2ecf20Sopenharmony_ci err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags), 2898c2ecf20Sopenharmony_ci mode, gid, &qid); 2908c2ecf20Sopenharmony_ci if (err < 0) { 2918c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d\n", 2928c2ecf20Sopenharmony_ci err); 2938c2ecf20Sopenharmony_ci goto error; 2948c2ecf20Sopenharmony_ci } 2958c2ecf20Sopenharmony_ci v9fs_invalidate_inode_attr(dir); 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci /* instantiate inode and assign the unopened fid to the dentry */ 2988c2ecf20Sopenharmony_ci fid = p9_client_walk(dfid, 1, &name, 1); 2998c2ecf20Sopenharmony_ci if (IS_ERR(fid)) { 3008c2ecf20Sopenharmony_ci err = PTR_ERR(fid); 3018c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 3028c2ecf20Sopenharmony_ci fid = NULL; 3038c2ecf20Sopenharmony_ci goto error; 3048c2ecf20Sopenharmony_ci } 3058c2ecf20Sopenharmony_ci inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 3068c2ecf20Sopenharmony_ci if (IS_ERR(inode)) { 3078c2ecf20Sopenharmony_ci err = PTR_ERR(inode); 3088c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err); 3098c2ecf20Sopenharmony_ci goto error; 3108c2ecf20Sopenharmony_ci } 3118c2ecf20Sopenharmony_ci /* Now set the ACL based on the default value */ 3128c2ecf20Sopenharmony_ci v9fs_set_create_acl(inode, fid, dacl, pacl); 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci v9fs_fid_add(dentry, fid); 3158c2ecf20Sopenharmony_ci d_instantiate(dentry, inode); 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci v9inode = V9FS_I(inode); 3188c2ecf20Sopenharmony_ci mutex_lock(&v9inode->v_mutex); 3198c2ecf20Sopenharmony_ci if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) && 3208c2ecf20Sopenharmony_ci !v9inode->writeback_fid && 3218c2ecf20Sopenharmony_ci ((flags & O_ACCMODE) != O_RDONLY)) { 3228c2ecf20Sopenharmony_ci /* 3238c2ecf20Sopenharmony_ci * clone a fid and add it to writeback_fid 3248c2ecf20Sopenharmony_ci * we do it during open time instead of 3258c2ecf20Sopenharmony_ci * page dirty time via write_begin/page_mkwrite 3268c2ecf20Sopenharmony_ci * because we want write after unlink usecase 3278c2ecf20Sopenharmony_ci * to work. 3288c2ecf20Sopenharmony_ci */ 3298c2ecf20Sopenharmony_ci inode_fid = v9fs_writeback_fid(dentry); 3308c2ecf20Sopenharmony_ci if (IS_ERR(inode_fid)) { 3318c2ecf20Sopenharmony_ci err = PTR_ERR(inode_fid); 3328c2ecf20Sopenharmony_ci mutex_unlock(&v9inode->v_mutex); 3338c2ecf20Sopenharmony_ci goto err_clunk_old_fid; 3348c2ecf20Sopenharmony_ci } 3358c2ecf20Sopenharmony_ci v9inode->writeback_fid = (void *) inode_fid; 3368c2ecf20Sopenharmony_ci } 3378c2ecf20Sopenharmony_ci mutex_unlock(&v9inode->v_mutex); 3388c2ecf20Sopenharmony_ci /* Since we are opening a file, assign the open fid to the file */ 3398c2ecf20Sopenharmony_ci err = finish_open(file, dentry, generic_file_open); 3408c2ecf20Sopenharmony_ci if (err) 3418c2ecf20Sopenharmony_ci goto err_clunk_old_fid; 3428c2ecf20Sopenharmony_ci file->private_data = ofid; 3438c2ecf20Sopenharmony_ci if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) 3448c2ecf20Sopenharmony_ci v9fs_cache_inode_set_cookie(inode, file); 3458c2ecf20Sopenharmony_ci file->f_mode |= FMODE_CREATED; 3468c2ecf20Sopenharmony_ciout: 3478c2ecf20Sopenharmony_ci v9fs_put_acl(dacl, pacl); 3488c2ecf20Sopenharmony_ci dput(res); 3498c2ecf20Sopenharmony_ci return err; 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_cierror: 3528c2ecf20Sopenharmony_ci if (fid) 3538c2ecf20Sopenharmony_ci p9_client_clunk(fid); 3548c2ecf20Sopenharmony_cierr_clunk_old_fid: 3558c2ecf20Sopenharmony_ci if (ofid) 3568c2ecf20Sopenharmony_ci p9_client_clunk(ofid); 3578c2ecf20Sopenharmony_ci goto out; 3588c2ecf20Sopenharmony_ci} 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci/** 3618c2ecf20Sopenharmony_ci * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory 3628c2ecf20Sopenharmony_ci * @dir: inode that is being unlinked 3638c2ecf20Sopenharmony_ci * @dentry: dentry that is being unlinked 3648c2ecf20Sopenharmony_ci * @omode: mode for new directory 3658c2ecf20Sopenharmony_ci * 3668c2ecf20Sopenharmony_ci */ 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_cistatic int v9fs_vfs_mkdir_dotl(struct inode *dir, 3698c2ecf20Sopenharmony_ci struct dentry *dentry, umode_t omode) 3708c2ecf20Sopenharmony_ci{ 3718c2ecf20Sopenharmony_ci int err; 3728c2ecf20Sopenharmony_ci struct v9fs_session_info *v9ses; 3738c2ecf20Sopenharmony_ci struct p9_fid *fid = NULL, *dfid = NULL; 3748c2ecf20Sopenharmony_ci kgid_t gid; 3758c2ecf20Sopenharmony_ci const unsigned char *name; 3768c2ecf20Sopenharmony_ci umode_t mode; 3778c2ecf20Sopenharmony_ci struct inode *inode; 3788c2ecf20Sopenharmony_ci struct p9_qid qid; 3798c2ecf20Sopenharmony_ci struct posix_acl *dacl = NULL, *pacl = NULL; 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry); 3828c2ecf20Sopenharmony_ci err = 0; 3838c2ecf20Sopenharmony_ci v9ses = v9fs_inode2v9ses(dir); 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci omode |= S_IFDIR; 3868c2ecf20Sopenharmony_ci if (dir->i_mode & S_ISGID) 3878c2ecf20Sopenharmony_ci omode |= S_ISGID; 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci dfid = v9fs_parent_fid(dentry); 3908c2ecf20Sopenharmony_ci if (IS_ERR(dfid)) { 3918c2ecf20Sopenharmony_ci err = PTR_ERR(dfid); 3928c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 3938c2ecf20Sopenharmony_ci dfid = NULL; 3948c2ecf20Sopenharmony_ci goto error; 3958c2ecf20Sopenharmony_ci } 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci gid = v9fs_get_fsgid_for_create(dir); 3988c2ecf20Sopenharmony_ci mode = omode; 3998c2ecf20Sopenharmony_ci /* Update mode based on ACL value */ 4008c2ecf20Sopenharmony_ci err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); 4018c2ecf20Sopenharmony_ci if (err) { 4028c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mkdir %d\n", 4038c2ecf20Sopenharmony_ci err); 4048c2ecf20Sopenharmony_ci goto error; 4058c2ecf20Sopenharmony_ci } 4068c2ecf20Sopenharmony_ci name = dentry->d_name.name; 4078c2ecf20Sopenharmony_ci err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid); 4088c2ecf20Sopenharmony_ci if (err < 0) 4098c2ecf20Sopenharmony_ci goto error; 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci fid = p9_client_walk(dfid, 1, &name, 1); 4128c2ecf20Sopenharmony_ci if (IS_ERR(fid)) { 4138c2ecf20Sopenharmony_ci err = PTR_ERR(fid); 4148c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 4158c2ecf20Sopenharmony_ci err); 4168c2ecf20Sopenharmony_ci fid = NULL; 4178c2ecf20Sopenharmony_ci goto error; 4188c2ecf20Sopenharmony_ci } 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci /* instantiate inode and assign the unopened fid to the dentry */ 4218c2ecf20Sopenharmony_ci if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 4228c2ecf20Sopenharmony_ci inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 4238c2ecf20Sopenharmony_ci if (IS_ERR(inode)) { 4248c2ecf20Sopenharmony_ci err = PTR_ERR(inode); 4258c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", 4268c2ecf20Sopenharmony_ci err); 4278c2ecf20Sopenharmony_ci goto error; 4288c2ecf20Sopenharmony_ci } 4298c2ecf20Sopenharmony_ci v9fs_fid_add(dentry, fid); 4308c2ecf20Sopenharmony_ci v9fs_set_create_acl(inode, fid, dacl, pacl); 4318c2ecf20Sopenharmony_ci d_instantiate(dentry, inode); 4328c2ecf20Sopenharmony_ci fid = NULL; 4338c2ecf20Sopenharmony_ci err = 0; 4348c2ecf20Sopenharmony_ci } else { 4358c2ecf20Sopenharmony_ci /* 4368c2ecf20Sopenharmony_ci * Not in cached mode. No need to populate 4378c2ecf20Sopenharmony_ci * inode with stat. We need to get an inode 4388c2ecf20Sopenharmony_ci * so that we can set the acl with dentry 4398c2ecf20Sopenharmony_ci */ 4408c2ecf20Sopenharmony_ci inode = v9fs_get_inode(dir->i_sb, mode, 0); 4418c2ecf20Sopenharmony_ci if (IS_ERR(inode)) { 4428c2ecf20Sopenharmony_ci err = PTR_ERR(inode); 4438c2ecf20Sopenharmony_ci goto error; 4448c2ecf20Sopenharmony_ci } 4458c2ecf20Sopenharmony_ci v9fs_set_create_acl(inode, fid, dacl, pacl); 4468c2ecf20Sopenharmony_ci d_instantiate(dentry, inode); 4478c2ecf20Sopenharmony_ci } 4488c2ecf20Sopenharmony_ci inc_nlink(dir); 4498c2ecf20Sopenharmony_ci v9fs_invalidate_inode_attr(dir); 4508c2ecf20Sopenharmony_cierror: 4518c2ecf20Sopenharmony_ci if (fid) 4528c2ecf20Sopenharmony_ci p9_client_clunk(fid); 4538c2ecf20Sopenharmony_ci v9fs_put_acl(dacl, pacl); 4548c2ecf20Sopenharmony_ci return err; 4558c2ecf20Sopenharmony_ci} 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_cistatic int 4588c2ecf20Sopenharmony_civ9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat, 4598c2ecf20Sopenharmony_ci u32 request_mask, unsigned int flags) 4608c2ecf20Sopenharmony_ci{ 4618c2ecf20Sopenharmony_ci struct dentry *dentry = path->dentry; 4628c2ecf20Sopenharmony_ci struct v9fs_session_info *v9ses; 4638c2ecf20Sopenharmony_ci struct p9_fid *fid; 4648c2ecf20Sopenharmony_ci struct p9_stat_dotl *st; 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry); 4678c2ecf20Sopenharmony_ci v9ses = v9fs_dentry2v9ses(dentry); 4688c2ecf20Sopenharmony_ci if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 4698c2ecf20Sopenharmony_ci generic_fillattr(d_inode(dentry), stat); 4708c2ecf20Sopenharmony_ci return 0; 4718c2ecf20Sopenharmony_ci } 4728c2ecf20Sopenharmony_ci fid = v9fs_fid_lookup(dentry); 4738c2ecf20Sopenharmony_ci if (IS_ERR(fid)) 4748c2ecf20Sopenharmony_ci return PTR_ERR(fid); 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci /* Ask for all the fields in stat structure. Server will return 4778c2ecf20Sopenharmony_ci * whatever it supports 4788c2ecf20Sopenharmony_ci */ 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci st = p9_client_getattr_dotl(fid, P9_STATS_ALL); 4818c2ecf20Sopenharmony_ci if (IS_ERR(st)) 4828c2ecf20Sopenharmony_ci return PTR_ERR(st); 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci v9fs_stat2inode_dotl(st, d_inode(dentry), 0); 4858c2ecf20Sopenharmony_ci generic_fillattr(d_inode(dentry), stat); 4868c2ecf20Sopenharmony_ci /* Change block size to what the server returned */ 4878c2ecf20Sopenharmony_ci stat->blksize = st->st_blksize; 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci kfree(st); 4908c2ecf20Sopenharmony_ci return 0; 4918c2ecf20Sopenharmony_ci} 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci/* 4948c2ecf20Sopenharmony_ci * Attribute flags. 4958c2ecf20Sopenharmony_ci */ 4968c2ecf20Sopenharmony_ci#define P9_ATTR_MODE (1 << 0) 4978c2ecf20Sopenharmony_ci#define P9_ATTR_UID (1 << 1) 4988c2ecf20Sopenharmony_ci#define P9_ATTR_GID (1 << 2) 4998c2ecf20Sopenharmony_ci#define P9_ATTR_SIZE (1 << 3) 5008c2ecf20Sopenharmony_ci#define P9_ATTR_ATIME (1 << 4) 5018c2ecf20Sopenharmony_ci#define P9_ATTR_MTIME (1 << 5) 5028c2ecf20Sopenharmony_ci#define P9_ATTR_CTIME (1 << 6) 5038c2ecf20Sopenharmony_ci#define P9_ATTR_ATIME_SET (1 << 7) 5048c2ecf20Sopenharmony_ci#define P9_ATTR_MTIME_SET (1 << 8) 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_cistruct dotl_iattr_map { 5078c2ecf20Sopenharmony_ci int iattr_valid; 5088c2ecf20Sopenharmony_ci int p9_iattr_valid; 5098c2ecf20Sopenharmony_ci}; 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_cistatic int v9fs_mapped_iattr_valid(int iattr_valid) 5128c2ecf20Sopenharmony_ci{ 5138c2ecf20Sopenharmony_ci int i; 5148c2ecf20Sopenharmony_ci int p9_iattr_valid = 0; 5158c2ecf20Sopenharmony_ci struct dotl_iattr_map dotl_iattr_map[] = { 5168c2ecf20Sopenharmony_ci { ATTR_MODE, P9_ATTR_MODE }, 5178c2ecf20Sopenharmony_ci { ATTR_UID, P9_ATTR_UID }, 5188c2ecf20Sopenharmony_ci { ATTR_GID, P9_ATTR_GID }, 5198c2ecf20Sopenharmony_ci { ATTR_SIZE, P9_ATTR_SIZE }, 5208c2ecf20Sopenharmony_ci { ATTR_ATIME, P9_ATTR_ATIME }, 5218c2ecf20Sopenharmony_ci { ATTR_MTIME, P9_ATTR_MTIME }, 5228c2ecf20Sopenharmony_ci { ATTR_CTIME, P9_ATTR_CTIME }, 5238c2ecf20Sopenharmony_ci { ATTR_ATIME_SET, P9_ATTR_ATIME_SET }, 5248c2ecf20Sopenharmony_ci { ATTR_MTIME_SET, P9_ATTR_MTIME_SET }, 5258c2ecf20Sopenharmony_ci }; 5268c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(dotl_iattr_map); i++) { 5278c2ecf20Sopenharmony_ci if (iattr_valid & dotl_iattr_map[i].iattr_valid) 5288c2ecf20Sopenharmony_ci p9_iattr_valid |= dotl_iattr_map[i].p9_iattr_valid; 5298c2ecf20Sopenharmony_ci } 5308c2ecf20Sopenharmony_ci return p9_iattr_valid; 5318c2ecf20Sopenharmony_ci} 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci/** 5348c2ecf20Sopenharmony_ci * v9fs_vfs_setattr_dotl - set file metadata 5358c2ecf20Sopenharmony_ci * @dentry: file whose metadata to set 5368c2ecf20Sopenharmony_ci * @iattr: metadata assignment structure 5378c2ecf20Sopenharmony_ci * 5388c2ecf20Sopenharmony_ci */ 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ciint v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr) 5418c2ecf20Sopenharmony_ci{ 5428c2ecf20Sopenharmony_ci int retval; 5438c2ecf20Sopenharmony_ci struct p9_fid *fid = NULL; 5448c2ecf20Sopenharmony_ci struct p9_iattr_dotl p9attr = { 5458c2ecf20Sopenharmony_ci .uid = INVALID_UID, 5468c2ecf20Sopenharmony_ci .gid = INVALID_GID, 5478c2ecf20Sopenharmony_ci }; 5488c2ecf20Sopenharmony_ci struct inode *inode = d_inode(dentry); 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "\n"); 5518c2ecf20Sopenharmony_ci 5528c2ecf20Sopenharmony_ci retval = setattr_prepare(dentry, iattr); 5538c2ecf20Sopenharmony_ci if (retval) 5548c2ecf20Sopenharmony_ci return retval; 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_ci p9attr.valid = v9fs_mapped_iattr_valid(iattr->ia_valid); 5578c2ecf20Sopenharmony_ci if (iattr->ia_valid & ATTR_MODE) 5588c2ecf20Sopenharmony_ci p9attr.mode = iattr->ia_mode; 5598c2ecf20Sopenharmony_ci if (iattr->ia_valid & ATTR_UID) 5608c2ecf20Sopenharmony_ci p9attr.uid = iattr->ia_uid; 5618c2ecf20Sopenharmony_ci if (iattr->ia_valid & ATTR_GID) 5628c2ecf20Sopenharmony_ci p9attr.gid = iattr->ia_gid; 5638c2ecf20Sopenharmony_ci if (iattr->ia_valid & ATTR_SIZE) 5648c2ecf20Sopenharmony_ci p9attr.size = iattr->ia_size; 5658c2ecf20Sopenharmony_ci if (iattr->ia_valid & ATTR_ATIME_SET) { 5668c2ecf20Sopenharmony_ci p9attr.atime_sec = iattr->ia_atime.tv_sec; 5678c2ecf20Sopenharmony_ci p9attr.atime_nsec = iattr->ia_atime.tv_nsec; 5688c2ecf20Sopenharmony_ci } 5698c2ecf20Sopenharmony_ci if (iattr->ia_valid & ATTR_MTIME_SET) { 5708c2ecf20Sopenharmony_ci p9attr.mtime_sec = iattr->ia_mtime.tv_sec; 5718c2ecf20Sopenharmony_ci p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec; 5728c2ecf20Sopenharmony_ci } 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci if (iattr->ia_valid & ATTR_FILE) { 5758c2ecf20Sopenharmony_ci fid = iattr->ia_file->private_data; 5768c2ecf20Sopenharmony_ci WARN_ON(!fid); 5778c2ecf20Sopenharmony_ci } 5788c2ecf20Sopenharmony_ci if (!fid) 5798c2ecf20Sopenharmony_ci fid = v9fs_fid_lookup(dentry); 5808c2ecf20Sopenharmony_ci if (IS_ERR(fid)) 5818c2ecf20Sopenharmony_ci return PTR_ERR(fid); 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_ci /* Write all dirty data */ 5848c2ecf20Sopenharmony_ci if (S_ISREG(inode->i_mode)) 5858c2ecf20Sopenharmony_ci filemap_write_and_wait(inode->i_mapping); 5868c2ecf20Sopenharmony_ci 5878c2ecf20Sopenharmony_ci retval = p9_client_setattr(fid, &p9attr); 5888c2ecf20Sopenharmony_ci if (retval < 0) 5898c2ecf20Sopenharmony_ci return retval; 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci if ((iattr->ia_valid & ATTR_SIZE) && 5928c2ecf20Sopenharmony_ci iattr->ia_size != i_size_read(inode)) 5938c2ecf20Sopenharmony_ci truncate_setsize(inode, iattr->ia_size); 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_ci v9fs_invalidate_inode_attr(inode); 5968c2ecf20Sopenharmony_ci setattr_copy(inode, iattr); 5978c2ecf20Sopenharmony_ci mark_inode_dirty(inode); 5988c2ecf20Sopenharmony_ci if (iattr->ia_valid & ATTR_MODE) { 5998c2ecf20Sopenharmony_ci /* We also want to update ACL when we update mode bits */ 6008c2ecf20Sopenharmony_ci retval = v9fs_acl_chmod(inode, fid); 6018c2ecf20Sopenharmony_ci if (retval < 0) 6028c2ecf20Sopenharmony_ci return retval; 6038c2ecf20Sopenharmony_ci } 6048c2ecf20Sopenharmony_ci return 0; 6058c2ecf20Sopenharmony_ci} 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci/** 6088c2ecf20Sopenharmony_ci * v9fs_stat2inode_dotl - populate an inode structure with stat info 6098c2ecf20Sopenharmony_ci * @stat: stat structure 6108c2ecf20Sopenharmony_ci * @inode: inode to populate 6118c2ecf20Sopenharmony_ci * @flags: ctrl flags (e.g. V9FS_STAT2INODE_KEEP_ISIZE) 6128c2ecf20Sopenharmony_ci * 6138c2ecf20Sopenharmony_ci */ 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_civoid 6168c2ecf20Sopenharmony_civ9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode, 6178c2ecf20Sopenharmony_ci unsigned int flags) 6188c2ecf20Sopenharmony_ci{ 6198c2ecf20Sopenharmony_ci umode_t mode; 6208c2ecf20Sopenharmony_ci struct v9fs_inode *v9inode = V9FS_I(inode); 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_ci if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) { 6238c2ecf20Sopenharmony_ci inode->i_atime.tv_sec = stat->st_atime_sec; 6248c2ecf20Sopenharmony_ci inode->i_atime.tv_nsec = stat->st_atime_nsec; 6258c2ecf20Sopenharmony_ci inode->i_mtime.tv_sec = stat->st_mtime_sec; 6268c2ecf20Sopenharmony_ci inode->i_mtime.tv_nsec = stat->st_mtime_nsec; 6278c2ecf20Sopenharmony_ci inode->i_ctime.tv_sec = stat->st_ctime_sec; 6288c2ecf20Sopenharmony_ci inode->i_ctime.tv_nsec = stat->st_ctime_nsec; 6298c2ecf20Sopenharmony_ci inode->i_uid = stat->st_uid; 6308c2ecf20Sopenharmony_ci inode->i_gid = stat->st_gid; 6318c2ecf20Sopenharmony_ci set_nlink(inode, stat->st_nlink); 6328c2ecf20Sopenharmony_ci 6338c2ecf20Sopenharmony_ci mode = stat->st_mode & S_IALLUGO; 6348c2ecf20Sopenharmony_ci mode |= inode->i_mode & ~S_IALLUGO; 6358c2ecf20Sopenharmony_ci inode->i_mode = mode; 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE)) 6388c2ecf20Sopenharmony_ci v9fs_i_size_write(inode, stat->st_size); 6398c2ecf20Sopenharmony_ci inode->i_blocks = stat->st_blocks; 6408c2ecf20Sopenharmony_ci } else { 6418c2ecf20Sopenharmony_ci if (stat->st_result_mask & P9_STATS_ATIME) { 6428c2ecf20Sopenharmony_ci inode->i_atime.tv_sec = stat->st_atime_sec; 6438c2ecf20Sopenharmony_ci inode->i_atime.tv_nsec = stat->st_atime_nsec; 6448c2ecf20Sopenharmony_ci } 6458c2ecf20Sopenharmony_ci if (stat->st_result_mask & P9_STATS_MTIME) { 6468c2ecf20Sopenharmony_ci inode->i_mtime.tv_sec = stat->st_mtime_sec; 6478c2ecf20Sopenharmony_ci inode->i_mtime.tv_nsec = stat->st_mtime_nsec; 6488c2ecf20Sopenharmony_ci } 6498c2ecf20Sopenharmony_ci if (stat->st_result_mask & P9_STATS_CTIME) { 6508c2ecf20Sopenharmony_ci inode->i_ctime.tv_sec = stat->st_ctime_sec; 6518c2ecf20Sopenharmony_ci inode->i_ctime.tv_nsec = stat->st_ctime_nsec; 6528c2ecf20Sopenharmony_ci } 6538c2ecf20Sopenharmony_ci if (stat->st_result_mask & P9_STATS_UID) 6548c2ecf20Sopenharmony_ci inode->i_uid = stat->st_uid; 6558c2ecf20Sopenharmony_ci if (stat->st_result_mask & P9_STATS_GID) 6568c2ecf20Sopenharmony_ci inode->i_gid = stat->st_gid; 6578c2ecf20Sopenharmony_ci if (stat->st_result_mask & P9_STATS_NLINK) 6588c2ecf20Sopenharmony_ci set_nlink(inode, stat->st_nlink); 6598c2ecf20Sopenharmony_ci if (stat->st_result_mask & P9_STATS_MODE) { 6608c2ecf20Sopenharmony_ci mode = stat->st_mode & S_IALLUGO; 6618c2ecf20Sopenharmony_ci mode |= inode->i_mode & ~S_IALLUGO; 6628c2ecf20Sopenharmony_ci inode->i_mode = mode; 6638c2ecf20Sopenharmony_ci } 6648c2ecf20Sopenharmony_ci if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE) && 6658c2ecf20Sopenharmony_ci stat->st_result_mask & P9_STATS_SIZE) 6668c2ecf20Sopenharmony_ci v9fs_i_size_write(inode, stat->st_size); 6678c2ecf20Sopenharmony_ci if (stat->st_result_mask & P9_STATS_BLOCKS) 6688c2ecf20Sopenharmony_ci inode->i_blocks = stat->st_blocks; 6698c2ecf20Sopenharmony_ci } 6708c2ecf20Sopenharmony_ci if (stat->st_result_mask & P9_STATS_GEN) 6718c2ecf20Sopenharmony_ci inode->i_generation = stat->st_gen; 6728c2ecf20Sopenharmony_ci 6738c2ecf20Sopenharmony_ci /* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION 6748c2ecf20Sopenharmony_ci * because the inode structure does not have fields for them. 6758c2ecf20Sopenharmony_ci */ 6768c2ecf20Sopenharmony_ci v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR; 6778c2ecf20Sopenharmony_ci} 6788c2ecf20Sopenharmony_ci 6798c2ecf20Sopenharmony_cistatic int 6808c2ecf20Sopenharmony_civ9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry, 6818c2ecf20Sopenharmony_ci const char *symname) 6828c2ecf20Sopenharmony_ci{ 6838c2ecf20Sopenharmony_ci int err; 6848c2ecf20Sopenharmony_ci kgid_t gid; 6858c2ecf20Sopenharmony_ci const unsigned char *name; 6868c2ecf20Sopenharmony_ci struct p9_qid qid; 6878c2ecf20Sopenharmony_ci struct inode *inode; 6888c2ecf20Sopenharmony_ci struct p9_fid *dfid; 6898c2ecf20Sopenharmony_ci struct p9_fid *fid = NULL; 6908c2ecf20Sopenharmony_ci struct v9fs_session_info *v9ses; 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci name = dentry->d_name.name; 6938c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "%lu,%s,%s\n", dir->i_ino, name, symname); 6948c2ecf20Sopenharmony_ci v9ses = v9fs_inode2v9ses(dir); 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci dfid = v9fs_parent_fid(dentry); 6978c2ecf20Sopenharmony_ci if (IS_ERR(dfid)) { 6988c2ecf20Sopenharmony_ci err = PTR_ERR(dfid); 6998c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 7008c2ecf20Sopenharmony_ci return err; 7018c2ecf20Sopenharmony_ci } 7028c2ecf20Sopenharmony_ci 7038c2ecf20Sopenharmony_ci gid = v9fs_get_fsgid_for_create(dir); 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci /* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */ 7068c2ecf20Sopenharmony_ci err = p9_client_symlink(dfid, name, symname, gid, &qid); 7078c2ecf20Sopenharmony_ci 7088c2ecf20Sopenharmony_ci if (err < 0) { 7098c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err); 7108c2ecf20Sopenharmony_ci goto error; 7118c2ecf20Sopenharmony_ci } 7128c2ecf20Sopenharmony_ci 7138c2ecf20Sopenharmony_ci v9fs_invalidate_inode_attr(dir); 7148c2ecf20Sopenharmony_ci if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 7158c2ecf20Sopenharmony_ci /* Now walk from the parent so we can get an unopened fid. */ 7168c2ecf20Sopenharmony_ci fid = p9_client_walk(dfid, 1, &name, 1); 7178c2ecf20Sopenharmony_ci if (IS_ERR(fid)) { 7188c2ecf20Sopenharmony_ci err = PTR_ERR(fid); 7198c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 7208c2ecf20Sopenharmony_ci err); 7218c2ecf20Sopenharmony_ci fid = NULL; 7228c2ecf20Sopenharmony_ci goto error; 7238c2ecf20Sopenharmony_ci } 7248c2ecf20Sopenharmony_ci 7258c2ecf20Sopenharmony_ci /* instantiate inode and assign the unopened fid to dentry */ 7268c2ecf20Sopenharmony_ci inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 7278c2ecf20Sopenharmony_ci if (IS_ERR(inode)) { 7288c2ecf20Sopenharmony_ci err = PTR_ERR(inode); 7298c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", 7308c2ecf20Sopenharmony_ci err); 7318c2ecf20Sopenharmony_ci goto error; 7328c2ecf20Sopenharmony_ci } 7338c2ecf20Sopenharmony_ci v9fs_fid_add(dentry, fid); 7348c2ecf20Sopenharmony_ci d_instantiate(dentry, inode); 7358c2ecf20Sopenharmony_ci fid = NULL; 7368c2ecf20Sopenharmony_ci err = 0; 7378c2ecf20Sopenharmony_ci } else { 7388c2ecf20Sopenharmony_ci /* Not in cached mode. No need to populate inode with stat */ 7398c2ecf20Sopenharmony_ci inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0); 7408c2ecf20Sopenharmony_ci if (IS_ERR(inode)) { 7418c2ecf20Sopenharmony_ci err = PTR_ERR(inode); 7428c2ecf20Sopenharmony_ci goto error; 7438c2ecf20Sopenharmony_ci } 7448c2ecf20Sopenharmony_ci d_instantiate(dentry, inode); 7458c2ecf20Sopenharmony_ci } 7468c2ecf20Sopenharmony_ci 7478c2ecf20Sopenharmony_cierror: 7488c2ecf20Sopenharmony_ci if (fid) 7498c2ecf20Sopenharmony_ci p9_client_clunk(fid); 7508c2ecf20Sopenharmony_ci 7518c2ecf20Sopenharmony_ci return err; 7528c2ecf20Sopenharmony_ci} 7538c2ecf20Sopenharmony_ci 7548c2ecf20Sopenharmony_ci/** 7558c2ecf20Sopenharmony_ci * v9fs_vfs_link_dotl - create a hardlink for dotl 7568c2ecf20Sopenharmony_ci * @old_dentry: dentry for file to link to 7578c2ecf20Sopenharmony_ci * @dir: inode destination for new link 7588c2ecf20Sopenharmony_ci * @dentry: dentry for link 7598c2ecf20Sopenharmony_ci * 7608c2ecf20Sopenharmony_ci */ 7618c2ecf20Sopenharmony_ci 7628c2ecf20Sopenharmony_cistatic int 7638c2ecf20Sopenharmony_civ9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir, 7648c2ecf20Sopenharmony_ci struct dentry *dentry) 7658c2ecf20Sopenharmony_ci{ 7668c2ecf20Sopenharmony_ci int err; 7678c2ecf20Sopenharmony_ci struct p9_fid *dfid, *oldfid; 7688c2ecf20Sopenharmony_ci struct v9fs_session_info *v9ses; 7698c2ecf20Sopenharmony_ci 7708c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "dir ino: %lu, old_name: %pd, new_name: %pd\n", 7718c2ecf20Sopenharmony_ci dir->i_ino, old_dentry, dentry); 7728c2ecf20Sopenharmony_ci 7738c2ecf20Sopenharmony_ci v9ses = v9fs_inode2v9ses(dir); 7748c2ecf20Sopenharmony_ci dfid = v9fs_parent_fid(dentry); 7758c2ecf20Sopenharmony_ci if (IS_ERR(dfid)) 7768c2ecf20Sopenharmony_ci return PTR_ERR(dfid); 7778c2ecf20Sopenharmony_ci 7788c2ecf20Sopenharmony_ci oldfid = v9fs_fid_lookup(old_dentry); 7798c2ecf20Sopenharmony_ci if (IS_ERR(oldfid)) 7808c2ecf20Sopenharmony_ci return PTR_ERR(oldfid); 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_ci err = p9_client_link(dfid, oldfid, dentry->d_name.name); 7838c2ecf20Sopenharmony_ci 7848c2ecf20Sopenharmony_ci if (err < 0) { 7858c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "p9_client_link failed %d\n", err); 7868c2ecf20Sopenharmony_ci return err; 7878c2ecf20Sopenharmony_ci } 7888c2ecf20Sopenharmony_ci 7898c2ecf20Sopenharmony_ci v9fs_invalidate_inode_attr(dir); 7908c2ecf20Sopenharmony_ci if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 7918c2ecf20Sopenharmony_ci /* Get the latest stat info from server. */ 7928c2ecf20Sopenharmony_ci struct p9_fid *fid; 7938c2ecf20Sopenharmony_ci fid = v9fs_fid_lookup(old_dentry); 7948c2ecf20Sopenharmony_ci if (IS_ERR(fid)) 7958c2ecf20Sopenharmony_ci return PTR_ERR(fid); 7968c2ecf20Sopenharmony_ci 7978c2ecf20Sopenharmony_ci v9fs_refresh_inode_dotl(fid, d_inode(old_dentry)); 7988c2ecf20Sopenharmony_ci } 7998c2ecf20Sopenharmony_ci ihold(d_inode(old_dentry)); 8008c2ecf20Sopenharmony_ci d_instantiate(dentry, d_inode(old_dentry)); 8018c2ecf20Sopenharmony_ci 8028c2ecf20Sopenharmony_ci return err; 8038c2ecf20Sopenharmony_ci} 8048c2ecf20Sopenharmony_ci 8058c2ecf20Sopenharmony_ci/** 8068c2ecf20Sopenharmony_ci * v9fs_vfs_mknod_dotl - create a special file 8078c2ecf20Sopenharmony_ci * @dir: inode destination for new link 8088c2ecf20Sopenharmony_ci * @dentry: dentry for file 8098c2ecf20Sopenharmony_ci * @omode: mode for creation 8108c2ecf20Sopenharmony_ci * @rdev: device associated with special file 8118c2ecf20Sopenharmony_ci * 8128c2ecf20Sopenharmony_ci */ 8138c2ecf20Sopenharmony_cistatic int 8148c2ecf20Sopenharmony_civ9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, 8158c2ecf20Sopenharmony_ci dev_t rdev) 8168c2ecf20Sopenharmony_ci{ 8178c2ecf20Sopenharmony_ci int err; 8188c2ecf20Sopenharmony_ci kgid_t gid; 8198c2ecf20Sopenharmony_ci const unsigned char *name; 8208c2ecf20Sopenharmony_ci umode_t mode; 8218c2ecf20Sopenharmony_ci struct v9fs_session_info *v9ses; 8228c2ecf20Sopenharmony_ci struct p9_fid *fid = NULL, *dfid = NULL; 8238c2ecf20Sopenharmony_ci struct inode *inode; 8248c2ecf20Sopenharmony_ci struct p9_qid qid; 8258c2ecf20Sopenharmony_ci struct posix_acl *dacl = NULL, *pacl = NULL; 8268c2ecf20Sopenharmony_ci 8278c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %hx MAJOR: %u MINOR: %u\n", 8288c2ecf20Sopenharmony_ci dir->i_ino, dentry, omode, 8298c2ecf20Sopenharmony_ci MAJOR(rdev), MINOR(rdev)); 8308c2ecf20Sopenharmony_ci 8318c2ecf20Sopenharmony_ci v9ses = v9fs_inode2v9ses(dir); 8328c2ecf20Sopenharmony_ci dfid = v9fs_parent_fid(dentry); 8338c2ecf20Sopenharmony_ci if (IS_ERR(dfid)) { 8348c2ecf20Sopenharmony_ci err = PTR_ERR(dfid); 8358c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 8368c2ecf20Sopenharmony_ci dfid = NULL; 8378c2ecf20Sopenharmony_ci goto error; 8388c2ecf20Sopenharmony_ci } 8398c2ecf20Sopenharmony_ci 8408c2ecf20Sopenharmony_ci gid = v9fs_get_fsgid_for_create(dir); 8418c2ecf20Sopenharmony_ci mode = omode; 8428c2ecf20Sopenharmony_ci /* Update mode based on ACL value */ 8438c2ecf20Sopenharmony_ci err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); 8448c2ecf20Sopenharmony_ci if (err) { 8458c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mknod %d\n", 8468c2ecf20Sopenharmony_ci err); 8478c2ecf20Sopenharmony_ci goto error; 8488c2ecf20Sopenharmony_ci } 8498c2ecf20Sopenharmony_ci name = dentry->d_name.name; 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_ci err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid); 8528c2ecf20Sopenharmony_ci if (err < 0) 8538c2ecf20Sopenharmony_ci goto error; 8548c2ecf20Sopenharmony_ci 8558c2ecf20Sopenharmony_ci v9fs_invalidate_inode_attr(dir); 8568c2ecf20Sopenharmony_ci fid = p9_client_walk(dfid, 1, &name, 1); 8578c2ecf20Sopenharmony_ci if (IS_ERR(fid)) { 8588c2ecf20Sopenharmony_ci err = PTR_ERR(fid); 8598c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", 8608c2ecf20Sopenharmony_ci err); 8618c2ecf20Sopenharmony_ci fid = NULL; 8628c2ecf20Sopenharmony_ci goto error; 8638c2ecf20Sopenharmony_ci } 8648c2ecf20Sopenharmony_ci 8658c2ecf20Sopenharmony_ci /* instantiate inode and assign the unopened fid to the dentry */ 8668c2ecf20Sopenharmony_ci if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) { 8678c2ecf20Sopenharmony_ci inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); 8688c2ecf20Sopenharmony_ci if (IS_ERR(inode)) { 8698c2ecf20Sopenharmony_ci err = PTR_ERR(inode); 8708c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", 8718c2ecf20Sopenharmony_ci err); 8728c2ecf20Sopenharmony_ci goto error; 8738c2ecf20Sopenharmony_ci } 8748c2ecf20Sopenharmony_ci v9fs_set_create_acl(inode, fid, dacl, pacl); 8758c2ecf20Sopenharmony_ci v9fs_fid_add(dentry, fid); 8768c2ecf20Sopenharmony_ci d_instantiate(dentry, inode); 8778c2ecf20Sopenharmony_ci fid = NULL; 8788c2ecf20Sopenharmony_ci err = 0; 8798c2ecf20Sopenharmony_ci } else { 8808c2ecf20Sopenharmony_ci /* 8818c2ecf20Sopenharmony_ci * Not in cached mode. No need to populate inode with stat. 8828c2ecf20Sopenharmony_ci * socket syscall returns a fd, so we need instantiate 8838c2ecf20Sopenharmony_ci */ 8848c2ecf20Sopenharmony_ci inode = v9fs_get_inode(dir->i_sb, mode, rdev); 8858c2ecf20Sopenharmony_ci if (IS_ERR(inode)) { 8868c2ecf20Sopenharmony_ci err = PTR_ERR(inode); 8878c2ecf20Sopenharmony_ci goto error; 8888c2ecf20Sopenharmony_ci } 8898c2ecf20Sopenharmony_ci v9fs_set_create_acl(inode, fid, dacl, pacl); 8908c2ecf20Sopenharmony_ci d_instantiate(dentry, inode); 8918c2ecf20Sopenharmony_ci } 8928c2ecf20Sopenharmony_cierror: 8938c2ecf20Sopenharmony_ci if (fid) 8948c2ecf20Sopenharmony_ci p9_client_clunk(fid); 8958c2ecf20Sopenharmony_ci v9fs_put_acl(dacl, pacl); 8968c2ecf20Sopenharmony_ci return err; 8978c2ecf20Sopenharmony_ci} 8988c2ecf20Sopenharmony_ci 8998c2ecf20Sopenharmony_ci/** 9008c2ecf20Sopenharmony_ci * v9fs_vfs_get_link_dotl - follow a symlink path 9018c2ecf20Sopenharmony_ci * @dentry: dentry for symlink 9028c2ecf20Sopenharmony_ci * @inode: inode for symlink 9038c2ecf20Sopenharmony_ci * @done: destructor for return value 9048c2ecf20Sopenharmony_ci */ 9058c2ecf20Sopenharmony_ci 9068c2ecf20Sopenharmony_cistatic const char * 9078c2ecf20Sopenharmony_civ9fs_vfs_get_link_dotl(struct dentry *dentry, 9088c2ecf20Sopenharmony_ci struct inode *inode, 9098c2ecf20Sopenharmony_ci struct delayed_call *done) 9108c2ecf20Sopenharmony_ci{ 9118c2ecf20Sopenharmony_ci struct p9_fid *fid; 9128c2ecf20Sopenharmony_ci char *target; 9138c2ecf20Sopenharmony_ci int retval; 9148c2ecf20Sopenharmony_ci 9158c2ecf20Sopenharmony_ci if (!dentry) 9168c2ecf20Sopenharmony_ci return ERR_PTR(-ECHILD); 9178c2ecf20Sopenharmony_ci 9188c2ecf20Sopenharmony_ci p9_debug(P9_DEBUG_VFS, "%pd\n", dentry); 9198c2ecf20Sopenharmony_ci 9208c2ecf20Sopenharmony_ci fid = v9fs_fid_lookup(dentry); 9218c2ecf20Sopenharmony_ci if (IS_ERR(fid)) 9228c2ecf20Sopenharmony_ci return ERR_CAST(fid); 9238c2ecf20Sopenharmony_ci retval = p9_client_readlink(fid, &target); 9248c2ecf20Sopenharmony_ci if (retval) 9258c2ecf20Sopenharmony_ci return ERR_PTR(retval); 9268c2ecf20Sopenharmony_ci set_delayed_call(done, kfree_link, target); 9278c2ecf20Sopenharmony_ci return target; 9288c2ecf20Sopenharmony_ci} 9298c2ecf20Sopenharmony_ci 9308c2ecf20Sopenharmony_ciint v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode) 9318c2ecf20Sopenharmony_ci{ 9328c2ecf20Sopenharmony_ci struct p9_stat_dotl *st; 9338c2ecf20Sopenharmony_ci struct v9fs_session_info *v9ses; 9348c2ecf20Sopenharmony_ci unsigned int flags; 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ci v9ses = v9fs_inode2v9ses(inode); 9378c2ecf20Sopenharmony_ci st = p9_client_getattr_dotl(fid, P9_STATS_ALL); 9388c2ecf20Sopenharmony_ci if (IS_ERR(st)) 9398c2ecf20Sopenharmony_ci return PTR_ERR(st); 9408c2ecf20Sopenharmony_ci /* 9418c2ecf20Sopenharmony_ci * Don't update inode if the file type is different 9428c2ecf20Sopenharmony_ci */ 9438c2ecf20Sopenharmony_ci if (inode_wrong_type(inode, st->st_mode)) 9448c2ecf20Sopenharmony_ci goto out; 9458c2ecf20Sopenharmony_ci 9468c2ecf20Sopenharmony_ci /* 9478c2ecf20Sopenharmony_ci * We don't want to refresh inode->i_size, 9488c2ecf20Sopenharmony_ci * because we may have cached data 9498c2ecf20Sopenharmony_ci */ 9508c2ecf20Sopenharmony_ci flags = (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) ? 9518c2ecf20Sopenharmony_ci V9FS_STAT2INODE_KEEP_ISIZE : 0; 9528c2ecf20Sopenharmony_ci v9fs_stat2inode_dotl(st, inode, flags); 9538c2ecf20Sopenharmony_ciout: 9548c2ecf20Sopenharmony_ci kfree(st); 9558c2ecf20Sopenharmony_ci return 0; 9568c2ecf20Sopenharmony_ci} 9578c2ecf20Sopenharmony_ci 9588c2ecf20Sopenharmony_ciconst struct inode_operations v9fs_dir_inode_operations_dotl = { 9598c2ecf20Sopenharmony_ci .create = v9fs_vfs_create_dotl, 9608c2ecf20Sopenharmony_ci .atomic_open = v9fs_vfs_atomic_open_dotl, 9618c2ecf20Sopenharmony_ci .lookup = v9fs_vfs_lookup, 9628c2ecf20Sopenharmony_ci .link = v9fs_vfs_link_dotl, 9638c2ecf20Sopenharmony_ci .symlink = v9fs_vfs_symlink_dotl, 9648c2ecf20Sopenharmony_ci .unlink = v9fs_vfs_unlink, 9658c2ecf20Sopenharmony_ci .mkdir = v9fs_vfs_mkdir_dotl, 9668c2ecf20Sopenharmony_ci .rmdir = v9fs_vfs_rmdir, 9678c2ecf20Sopenharmony_ci .mknod = v9fs_vfs_mknod_dotl, 9688c2ecf20Sopenharmony_ci .rename = v9fs_vfs_rename, 9698c2ecf20Sopenharmony_ci .getattr = v9fs_vfs_getattr_dotl, 9708c2ecf20Sopenharmony_ci .setattr = v9fs_vfs_setattr_dotl, 9718c2ecf20Sopenharmony_ci .listxattr = v9fs_listxattr, 9728c2ecf20Sopenharmony_ci .get_acl = v9fs_iop_get_acl, 9738c2ecf20Sopenharmony_ci}; 9748c2ecf20Sopenharmony_ci 9758c2ecf20Sopenharmony_ciconst struct inode_operations v9fs_file_inode_operations_dotl = { 9768c2ecf20Sopenharmony_ci .getattr = v9fs_vfs_getattr_dotl, 9778c2ecf20Sopenharmony_ci .setattr = v9fs_vfs_setattr_dotl, 9788c2ecf20Sopenharmony_ci .listxattr = v9fs_listxattr, 9798c2ecf20Sopenharmony_ci .get_acl = v9fs_iop_get_acl, 9808c2ecf20Sopenharmony_ci}; 9818c2ecf20Sopenharmony_ci 9828c2ecf20Sopenharmony_ciconst struct inode_operations v9fs_symlink_inode_operations_dotl = { 9838c2ecf20Sopenharmony_ci .get_link = v9fs_vfs_get_link_dotl, 9848c2ecf20Sopenharmony_ci .getattr = v9fs_vfs_getattr_dotl, 9858c2ecf20Sopenharmony_ci .setattr = v9fs_vfs_setattr_dotl, 9868c2ecf20Sopenharmony_ci .listxattr = v9fs_listxattr, 9878c2ecf20Sopenharmony_ci}; 988