aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p
diff options
context:
space:
mode:
authorEric Van Hensbergen <ericvh@gmail.com>2010-08-02 15:28:09 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2010-08-02 15:28:09 -0400
commit09d34ee5f93b2e53b64ffba27bc18731e31154e1 (patch)
tree6a1abd891731247c270d42ba8d7c3b4e8b9fd4b3 /fs/9p
parent87d7845aa0b157a62448dd3e339856f28befe1f4 (diff)
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>
Diffstat (limited to 'fs/9p')
-rw-r--r--fs/9p/vfs_inode.c107
1 files changed, 106 insertions, 1 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index a90324f4546a..e6ece237241f 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -236,6 +236,41 @@ void v9fs_destroy_inode(struct inode *inode)
236#endif 236#endif
237 237
238/** 238/**
239 * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
240 * new file system object. This checks the S_ISGID to determine the owning
241 * group of the new file system object.
242 */
243
244static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
245{
246 BUG_ON(dir_inode == NULL);
247
248 if (dir_inode->i_mode & S_ISGID) {
249 /* set_gid bit is set.*/
250 return dir_inode->i_gid;
251 }
252 return current_fsgid();
253}
254
255/**
256 * v9fs_dentry_from_dir_inode - helper function to get the dentry from
257 * dir inode.
258 *
259 */
260
261struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
262{
263 struct dentry *dentry;
264
265 spin_lock(&dcache_lock);
266 /* Directory should have only one entry. */
267 BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry));
268 dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
269 spin_unlock(&dcache_lock);
270 return dentry;
271}
272
273/**
239 * v9fs_get_inode - helper function to setup an inode 274 * v9fs_get_inode - helper function to setup an inode
240 * @sb: superblock 275 * @sb: superblock
241 * @mode: mode to setup inode with 276 * @mode: mode to setup inode with
@@ -1374,6 +1409,76 @@ clunk_fid:
1374} 1409}
1375 1410
1376/** 1411/**
1412 * v9fs_vfs_link_dotl - create a hardlink for dotl
1413 * @old_dentry: dentry for file to link to
1414 * @dir: inode destination for new link
1415 * @dentry: dentry for link
1416 *
1417 */
1418
1419static int
1420v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
1421 struct dentry *dentry)
1422{
1423 int err;
1424 struct p9_fid *dfid, *oldfid;
1425 char *name;
1426 struct v9fs_session_info *v9ses;
1427 struct dentry *dir_dentry;
1428
1429 P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n",
1430 dir->i_ino, old_dentry->d_name.name,
1431 dentry->d_name.name);
1432
1433 v9ses = v9fs_inode2v9ses(dir);
1434 dir_dentry = v9fs_dentry_from_dir_inode(dir);
1435 dfid = v9fs_fid_lookup(dir_dentry);
1436 if (IS_ERR(dfid))
1437 return PTR_ERR(dfid);
1438
1439 oldfid = v9fs_fid_lookup(old_dentry);
1440 if (IS_ERR(oldfid))
1441 return PTR_ERR(oldfid);
1442
1443 name = (char *) dentry->d_name.name;
1444
1445 err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name);
1446
1447 if (err < 0) {
1448 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
1449 return err;
1450 }
1451
1452 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
1453 /* Get the latest stat info from server. */
1454 struct p9_fid *fid;
1455 struct p9_stat_dotl *st;
1456
1457 fid = v9fs_fid_lookup(old_dentry);
1458 if (IS_ERR(fid))
1459 return PTR_ERR(fid);
1460
1461 st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
1462 if (IS_ERR(st))
1463 return PTR_ERR(st);
1464
1465 v9fs_stat2inode_dotl(st, old_dentry->d_inode);
1466
1467 kfree(st);
1468 } else {
1469 /* Caching disabled. No need to get upto date stat info.
1470 * This dentry will be released immediately. So, just i_count++
1471 */
1472 atomic_inc(&old_dentry->d_inode->i_count);
1473 }
1474
1475 dentry->d_op = old_dentry->d_op;
1476 d_instantiate(dentry, old_dentry->d_inode);
1477
1478 return err;
1479}
1480
1481/**
1377 * v9fs_vfs_mknod - create a special file 1482 * v9fs_vfs_mknod - create a special file
1378 * @dir: inode destination for new link 1483 * @dir: inode destination for new link
1379 * @dentry: dentry for file 1484 * @dentry: dentry for file
@@ -1422,7 +1527,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotu = {
1422 .create = v9fs_vfs_create, 1527 .create = v9fs_vfs_create,
1423 .lookup = v9fs_vfs_lookup, 1528 .lookup = v9fs_vfs_lookup,
1424 .symlink = v9fs_vfs_symlink, 1529 .symlink = v9fs_vfs_symlink,
1425 .link = v9fs_vfs_link, 1530 .link = v9fs_vfs_link_dotl,
1426 .unlink = v9fs_vfs_unlink, 1531 .unlink = v9fs_vfs_unlink,
1427 .mkdir = v9fs_vfs_mkdir, 1532 .mkdir = v9fs_vfs_mkdir,
1428 .rmdir = v9fs_vfs_rmdir, 1533 .rmdir = v9fs_vfs_rmdir,