aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spufs
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs')
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c77
-rw-r--r--arch/powerpc/platforms/cell/spufs/syscalls.c2
2 files changed, 26 insertions, 53 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index d544d7816df..dba1ce235da 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -186,10 +186,13 @@ static void spufs_prune_dir(struct dentry *dir)
186static int spufs_rmdir(struct inode *parent, struct dentry *dir) 186static int spufs_rmdir(struct inode *parent, struct dentry *dir)
187{ 187{
188 /* remove all entries */ 188 /* remove all entries */
189 int res;
189 spufs_prune_dir(dir); 190 spufs_prune_dir(dir);
190 d_drop(dir); 191 d_drop(dir);
191 192 res = simple_rmdir(parent, dir);
192 return simple_rmdir(parent, dir); 193 /* We have to give up the mm_struct */
194 spu_forget(SPUFS_I(dir->d_inode)->i_ctx);
195 return res;
193} 196}
194 197
195static int spufs_fill_dir(struct dentry *dir, 198static int spufs_fill_dir(struct dentry *dir,
@@ -245,9 +248,6 @@ static int spufs_dir_close(struct inode *inode, struct file *file)
245 mutex_unlock(&parent->i_mutex); 248 mutex_unlock(&parent->i_mutex);
246 WARN_ON(ret); 249 WARN_ON(ret);
247 250
248 /* We have to give up the mm_struct */
249 spu_forget(ctx);
250
251 return dcache_dir_close(inode, file); 251 return dcache_dir_close(inode, file);
252} 252}
253 253
@@ -450,28 +450,24 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
450 struct spu_context *neighbor; 450 struct spu_context *neighbor;
451 struct path path = {.mnt = mnt, .dentry = dentry}; 451 struct path path = {.mnt = mnt, .dentry = dentry};
452 452
453 ret = -EPERM;
454 if ((flags & SPU_CREATE_NOSCHED) && 453 if ((flags & SPU_CREATE_NOSCHED) &&
455 !capable(CAP_SYS_NICE)) 454 !capable(CAP_SYS_NICE))
456 goto out_unlock; 455 return -EPERM;
457 456
458 ret = -EINVAL;
459 if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE)) 457 if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE))
460 == SPU_CREATE_ISOLATE) 458 == SPU_CREATE_ISOLATE)
461 goto out_unlock; 459 return -EINVAL;
462 460
463 ret = -ENODEV;
464 if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader) 461 if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader)
465 goto out_unlock; 462 return -ENODEV;
466 463
467 gang = NULL; 464 gang = NULL;
468 neighbor = NULL; 465 neighbor = NULL;
469 affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU); 466 affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU);
470 if (affinity) { 467 if (affinity) {
471 gang = SPUFS_I(inode)->i_gang; 468 gang = SPUFS_I(inode)->i_gang;
472 ret = -EINVAL;
473 if (!gang) 469 if (!gang)
474 goto out_unlock; 470 return -EINVAL;
475 mutex_lock(&gang->aff_mutex); 471 mutex_lock(&gang->aff_mutex);
476 neighbor = spufs_assert_affinity(flags, gang, aff_filp); 472 neighbor = spufs_assert_affinity(flags, gang, aff_filp);
477 if (IS_ERR(neighbor)) { 473 if (IS_ERR(neighbor)) {
@@ -492,22 +488,12 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
492 } 488 }
493 489
494 ret = spufs_context_open(&path); 490 ret = spufs_context_open(&path);
495 if (ret < 0) { 491 if (ret < 0)
496 WARN_ON(spufs_rmdir(inode, dentry)); 492 WARN_ON(spufs_rmdir(inode, dentry));
497 if (affinity)
498 mutex_unlock(&gang->aff_mutex);
499 mutex_unlock(&inode->i_mutex);
500 spu_forget(SPUFS_I(dentry->d_inode)->i_ctx);
501 goto out;
502 }
503 493
504out_aff_unlock: 494out_aff_unlock:
505 if (affinity) 495 if (affinity)
506 mutex_unlock(&gang->aff_mutex); 496 mutex_unlock(&gang->aff_mutex);
507out_unlock:
508 mutex_unlock(&inode->i_mutex);
509out:
510 dput(dentry);
511 return ret; 497 return ret;
512} 498}
513 499
@@ -580,18 +566,13 @@ static int spufs_create_gang(struct inode *inode,
580 int ret; 566 int ret;
581 567
582 ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO); 568 ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO);
583 if (ret) 569 if (!ret) {
584 goto out; 570 ret = spufs_gang_open(&path);
585 571 if (ret < 0) {
586 ret = spufs_gang_open(&path); 572 int err = simple_rmdir(inode, dentry);
587 if (ret < 0) { 573 WARN_ON(err);
588 int err = simple_rmdir(inode, dentry); 574 }
589 WARN_ON(err);
590 } 575 }
591
592out:
593 mutex_unlock(&inode->i_mutex);
594 dput(dentry);
595 return ret; 576 return ret;
596} 577}
597 578
@@ -601,40 +582,32 @@ static struct file_system_type spufs_type;
601long spufs_create(struct path *path, struct dentry *dentry, 582long spufs_create(struct path *path, struct dentry *dentry,
602 unsigned int flags, umode_t mode, struct file *filp) 583 unsigned int flags, umode_t mode, struct file *filp)
603{ 584{
585 struct inode *dir = path->dentry->d_inode;
604 int ret; 586 int ret;
605 587
606 ret = -EINVAL;
607 /* check if we are on spufs */ 588 /* check if we are on spufs */
608 if (path->dentry->d_sb->s_type != &spufs_type) 589 if (path->dentry->d_sb->s_type != &spufs_type)
609 goto out; 590 return -EINVAL;
610 591
611 /* don't accept undefined flags */ 592 /* don't accept undefined flags */
612 if (flags & (~SPU_CREATE_FLAG_ALL)) 593 if (flags & (~SPU_CREATE_FLAG_ALL))
613 goto out; 594 return -EINVAL;
614 595
615 /* only threads can be underneath a gang */ 596 /* only threads can be underneath a gang */
616 if (path->dentry != path->dentry->d_sb->s_root) { 597 if (path->dentry != path->dentry->d_sb->s_root)
617 if ((flags & SPU_CREATE_GANG) || 598 if ((flags & SPU_CREATE_GANG) || !SPUFS_I(dir)->i_gang)
618 !SPUFS_I(path->dentry->d_inode)->i_gang) 599 return -EINVAL;
619 goto out;
620 }
621 600
622 mode &= ~current_umask(); 601 mode &= ~current_umask();
623 602
624 if (flags & SPU_CREATE_GANG) 603 if (flags & SPU_CREATE_GANG)
625 ret = spufs_create_gang(path->dentry->d_inode, 604 ret = spufs_create_gang(dir, dentry, path->mnt, mode);
626 dentry, path->mnt, mode);
627 else 605 else
628 ret = spufs_create_context(path->dentry->d_inode, 606 ret = spufs_create_context(dir, dentry, path->mnt, flags, mode,
629 dentry, path->mnt, flags, mode,
630 filp); 607 filp);
631 if (ret >= 0) 608 if (ret >= 0)
632 fsnotify_mkdir(path->dentry->d_inode, dentry); 609 fsnotify_mkdir(dir, dentry);
633 return ret;
634 610
635out:
636 mutex_unlock(&path->dentry->d_inode->i_mutex);
637 dput(dentry);
638 return ret; 611 return ret;
639} 612}
640 613
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
index 5665dcc382c..5b7d8ffbf89 100644
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -70,7 +70,7 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
70 ret = PTR_ERR(dentry); 70 ret = PTR_ERR(dentry);
71 if (!IS_ERR(dentry)) { 71 if (!IS_ERR(dentry)) {
72 ret = spufs_create(&path, dentry, flags, mode, neighbor); 72 ret = spufs_create(&path, dentry, flags, mode, neighbor);
73 path_put(&path); 73 done_path_create(&path, dentry);
74 } 74 }
75 75
76 return ret; 76 return ret;