Commit 36231d255b8df9cb4698e9a3902c16067d5c1398

Authored by Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs fixes from Al Viro:
 "The sget() one is a long-standing bug and will need to go into -stable
  (in fact, it had been originally caught in RHEL6), the other two are
  3.11-only"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  vfs: constify dentry parameter in d_count()
  livelock avoidance in sget()
  allow O_TMPFILE to work with O_WRONLY

Showing 4 changed files Side-by-side Diff

... ... @@ -844,6 +844,8 @@
844 844 if ((flags & O_TMPFILE_MASK) != O_TMPFILE)
845 845 return -EINVAL;
846 846 acc_mode = MAY_OPEN | ACC_MODE(flags);
  847 + if (!(acc_mode & MAY_WRITE))
  848 + return -EINVAL;
847 849 } else if (flags & O_PATH) {
848 850 /*
849 851 * If we have O_PATH in the open flag. Then we
... ... @@ -336,19 +336,19 @@
336 336 * and want to turn it into a full-blown active reference. grab_super()
337 337 * is called with sb_lock held and drops it. Returns 1 in case of
338 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 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 345 s->s_count++;
349 346 spin_unlock(&sb_lock);
350   - /* wait for it to die */
351 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 352 up_write(&s->s_umount);
353 353 put_super(s);
354 354 return 0;
... ... @@ -463,11 +463,6 @@
463 463 destroy_super(s);
464 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 466 return old;
472 467 }
473 468 }
474 469  
... ... @@ -660,10 +655,10 @@
660 655 if (hlist_unhashed(&sb->s_instances))
661 656 continue;
662 657 if (sb->s_bdev == bdev) {
663   - if (grab_super(sb)) /* drops sb_lock */
664   - return sb;
665   - else
  658 + if (!grab_super(sb))
666 659 goto restart;
  660 + up_write(&sb->s_umount);
  661 + return sb;
667 662 }
668 663 }
669 664 spin_unlock(&sb_lock);
include/linux/dcache.h
... ... @@ -324,7 +324,7 @@
324 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 329 return dentry->d_count;
330 330 }
include/uapi/asm-generic/fcntl.h
... ... @@ -89,8 +89,8 @@
89 89 #endif
90 90  
91 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)
93   -#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT | O_ACCMODE)
  92 +#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
  93 +#define O_TMPFILE_MASK (__O_TMPFILE | O_DIRECTORY | O_CREAT)
94 94  
95 95 #ifndef O_NDELAY
96 96 #define O_NDELAY O_NONBLOCK