-/**
- * v9fs_vfs_mknod_dotl - create a special file
- * @dir: inode destination for new link
- * @dentry: dentry for file
- * @mode: mode for creation
- * @rdev: device associated with special file
- *
- */
-static int
-v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
- dev_t rdev)
-{
- int err;
- char *name;
- mode_t mode;
- struct v9fs_session_info *v9ses;
- struct p9_fid *fid = NULL, *dfid = NULL;
- struct inode *inode;
- gid_t gid;
- struct p9_qid qid;
- struct dentry *dir_dentry;
- struct posix_acl *dacl = NULL, *pacl = NULL;
-
- P9_DPRINTK(P9_DEBUG_VFS,
- " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
- dentry->d_name.name, omode, MAJOR(rdev), MINOR(rdev));
-
- if (!new_valid_dev(rdev))
- return -EINVAL;
-
- v9ses = v9fs_inode2v9ses(dir);
- dir_dentry = v9fs_dentry_from_dir_inode(dir);
- dfid = v9fs_fid_lookup(dir_dentry);
- if (IS_ERR(dfid)) {
- err = PTR_ERR(dfid);
- P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
- dfid = NULL;
- goto error;
- }
-
- 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_DPRINTK(P9_DEBUG_VFS,
- "Failed to get acl values in mknod %d\n", err);
- goto error;
- }
- name = (char *) dentry->d_name.name;
-
- err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
- if (err < 0)
- goto error;
-
- /* instantiate inode and assign the unopened fid to the dentry */
- if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
- fid = p9_client_walk(dfid, 1, &name, 1);
- if (IS_ERR(fid)) {
- err = PTR_ERR(fid);
- P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
- err);
- fid = NULL;
- goto error;
- }
-
- inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
- if (IS_ERR(inode)) {
- err = PTR_ERR(inode);
- P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
- err);
- goto error;
- }
- dentry->d_op = &v9fs_cached_dentry_operations;
- d_instantiate(dentry, inode);
- err = v9fs_fid_add(dentry, fid);
- if (err < 0)
- goto error;
- fid = NULL;
- } else {
- /*
- * Not in cached mode. No need to populate inode with stat.
- * socket syscall returns a fd, so we need instantiate
- */
- inode = v9fs_get_inode(dir->i_sb, mode);
- if (IS_ERR(inode)) {
- err = PTR_ERR(inode);
- goto error;
- }
- dentry->d_op = &v9fs_dentry_operations;
- d_instantiate(dentry, inode);
- }
- /* Now set the ACL based on the default value */
- v9fs_set_create_acl(dentry, dacl, pacl);
-error:
- if (fid)
- p9_client_clunk(fid);
- return err;
-}
-
-static int
-v9fs_vfs_readlink_dotl(struct dentry *dentry, char *buffer, int buflen)
-{
- int retval;
- struct p9_fid *fid;
- char *target = NULL;
-
- P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name);
- retval = -EPERM;
- fid = v9fs_fid_lookup(dentry);
- if (IS_ERR(fid))
- return PTR_ERR(fid);
-
- retval = p9_client_readlink(fid, &target);
- if (retval < 0)
- return retval;
-
- strncpy(buffer, target, buflen);
- P9_DPRINTK(P9_DEBUG_VFS, "%s -> %s\n", dentry->d_name.name, buffer);
-
- retval = strnlen(buffer, buflen);
- return retval;
-}
-
-/**
- * v9fs_vfs_follow_link_dotl - follow a symlink path
- * @dentry: dentry for symlink
- * @nd: nameidata
- *
- */
-
-static void *
-v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd)
-{
- int len = 0;
- char *link = __getname();
-
- P9_DPRINTK(P9_DEBUG_VFS, "%s n", dentry->d_name.name);
-
- if (!link)
- link = ERR_PTR(-ENOMEM);
- else {
- len = v9fs_vfs_readlink_dotl(dentry, link, PATH_MAX);
- if (len < 0) {
- __putname(link);
- link = ERR_PTR(len);
- } else
- link[min(len, PATH_MAX-1)] = 0;
- }
- nd_set_link(nd, link);
-
- return NULL;
-}
-