aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 13:26:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 13:26:23 -0400
commita0e881b7c189fa2bd76c024dbff91e79511c971d (patch)
tree0c801918565b08921d21aceee5b326f64d998f5f /arch/powerpc
parenteff0d13f3823f35d70228cd151d2a2c89288ff32 (diff)
parentdbc6e0222d79e78925fe20733844a796a4b72cf9 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second vfs pile from Al Viro: "The stuff in there: fsfreeze deadlock fixes by Jan (essentially, the deadlock reproduced by xfstests 068), symlink and hardlink restriction patches, plus assorted cleanups and fixes. Note that another fsfreeze deadlock (emergency thaw one) is *not* dealt with - the series by Fernando conflicts a lot with Jan's, breaks userland ABI (FIFREEZE semantics gets changed) and trades the deadlock for massive vfsmount leak; this is going to be handled next cycle. There probably will be another pull request, but that stuff won't be in it." Fix up trivial conflicts due to unrelated changes next to each other in drivers/{staging/gdm72xx/usb_boot.c, usb/gadget/storage_common.c} * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (54 commits) delousing target_core_file a bit Documentation: Correct s_umount state for freeze_fs/unfreeze_fs fs: Remove old freezing mechanism ext2: Implement freezing btrfs: Convert to new freezing mechanism nilfs2: Convert to new freezing mechanism ntfs: Convert to new freezing mechanism fuse: Convert to new freezing mechanism gfs2: Convert to new freezing mechanism ocfs2: Convert to new freezing mechanism xfs: Convert to new freezing code ext4: Convert to new freezing mechanism fs: Protect write paths by sb_start_write - sb_end_write fs: Skip atime update on frozen filesystem fs: Add freezing handling to mnt_want_write() / mnt_drop_write() fs: Improve filesystem freezing handling switch the protection of percpu_counter list to spinlock nfsd: Push mnt_want_write() outside of i_mutex btrfs: Push mnt_want_write() outside of i_mutex fat: Push mnt_want_write() outside of i_mutex ...
Diffstat (limited to 'arch/powerpc')
-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 d544d7816df3..dba1ce235da5 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 5665dcc382c7..5b7d8ffbf890 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;