diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-07 16:00:23 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-08-07 16:00:23 -0400 |
| commit | 8ef9c292ac7bf91fc0367746cf5db264adddced9 (patch) | |
| tree | 61ab727e8d0fa4bf058c0d914b95e9f40d1ede33 | |
| parent | e4ef108fcde0b97ed38923ba1ea06c7a152bab9e (diff) | |
| parent | 3d62c45b38e534262d443b5820fb06a0e6d0d42f (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro.
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
vfs: add missing check for __O_TMPFILE in fcntl_init()
fs: Allow unprivileged linkat(..., AT_EMPTY_PATH) aka flink
fs: Fix file mode for O_TMPFILE
reiserfs: fix deadlock in umount
| -rw-r--r-- | fs/fcntl.c | 4 | ||||
| -rw-r--r-- | fs/namei.c | 10 | ||||
| -rw-r--r-- | fs/open.c | 2 | ||||
| -rw-r--r-- | fs/reiserfs/procfs.c | 99 | ||||
| -rw-r--r-- | fs/reiserfs/super.c | 3 |
5 files changed, 26 insertions, 92 deletions
diff --git a/fs/fcntl.c b/fs/fcntl.c index 6599222536eb..65343c3741ff 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
| @@ -730,14 +730,14 @@ static int __init fcntl_init(void) | |||
| 730 | * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY | 730 | * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY |
| 731 | * is defined as O_NONBLOCK on some platforms and not on others. | 731 | * is defined as O_NONBLOCK on some platforms and not on others. |
| 732 | */ | 732 | */ |
| 733 | BUILD_BUG_ON(19 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( | 733 | BUILD_BUG_ON(20 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( |
| 734 | O_RDONLY | O_WRONLY | O_RDWR | | 734 | O_RDONLY | O_WRONLY | O_RDWR | |
| 735 | O_CREAT | O_EXCL | O_NOCTTY | | 735 | O_CREAT | O_EXCL | O_NOCTTY | |
| 736 | O_TRUNC | O_APPEND | /* O_NONBLOCK | */ | 736 | O_TRUNC | O_APPEND | /* O_NONBLOCK | */ |
| 737 | __O_SYNC | O_DSYNC | FASYNC | | 737 | __O_SYNC | O_DSYNC | FASYNC | |
| 738 | O_DIRECT | O_LARGEFILE | O_DIRECTORY | | 738 | O_DIRECT | O_LARGEFILE | O_DIRECTORY | |
| 739 | O_NOFOLLOW | O_NOATIME | O_CLOEXEC | | 739 | O_NOFOLLOW | O_NOATIME | O_CLOEXEC | |
| 740 | __FMODE_EXEC | O_PATH | 740 | __FMODE_EXEC | O_PATH | __O_TMPFILE |
| 741 | )); | 741 | )); |
| 742 | 742 | ||
| 743 | fasync_cache = kmem_cache_create("fasync_cache", | 743 | fasync_cache = kmem_cache_create("fasync_cache", |
diff --git a/fs/namei.c b/fs/namei.c index 8b61d103a8a7..89a612e392eb 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -3671,15 +3671,11 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, | |||
| 3671 | if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) | 3671 | if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) |
| 3672 | return -EINVAL; | 3672 | return -EINVAL; |
| 3673 | /* | 3673 | /* |
| 3674 | * To use null names we require CAP_DAC_READ_SEARCH | 3674 | * Using empty names is equivalent to using AT_SYMLINK_FOLLOW |
| 3675 | * This ensures that not everyone will be able to create | 3675 | * on /proc/self/fd/<fd>. |
| 3676 | * handlink using the passed filedescriptor. | ||
| 3677 | */ | 3676 | */ |
| 3678 | if (flags & AT_EMPTY_PATH) { | 3677 | if (flags & AT_EMPTY_PATH) |
| 3679 | if (!capable(CAP_DAC_READ_SEARCH)) | ||
| 3680 | return -ENOENT; | ||
| 3681 | how = LOOKUP_EMPTY; | 3678 | how = LOOKUP_EMPTY; |
| 3682 | } | ||
| 3683 | 3679 | ||
| 3684 | if (flags & AT_SYMLINK_FOLLOW) | 3680 | if (flags & AT_SYMLINK_FOLLOW) |
| 3685 | how |= LOOKUP_FOLLOW; | 3681 | how |= LOOKUP_FOLLOW; |
| @@ -823,7 +823,7 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
| 823 | int lookup_flags = 0; | 823 | int lookup_flags = 0; |
| 824 | int acc_mode; | 824 | int acc_mode; |
| 825 | 825 | ||
| 826 | if (flags & O_CREAT) | 826 | if (flags & (O_CREAT | __O_TMPFILE)) |
| 827 | op->mode = (mode & S_IALLUGO) | S_IFREG; | 827 | op->mode = (mode & S_IALLUGO) | S_IFREG; |
| 828 | else | 828 | else |
| 829 | op->mode = 0; | 829 | op->mode = 0; |
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 33532f79b4f7..a958444a75fc 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c | |||
| @@ -19,12 +19,13 @@ | |||
| 19 | /* | 19 | /* |
| 20 | * LOCKING: | 20 | * LOCKING: |
| 21 | * | 21 | * |
| 22 | * We rely on new Alexander Viro's super-block locking. | 22 | * These guys are evicted from procfs as the very first step in ->kill_sb(). |
| 23 | * | 23 | * |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | static int show_version(struct seq_file *m, struct super_block *sb) | 26 | static int show_version(struct seq_file *m, void *unused) |
| 27 | { | 27 | { |
| 28 | struct super_block *sb = m->private; | ||
| 28 | char *format; | 29 | char *format; |
| 29 | 30 | ||
| 30 | if (REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6)) { | 31 | if (REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6)) { |
| @@ -66,8 +67,9 @@ static int show_version(struct seq_file *m, struct super_block *sb) | |||
| 66 | #define DJP( x ) le32_to_cpu( jp -> x ) | 67 | #define DJP( x ) le32_to_cpu( jp -> x ) |
| 67 | #define JF( x ) ( r -> s_journal -> x ) | 68 | #define JF( x ) ( r -> s_journal -> x ) |
| 68 | 69 | ||
| 69 | static int show_super(struct seq_file *m, struct super_block *sb) | 70 | static int show_super(struct seq_file *m, void *unused) |
| 70 | { | 71 | { |
| 72 | struct super_block *sb = m->private; | ||
| 71 | struct reiserfs_sb_info *r = REISERFS_SB(sb); | 73 | struct reiserfs_sb_info *r = REISERFS_SB(sb); |
| 72 | 74 | ||
| 73 | seq_printf(m, "state: \t%s\n" | 75 | seq_printf(m, "state: \t%s\n" |
| @@ -128,8 +130,9 @@ static int show_super(struct seq_file *m, struct super_block *sb) | |||
| 128 | return 0; | 130 | return 0; |
| 129 | } | 131 | } |
| 130 | 132 | ||
| 131 | static int show_per_level(struct seq_file *m, struct super_block *sb) | 133 | static int show_per_level(struct seq_file *m, void *unused) |
| 132 | { | 134 | { |
| 135 | struct super_block *sb = m->private; | ||
| 133 | struct reiserfs_sb_info *r = REISERFS_SB(sb); | 136 | struct reiserfs_sb_info *r = REISERFS_SB(sb); |
| 134 | int level; | 137 | int level; |
| 135 | 138 | ||
| @@ -186,8 +189,9 @@ static int show_per_level(struct seq_file *m, struct super_block *sb) | |||
| 186 | return 0; | 189 | return 0; |
| 187 | } | 190 | } |
| 188 | 191 | ||
| 189 | static int show_bitmap(struct seq_file *m, struct super_block *sb) | 192 | static int show_bitmap(struct seq_file *m, void *unused) |
| 190 | { | 193 | { |
| 194 | struct super_block *sb = m->private; | ||
| 191 | struct reiserfs_sb_info *r = REISERFS_SB(sb); | 195 | struct reiserfs_sb_info *r = REISERFS_SB(sb); |
| 192 | 196 | ||
| 193 | seq_printf(m, "free_block: %lu\n" | 197 | seq_printf(m, "free_block: %lu\n" |
| @@ -218,8 +222,9 @@ static int show_bitmap(struct seq_file *m, struct super_block *sb) | |||
| 218 | return 0; | 222 | return 0; |
| 219 | } | 223 | } |
| 220 | 224 | ||
| 221 | static int show_on_disk_super(struct seq_file *m, struct super_block *sb) | 225 | static int show_on_disk_super(struct seq_file *m, void *unused) |
| 222 | { | 226 | { |
| 227 | struct super_block *sb = m->private; | ||
| 223 | struct reiserfs_sb_info *sb_info = REISERFS_SB(sb); | 228 | struct reiserfs_sb_info *sb_info = REISERFS_SB(sb); |
| 224 | struct reiserfs_super_block *rs = sb_info->s_rs; | 229 | struct reiserfs_super_block *rs = sb_info->s_rs; |
| 225 | int hash_code = DFL(s_hash_function_code); | 230 | int hash_code = DFL(s_hash_function_code); |
| @@ -261,8 +266,9 @@ static int show_on_disk_super(struct seq_file *m, struct super_block *sb) | |||
| 261 | return 0; | 266 | return 0; |
| 262 | } | 267 | } |
| 263 | 268 | ||
| 264 | static int show_oidmap(struct seq_file *m, struct super_block *sb) | 269 | static int show_oidmap(struct seq_file *m, void *unused) |
| 265 | { | 270 | { |
| 271 | struct super_block *sb = m->private; | ||
| 266 | struct reiserfs_sb_info *sb_info = REISERFS_SB(sb); | 272 | struct reiserfs_sb_info *sb_info = REISERFS_SB(sb); |
| 267 | struct reiserfs_super_block *rs = sb_info->s_rs; | 273 | struct reiserfs_super_block *rs = sb_info->s_rs; |
| 268 | unsigned int mapsize = le16_to_cpu(rs->s_v1.s_oid_cursize); | 274 | unsigned int mapsize = le16_to_cpu(rs->s_v1.s_oid_cursize); |
| @@ -291,8 +297,9 @@ static int show_oidmap(struct seq_file *m, struct super_block *sb) | |||
| 291 | return 0; | 297 | return 0; |
| 292 | } | 298 | } |
| 293 | 299 | ||
| 294 | static int show_journal(struct seq_file *m, struct super_block *sb) | 300 | static int show_journal(struct seq_file *m, void *unused) |
| 295 | { | 301 | { |
| 302 | struct super_block *sb = m->private; | ||
| 296 | struct reiserfs_sb_info *r = REISERFS_SB(sb); | 303 | struct reiserfs_sb_info *r = REISERFS_SB(sb); |
| 297 | struct reiserfs_super_block *rs = r->s_rs; | 304 | struct reiserfs_super_block *rs = r->s_rs; |
| 298 | struct journal_params *jp = &rs->s_v1.s_journal; | 305 | struct journal_params *jp = &rs->s_v1.s_journal; |
| @@ -383,92 +390,24 @@ static int show_journal(struct seq_file *m, struct super_block *sb) | |||
| 383 | return 0; | 390 | return 0; |
| 384 | } | 391 | } |
| 385 | 392 | ||
| 386 | /* iterator */ | ||
| 387 | static int test_sb(struct super_block *sb, void *data) | ||
| 388 | { | ||
| 389 | return data == sb; | ||
| 390 | } | ||
| 391 | |||
| 392 | static int set_sb(struct super_block *sb, void *data) | ||
| 393 | { | ||
| 394 | return -ENOENT; | ||
| 395 | } | ||
| 396 | |||
| 397 | struct reiserfs_seq_private { | ||
| 398 | struct super_block *sb; | ||
| 399 | int (*show) (struct seq_file *, struct super_block *); | ||
| 400 | }; | ||
| 401 | |||
| 402 | static void *r_start(struct seq_file *m, loff_t * pos) | ||
| 403 | { | ||
| 404 | struct reiserfs_seq_private *priv = m->private; | ||
| 405< | |||
