diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-01 13:26:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-01 13:26:23 -0400 |
commit | a0e881b7c189fa2bd76c024dbff91e79511c971d (patch) | |
tree | 0c801918565b08921d21aceee5b326f64d998f5f /arch/powerpc | |
parent | eff0d13f3823f35d70228cd151d2a2c89288ff32 (diff) | |
parent | dbc6e0222d79e78925fe20733844a796a4b72cf9 (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.c | 77 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/syscalls.c | 2 |
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) | |||
186 | static int spufs_rmdir(struct inode *parent, struct dentry *dir) | 186 | static 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 | ||
195 | static int spufs_fill_dir(struct dentry *dir, | 198 | static 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 | ||
504 | out_aff_unlock: | 494 | out_aff_unlock: |
505 | if (affinity) | 495 | if (affinity) |
506 | mutex_unlock(&gang->aff_mutex); | 496 | mutex_unlock(&gang->aff_mutex); |
507 | out_unlock: | ||
508 | mutex_unlock(&inode->i_mutex); | ||
509 | out: | ||
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 | |||
592 | out: | ||
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; | |||
601 | long spufs_create(struct path *path, struct dentry *dentry, | 582 | long 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 | ||
635 | out: | ||
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; |