9p: Define and implement TLINK for 9P2000.L
This patch adds a helper function to get the dentry from inode and uses it in creating a Hardlink SYNOPSIS size[4] Tlink tag[2] dfid[4] oldfid[4] newpath[s] size[4] Rlink tag[2] DESCRIPTION Create a link 'newpath' in directory pointed by dfid linking to oldfid path. [sripathik@in.ibm.com : p9_client_link should not free req structure if p9_client_rpc has returned an error.] Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
This commit is contained in:
parent
87d7845aa0
commit
09d34ee5f9
1 changed files with 106 additions and 1 deletions
|
@ -235,6 +235,41 @@ void v9fs_destroy_inode(struct inode *inode)
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* v9fs_get_fsgid_for_create - 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.
|
||||
*/
|
||||
|
||||
static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
|
||||
{
|
||||
BUG_ON(dir_inode == NULL);
|
||||
|
||||
if (dir_inode->i_mode & S_ISGID) {
|
||||
/* set_gid bit is set.*/
|
||||
return dir_inode->i_gid;
|
||||
}
|
||||
return current_fsgid();
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_dentry_from_dir_inode - helper function to get the dentry from
|
||||
* dir inode.
|
||||
*
|
||||
*/
|
||||
|
||||
struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
|
||||
spin_lock(&dcache_lock);
|
||||
/* Directory should have only one entry. */
|
||||
BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry));
|
||||
dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
|
||||
spin_unlock(&dcache_lock);
|
||||
return dentry;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_get_inode - helper function to setup an inode
|
||||
* @sb: superblock
|
||||
|
@ -1373,6 +1408,76 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
|
||||
struct dentry *dentry)
|
||||
{
|
||||
int err;
|
||||
struct p9_fid *dfid, *oldfid;
|
||||
char *name;
|
||||
struct v9fs_session_info *v9ses;
|
||||
struct dentry *dir_dentry;
|
||||
|
||||
P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n",
|
||||
dir->i_ino, old_dentry->d_name.name,
|
||||
dentry->d_name.name);
|
||||
|
||||
v9ses = v9fs_inode2v9ses(dir);
|
||||
dir_dentry = v9fs_dentry_from_dir_inode(dir);
|
||||
dfid = v9fs_fid_lookup(dir_dentry);
|
||||
if (IS_ERR(dfid))
|
||||
return PTR_ERR(dfid);
|
||||
|
||||
oldfid = v9fs_fid_lookup(old_dentry);
|
||||
if (IS_ERR(oldfid))
|
||||
return PTR_ERR(oldfid);
|
||||
|
||||
name = (char *) dentry->d_name.name;
|
||||
|
||||
err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name);
|
||||
|
||||
if (err < 0) {
|
||||
P9_DPRINTK(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
|
||||
/* Get the latest stat info from server. */
|
||||
struct p9_fid *fid;
|
||||
struct p9_stat_dotl *st;
|
||||
|
||||
fid = v9fs_fid_lookup(old_dentry);
|
||||
if (IS_ERR(fid))
|
||||
return PTR_ERR(fid);
|
||||
|
||||
st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
|
||||
if (IS_ERR(st))
|
||||
return PTR_ERR(st);
|
||||
|
||||
v9fs_stat2inode_dotl(st, old_dentry->d_inode);
|
||||
|
||||
kfree(st);
|
||||
} else {
|
||||
/* Caching disabled. No need to get upto date stat info.
|
||||
* This dentry will be released immediately. So, just i_count++
|
||||
*/
|
||||
atomic_inc(&old_dentry->d_inode->i_count);
|
||||
}
|
||||
|
||||
dentry->d_op = old_dentry->d_op;
|
||||
d_instantiate(dentry, old_dentry->d_inode);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* v9fs_vfs_mknod - create a special file
|
||||
* @dir: inode destination for new link
|
||||
|
@ -1422,7 +1527,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotu = {
|
|||
.create = v9fs_vfs_create,
|
||||
.lookup = v9fs_vfs_lookup,
|
||||
.symlink = v9fs_vfs_symlink,
|
||||
.link = v9fs_vfs_link,
|
||||
.link = v9fs_vfs_link_dotl,
|
||||
.unlink = v9fs_vfs_unlink,
|
||||
.mkdir = v9fs_vfs_mkdir,
|
||||
.rmdir = v9fs_vfs_rmdir,
|
||||
|
|
Loading…
Reference in a new issue