aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/vfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/9p/vfs_inode.c')
-rw-r--r--fs/9p/vfs_inode.c95
1 files changed, 61 insertions, 34 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 0c13fc600049..2b696ae6655a 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -307,7 +307,7 @@ v9fs_create(struct inode *dir,
307 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); 307 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
308 struct super_block *sb = dir->i_sb; 308 struct super_block *sb = dir->i_sb;
309 struct v9fs_fid *dirfid = 309 struct v9fs_fid *dirfid =
310 v9fs_fid_lookup(file_dentry->d_parent, FID_WALK); 310 v9fs_fid_lookup(file_dentry->d_parent);
311 struct v9fs_fid *fid = NULL; 311 struct v9fs_fid *fid = NULL;
312 struct inode *file_inode = NULL; 312 struct inode *file_inode = NULL;
313 struct v9fs_fcall *fcall = NULL; 313 struct v9fs_fcall *fcall = NULL;
@@ -317,6 +317,7 @@ v9fs_create(struct inode *dir,
317 long newfid = -1; 317 long newfid = -1;
318 int result = 0; 318 int result = 0;
319 unsigned int iounit = 0; 319 unsigned int iounit = 0;
320 int wfidno = -1;
320 321
321 perm = unixmode2p9mode(v9ses, perm); 322 perm = unixmode2p9mode(v9ses, perm);
322 323
@@ -350,7 +351,7 @@ v9fs_create(struct inode *dir,
350 if (result < 0) { 351 if (result < 0) {
351 dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall)); 352 dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall));
352 v9fs_put_idpool(newfid, &v9ses->fidpool); 353 v9fs_put_idpool(newfid, &v9ses->fidpool);
353 newfid = 0; 354 newfid = -1;
354 goto CleanUpFid; 355 goto CleanUpFid;
355 } 356 }
356 357
@@ -369,20 +370,39 @@ v9fs_create(struct inode *dir,
369 qid = fcall->params.rcreate.qid; 370 qid = fcall->params.rcreate.qid;
370 kfree(fcall); 371 kfree(fcall);
371 372
372 fid = v9fs_fid_create(file_dentry); 373 fid = v9fs_fid_create(file_dentry, v9ses, newfid, 1);
374 dprintk(DEBUG_VFS, "fid %p %d\n", fid, fid->fidcreate);
373 if (!fid) { 375 if (!fid) {
374 result = -ENOMEM; 376 result = -ENOMEM;
375 goto CleanUpFid; 377 goto CleanUpFid;
376 } 378 }
377 379
378 fid->fid = newfid;
379 fid->fidopen = 0;
380 fid->fidcreate = 1;
381 fid->qid = qid; 380 fid->qid = qid;
382 fid->iounit = iounit; 381 fid->iounit = iounit;
383 fid->rdir_pos = 0; 382
384 fid->rdir_fcall = NULL; 383 /* walk to the newly created file and put the fid in the dentry */
385 fid->v9ses = v9ses; 384 wfidno = v9fs_get_idpool(&v9ses->fidpool);
385 if (newfid < 0) {
386 eprintk(KERN_WARNING, "no free fids available\n");
387 return -ENOSPC;
388 }
389
390 result = v9fs_t_walk(v9ses, dirfidnum, wfidno,
391 (char *) file_dentry->d_name.name, NULL);
392 if (result < 0) {
393 dprintk(DEBUG_ERROR, "clone error: %s\n", FCALL_ERROR(fcall));
394 v9fs_put_idpool(wfidno, &v9ses->fidpool);
395 wfidno = -1;
396 goto CleanUpFid;
397 }
398
399 if (!v9fs_fid_create(file_dentry, v9ses, wfidno, 0)) {
400 if (!v9fs_t_clunk(v9ses, newfid, &fcall)) {
401 v9fs_put_idpool(wfidno, &v9ses->fidpool);
402 }
403
404 goto CleanUpFid;
405 }
386 406
387 if ((perm & V9FS_DMSYMLINK) || (perm & V9FS_DMLINK) || 407 if ((perm & V9FS_DMSYMLINK) || (perm & V9FS_DMLINK) ||
388 (perm & V9FS_DMNAMEDPIPE) || (perm & V9FS_DMSOCKET) || 408 (perm & V9FS_DMNAMEDPIPE) || (perm & V9FS_DMSOCKET) ||
@@ -410,11 +430,11 @@ v9fs_create(struct inode *dir,
410 d_instantiate(file_dentry, file_inode); 430 d_instantiate(file_dentry, file_inode);
411 431
412 if (perm & V9FS_DMDIR) { 432 if (perm & V9FS_DMDIR) {
413 if (v9fs_t_clunk(v9ses, newfid, &fcall)) 433 if (!v9fs_t_clunk(v9ses, newfid, &fcall))
434 v9fs_put_idpool(newfid, &v9ses->fidpool);
435 else
414 dprintk(DEBUG_ERROR, "clunk for mkdir failed: %s\n", 436 dprintk(DEBUG_ERROR, "clunk for mkdir failed: %s\n",
415 FCALL_ERROR(fcall)); 437 FCALL_ERROR(fcall));
416
417 v9fs_put_idpool(newfid, &v9ses->fidpool);
418 kfree(fcall); 438 kfree(fcall);
419 fid->fidopen = 0; 439 fid->fidopen = 0;
420 fid->fidcreate = 0; 440 fid->fidcreate = 0;
@@ -426,12 +446,22 @@ v9fs_create(struct inode *dir,
426 CleanUpFid: 446 CleanUpFid:
427 kfree(fcall); 447 kfree(fcall);
428 448
429 if (newfid) { 449 if (newfid >= 0) {
430 if (v9fs_t_clunk(v9ses, newfid, &fcall)) 450 if (!v9fs_t_clunk(v9ses, newfid, &fcall))
451 v9fs_put_idpool(newfid, &v9ses->fidpool);
452 else
453 dprintk(DEBUG_ERROR, "clunk failed: %s\n",
454 FCALL_ERROR(fcall));
455
456 kfree(fcall);
457 }
458 if (wfidno >= 0) {
459 if (!v9fs_t_clunk(v9ses, wfidno, &fcall))
460 v9fs_put_idpool(wfidno, &v9ses->fidpool);
461 else
431 dprintk(DEBUG_ERROR, "clunk failed: %s\n", 462 dprintk(DEBUG_ERROR, "clunk failed: %s\n",
432 FCALL_ERROR(fcall)); 463 FCALL_ERROR(fcall));
433 464
434 v9fs_put_idpool(newfid, &v9ses->fidpool);
435 kfree(fcall); 465 kfree(fcall);
436 } 466 }
437 return result; 467 return result;
@@ -461,7 +491,7 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir)
461 file_inode = file->d_inode; 491 file_inode = file->d_inode;
462 sb = file_inode->i_sb; 492 sb = file_inode->i_sb;
463 v9ses = v9fs_inode2v9ses(file_inode); 493 v9ses = v9fs_inode2v9ses(file_inode);
464 v9fid = v9fs_fid_lookup(file, FID_OP); 494 v9fid = v9fs_fid_lookup(file);
465 495
466 if (!v9fid) { 496 if (!v9fid) {
467 dprintk(DEBUG_ERROR, 497 dprintk(DEBUG_ERROR,
@@ -545,7 +575,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
545 575
546 sb = dir->i_sb; 576 sb = dir->i_sb;
547 v9ses = v9fs_inode2v9ses(dir); 577 v9ses = v9fs_inode2v9ses(dir);
548 dirfid = v9fs_fid_lookup(dentry->d_parent, FID_WALK); 578 dirfid = v9fs_fid_lookup(dentry->d_parent);
549 579
550 if (!dirfid) { 580 if (!dirfid) {
551 dprintk(DEBUG_ERROR, "no dirfid\n"); 581 dprintk(DEBUG_ERROR, "no dirfid\n");
@@ -573,7 +603,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
573 v9fs_put_idpool(newfid, &v9ses->fidpool); 603 v9fs_put_idpool(newfid, &v9ses->fidpool);
574 if (result == -ENOENT) { 604 if (result == -ENOENT) {
575 d_add(dentry, NULL); 605 d_add(dentry, NULL);
576 dprintk(DEBUG_ERROR, 606 dprintk(DEBUG_VFS,
577 "Return negative dentry %p count %d\n", 607 "Return negative dentry %p count %d\n",
578 dentry, atomic_read(&dentry->d_count)); 608 dentry, atomic_read(&dentry->d_count));
579 return NULL; 609 return NULL;
@@ -601,16 +631,13 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
601 631
602 inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat->qid); 632 inode->i_ino = v9fs_qid2ino(&fcall->params.rstat.stat->qid);
603 633
604 fid = v9fs_fid_create(dentry); 634 fid = v9fs_fid_create(dentry, v9ses, newfid, 0);
605 if (fid == NULL) { 635 if (fid == NULL) {
606 dprintk(DEBUG_ERROR, "couldn't insert\n"); 636 dprintk(DEBUG_ERROR, "couldn't insert\n");
607 result = -ENOMEM; 637 result = -ENOMEM;
608 goto FreeFcall; 638 goto FreeFcall;
609 } 639 }
610 640
611 fid->fid = newfid;
612 fid->fidopen = 0;
613 fid->v9ses = v9ses;
614 fid->qid = fcall->params.rstat.stat->qid; 641 fid->qid = fcall->params.rstat.stat->qid;
615 642
616 dentry->d_op = &v9fs_dentry_operations; 643 dentry->d_op = &v9fs_dentry_operations;
@@ -665,11 +692,11 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
665{ 692{
666 struct inode *old_inode = old_dentry->d_inode; 693 struct inode *old_inode = old_dentry->d_inode;
667 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode); 694 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(old_inode);
668 struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry, FID_WALK); 695 struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry);
669 struct v9fs_fid *olddirfid = 696 struct v9fs_fid *olddirfid =
670 v9fs_fid_lookup(old_dentry->d_parent, FID_WALK); 697 v9fs_fid_lookup(old_dentry->d_parent);
671 struct v9fs_fid *newdirfid = 698 struct v9fs_fid *newdirfid =
672 v9fs_fid_lookup(new_dentry->d_parent, FID_WALK); 699 v9fs_fid_lookup(new_dentry->d_parent);
673 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); 700 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
674 struct v9fs_fcall *fcall = NULL; 701 struct v9fs_fcall *fcall = NULL;
675 int fid = -1; 702 int fid = -1;
@@ -744,7 +771,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
744{ 771{
745 struct v9fs_fcall *fcall = NULL; 772 struct v9fs_fcall *fcall = NULL;
746 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 773 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
747 struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP); 774 struct v9fs_fid *fid = v9fs_fid_lookup(dentry);
748 int err = -EPERM; 775 int err = -EPERM;
749 776
750 dprintk(DEBUG_VFS, "dentry: %p\n", dentry); 777 dprintk(DEBUG_VFS, "dentry: %p\n", dentry);
@@ -778,7 +805,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
778static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr) 805static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
779{ 806{
780 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 807 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
781 struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP); 808 struct v9fs_fid *fid = v9fs_fid_lookup(dentry);
782 struct v9fs_fcall *fcall = NULL; 809 struct v9fs_fcall *fcall = NULL;
783 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); 810 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
784 int res = -EPERM; 811 int res = -EPERM;
@@ -960,7 +987,7 @@ v9fs_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
960 if (retval != 0) 987 if (retval != 0)
961 goto FreeFcall; 988 goto FreeFcall;
962 989
963 newfid = v9fs_fid_lookup(dentry, FID_OP); 990 newfid = v9fs_fid_lookup(dentry);
964 991
965 /* issue a twstat */ 992 /* issue a twstat */
966 v9fs_blank_mistat(v9ses, mistat); 993 v9fs_blank_mistat(v9ses, mistat);
@@ -1004,7 +1031,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
1004 1031
1005 struct v9fs_fcall *fcall = NULL; 1032 struct v9fs_fcall *fcall = NULL;
1006 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode); 1033 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dentry->d_inode);
1007 struct v9fs_fid *fid = v9fs_fid_lookup(dentry, FID_OP); 1034 struct v9fs_fid *fid = v9fs_fid_lookup(dentry);
1008 1035
1009 if (!fid) { 1036 if (!fid) {
1010 dprintk(DEBUG_ERROR, "could not resolve fid from dentry\n"); 1037 dprintk(DEBUG_ERROR, "could not resolve fid from dentry\n");
@@ -1063,8 +1090,8 @@ static int v9fs_vfs_readlink(struct dentry *dentry, char __user * buffer,
1063 int ret; 1090 int ret;
1064 char *link = __getname(); 1091 char *link = __getname();
1065 1092
1066 if (strlen(link) < buflen) 1093 if (buflen > PATH_MAX)
1067 buflen = strlen(link); 1094 buflen = PATH_MAX;
1068 1095
1069 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 1096 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
1070 1097
@@ -1148,7 +1175,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
1148 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir); 1175 struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
1149 struct v9fs_fcall *fcall = NULL; 1176 struct v9fs_fcall *fcall = NULL;
1150 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL); 1177 struct v9fs_stat *mistat = kmalloc(v9ses->maxdata, GFP_KERNEL);
1151 struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry, FID_OP); 1178 struct v9fs_fid *oldfid = v9fs_fid_lookup(old_dentry);
1152 struct v9fs_fid *newfid = NULL; 1179 struct v9fs_fid *newfid = NULL;
1153 char *symname = __getname(); 1180 char *symname = __getname();
1154 1181
@@ -1168,7 +1195,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
1168 if (retval != 0) 1195 if (retval != 0)
1169 goto FreeMem; 1196 goto FreeMem;
1170 1197
1171 newfid = v9fs_fid_lookup(dentry, FID_OP); 1198 newfid = v9fs_fid_lookup(dentry);
1172 if (!newfid) { 1199 if (!newfid) {
1173 dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n"); 1200 dprintk(DEBUG_ERROR, "couldn't resolve fid from dentry\n");
1174 goto FreeMem; 1201 goto FreeMem;
@@ -1246,7 +1273,7 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
1246 if (retval != 0) 1273 if (retval != 0)
1247 goto FreeMem; 1274 goto FreeMem;
1248 1275
1249 newfid = v9fs_fid_lookup(dentry, FID_OP); 1276 newfid = v9fs_fid_lookup(dentry);
1250 if (!newfid) { 1277 if (!newfid) {
1251 dprintk(DEBUG_ERROR, "coudn't resove fid from dentry\n"); 1278 dprintk(DEBUG_ERROR, "coudn't resove fid from dentry\n");
1252 retval = -EINVAL; 1279 retval = -EINVAL;