diff options
-rw-r--r-- | fs/open.c | 2 | ||||
-rw-r--r-- | fs/super.c | 25 | ||||
-rw-r--r-- | include/linux/dcache.h | 2 | ||||
-rw-r--r-- | include/uapi/asm-generic/fcntl.h | 4 |
4 files changed, 15 insertions, 18 deletions
@@ -844,6 +844,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
844 | if ((flags & O_TMPFILE_MASK) != O_TMPFILE) | 844 | if ((flags & O_TMPFILE_MASK) != O_TMPFILE) |
845 | return -EINVAL; | 845 | return -EINVAL; |
846 | acc_mode = MAY_OPEN | ACC_MODE(flags); | 846 | acc_mode = MAY_OPEN | ACC_MODE(flags); |
847 | if (!(acc_mode & MAY_WRITE)) | ||
848 | return -EINVAL; | ||
847 | } else if (flags & O_PATH) { | 849 | } else if (flags & O_PATH) { |
848 | /* | 850 | /* |
849 | * If we have O_PATH in the open flag. Then we | 851 | * If we have O_PATH in the open flag. Then we |
diff --git a/fs/super.c b/fs/super.c index 7465d4364208..68307c029228 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -336,19 +336,19 @@ EXPORT_SYMBOL(deactivate_super); | |||
336 | * and want to turn it into a full-blown active reference. grab_super() | 336 | * and want to turn it into a full-blown active reference. grab_super() |
337 | * is called with sb_lock held and drops it. Returns 1 in case of | 337 | * is called with sb_lock held and drops it. Returns 1 in case of |
338 | * success, 0 if we had failed (superblock contents was already dead or | 338 | * success, 0 if we had failed (superblock contents was already dead or |
339 | * dying when grab_super() had been called). | 339 | * dying when grab_super() had been called). Note that this is only |
340 | * called for superblocks not in rundown mode (== ones still on ->fs_supers | ||
341 | * of their type), so increment of ->s_count is OK here. | ||
340 | */ | 342 | */ |
341 | static int grab_super(struct super_block *s) __releases(sb_lock) | 343 | static int grab_super(struct super_block *s) __releases(sb_lock) |
342 | { | 344 | { |
343 | if (atomic_inc_not_zero(&s->s_active)) { | ||
344 | spin_unlock(&sb_lock); | ||
345 | return 1; | ||
346 | } | ||
347 | /* it's going away */ | ||
348 | s->s_count++; | 345 | s->s_count++; |
349 | spin_unlock(&sb_lock); | 346 | spin_unlock(&sb_lock); |
350 | /* wait for it to die */ | ||
351 | down_write(&s->s_umount); | 347 | down_write(&s->s_umount); |
348 | if ((s->s_flags & MS_BORN) && atomic_inc_not_zero(&s->s_active)) { | ||
349 | put_super(s); | ||
350 | return 1; | ||
351 | } | ||
352 | up_write(&s->s_umount); | 352 | up_write(&s->s_umount); |
353 | put_super(s); | 353 | put_super(s); |
354 | return 0; | 354 | return 0; |
@@ -463,11 +463,6 @@ retry: | |||
463 | destroy_super(s); | 463 | destroy_super(s); |
464 | s = NULL; | 464 | s = NULL; |
465 | } | 465 | } |
466 | down_write(&old->s_umount); | ||
467 | if (unlikely(!(old->s_flags & MS_BORN))) { | ||
468 | deactivate_locked_super(old); | ||
469 | goto retry; | ||
470 | } | ||
471 | return old; | 466 | return old; |
472 | } | 467 | } |
473 | } | 468 | } |
@@ -660,10 +655,10 @@ restart: | |||
660 | if (hlist_unhashed(&sb->s_instances)) | 655 | if (hlist_unhashed(&sb->s_instances)) |
661 | continue; | 656 | continue; |
662 | if (sb->s_bdev == bdev) { | 657 | if (sb->s_bdev == bdev) { |
663 | if (grab_super(sb)) /* drops sb_lock */ | 658 | if (!grab_super(sb)) |
664 | return sb; | ||
665 | else | ||
666 | goto restart; | 659 | goto restart; |
660 | up_write(&sb->s_umount); | ||
661 | return sb; | ||
667 | } | 662 | } |
668 | } | 663 | } |
669 | spin_unlock(&sb_lock); | 664 | spin_unlock(&sb_lock); |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 3092df3614ae..b90337c9d468 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -324,7 +324,7 @@ static inline int __d_rcu_to_refcount(struct dentry *dentry, unsigned seq) | |||
324 | return ret; | 324 | return ret; |
325 | } | 325 | } |
326 | 326 | ||
327 | static inline unsigned d_count(struct dentry *dentry) | 327 | static inline unsigned d_count(const struct dentry *dentry) |
328 | { | 328 | { |
329 | return dentry->d_count; | 329 | return dentry->d_count; |
330 | } | 330 | } |
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h index 05ac354e124d..95e46c8e05f9 100644 --- a/include/uapi/asm-generic/fcntl.h +++ b/include/uapi/asm-generic/fcntl.h | |||
@@ -89,8 +89,8 @@ | |||
89 | #endif | 89 | #endif |
90 | 90 | ||
91 | /* a horrid kludge trying to make sure that this will fail on old kernels */ | 91 | /* a horrid kludge trying to make sure that this will fail on old kernels */ |
92 | #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY | O_RDWR) | 92 | #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) |
93 | #define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT | O_ACCMODE) | 93 | #define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT) |
94 | 94 | ||
95 | #ifndef O_NDELAY | 95 | #ifndef O_NDELAY |
96 | #define O_NDELAY O_NONBLOCK | 96 | #define O_NDELAY O_NONBLOCK |