// SPDX-License-Identifier: GPL-2.0-only /* * This file contains vfs inode ops for the 9P2000.L protocol. * * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*/
/** * v9fs_get_fsgid_for_create - Helper function to get the gid for a new object * @dir_inode: The directory inode * * Helper function to get the gid for creating a * new file system object. This checks the S_ISGID to determine the owning * group of the new file system object.
*/
if (new)
test = v9fs_test_new_inode_dotl; else
test = v9fs_test_inode_dotl;
inode = iget5_locked(sb, QID2INO(qid), test, v9fs_set_inode_dotl, st); if (!inode) return ERR_PTR(-ENOMEM); if (!(inode->i_state & I_NEW)) return inode; /* * initialize the inode with the stat info * FIXME!! we may need support for stale inodes * later.
*/
inode->i_ino = QID2INO(qid);
retval = v9fs_init_inode(v9ses, inode,
st->st_mode, new_decode_dev(st->st_rdev)); if (retval) goto error;
/** * v9fs_open_to_dotl_flags- convert Linux specific open flags to * plan 9 open flag. * @flags: flags to convert
*/ int v9fs_open_to_dotl_flags(int flags)
{ int rflags = 0;
/* * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY * and P9_DOTL_NOACCESS
*/
rflags |= flags & O_ACCMODE;
rflags |= v9fs_mapped_dotl_flags(flags);
return rflags;
}
/** * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol. * @idmap: The user namespace of the mount * @dir: directory inode that is being created * @dentry: dentry that is being deleted * @omode: create permissions * @excl: True if the file must not yet exist *
*/ staticint
v9fs_vfs_create_dotl(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t omode, bool excl)
{ return v9fs_vfs_mknod_dotl(idmap, dir, dentry, omode, 0);
}
/* clone a fid to use for creation */
ofid = clone_fid(dfid); if (IS_ERR(ofid)) {
err = PTR_ERR(ofid);
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); goto out;
}
gid = v9fs_get_fsgid_for_create(dir);
mode = omode; /* Update mode based on ACL value */
err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); if (err) {
p9_debug(P9_DEBUG_VFS, "Failed to get acl values in create %d\n",
err); goto out;
}
/* Since we are opening a file, assign the open fid to the file */
err = finish_open(file, dentry, generic_file_open); if (err) goto out;
file->private_data = ofid; #ifdef CONFIG_9P_FSCACHE if (v9ses->cache & CACHE_FSCACHE) { struct v9fs_inode *v9inode = V9FS_I(inode);
fscache_use_cookie(v9fs_inode_cookie(v9inode),
file->f_mode & FMODE_WRITE);
} #endif
v9fs_fid_add_modes(ofid, v9ses->flags, v9ses->cache, flags);
v9fs_open_fid_add(inode, &ofid);
file->f_mode |= FMODE_CREATED;
out:
p9_fid_put(dfid);
p9_fid_put(ofid);
p9_fid_put(fid);
v9fs_put_acl(dacl, pacl);
dput(res); return err;
}
/** * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory * @idmap: The idmap of the mount * @dir: inode that is being unlinked * @dentry: dentry that is being unlinked * @omode: mode for new directory *
*/
p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
v9ses = v9fs_dentry2v9ses(dentry); if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat); return 0;
} elseif (v9ses->cache) { if (S_ISREG(inode->i_mode)) { int retval = filemap_fdatawrite(inode->i_mapping);
if (retval)
p9_debug(P9_DEBUG_ERROR, "flushing writeback during getattr returned %d\n", retval);
}
}
fid = v9fs_fid_lookup(dentry); if (IS_ERR(fid)) return PTR_ERR(fid);
/* Ask for all the fields in stat structure. Server will return * whatever it supports
*/
st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
p9_fid_put(fid); if (IS_ERR(st)) return PTR_ERR(st);
v9fs_stat2inode_dotl(st, d_inode(dentry), 0);
generic_fillattr(&nop_mnt_idmap, request_mask, d_inode(dentry), stat); /* Change block size to what the server returned */
stat->blksize = st->st_blksize;
/** * v9fs_vfs_setattr_dotl - set file metadata * @idmap: idmap of the mount * @dentry: file whose metadata to set * @iattr: metadata assignment structure *
*/
#ifdef CONFIG_9P_FSCACHE if (v9ses->cache & CACHE_FSCACHE)
fscache_resize_cookie(v9fs_inode_cookie(V9FS_I(inode)),
iattr->ia_size); #endif
}
v9fs_invalidate_inode_attr(inode);
setattr_copy(&nop_mnt_idmap, inode, iattr);
mark_inode_dirty(inode); if (iattr->ia_valid & ATTR_MODE) { /* We also want to update ACL when we update mode bits */
retval = v9fs_acl_chmod(inode, fid); if (retval < 0) { if (use_dentry)
p9_fid_put(fid); return retval;
}
} if (use_dentry)
p9_fid_put(fid);
return 0;
}
/** * v9fs_stat2inode_dotl - populate an inode structure with stat info * @stat: stat structure * @inode: inode to populate * @flags: ctrl flags (e.g. V9FS_STAT2INODE_KEEP_ISIZE) *
*/
/* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION * because the inode structure does not have fields for them.
*/
v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
}
/** * v9fs_vfs_link_dotl - create a hardlink for dotl * @old_dentry: dentry for file to link to * @dir: inode destination for new link * @dentry: dentry for link *
*/
gid = v9fs_get_fsgid_for_create(dir);
mode = omode; /* Update mode based on ACL value */
err = v9fs_acl_mode(dir, &mode, &dacl, &pacl); if (err) {
p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mknod %d\n",
err); goto error;
}
name = dentry->d_name.name;
v9ses = v9fs_inode2v9ses(inode);
st = p9_client_getattr_dotl(fid, P9_STATS_ALL); if (IS_ERR(st)) return PTR_ERR(st); /* * Don't update inode if the file type is different
*/ if (inode_wrong_type(inode, st->st_mode)) goto out;
/* * We don't want to refresh inode->i_size, * because we may have cached data
*/
flags = (v9ses->cache & CACHE_LOOSE) ?
V9FS_STAT2INODE_KEEP_ISIZE : 0;
v9fs_stat2inode_dotl(st, inode, flags);
out:
kfree(st); return 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.