Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Pull vfs fixes from Al Viro:
"Fixes for crap of assorted ages: EOPENSTALE one is 4.2+, autofs one is
4.6, d_walk - 3.2+.

The atomic_open() and coredump ones are regressions from this window"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
coredump: fix dumping through pipes
fix a regression in atomic_open()
fix d_walk()/non-delayed __d_free() race
autofs braino fix for do_last()
fix EOPENSTALE bug in do_last()

+24 -52
+1 -1
arch/powerpc/platforms/cell/spufs/coredump.c
··· 172 172 if (rc < 0) 173 173 goto out; 174 174 175 - skip = roundup(cprm->file->f_pos - total + sz, 4) - cprm->file->f_pos; 175 + skip = roundup(cprm->pos - total + sz, 4) - cprm->pos; 176 176 if (!dump_skip(cprm, skip)) 177 177 goto Eio; 178 178 out:
+1 -1
fs/binfmt_elf.c
··· 2275 2275 goto end_coredump; 2276 2276 2277 2277 /* Align to page */ 2278 - if (!dump_skip(cprm, dataoff - cprm->file->f_pos)) 2278 + if (!dump_skip(cprm, dataoff - cprm->pos)) 2279 2279 goto end_coredump; 2280 2280 2281 2281 for (i = 0, vma = first_vma(current, gate_vma); vma != NULL;
+1 -1
fs/binfmt_elf_fdpic.c
··· 1787 1787 goto end_coredump; 1788 1788 } 1789 1789 1790 - if (!dump_skip(cprm, dataoff - cprm->file->f_pos)) 1790 + if (!dump_skip(cprm, dataoff - cprm->pos)) 1791 1791 goto end_coredump; 1792 1792 1793 1793 if (!elf_fdpic_dump_segments(cprm))
+3 -1
fs/coredump.c
··· 794 794 return 0; 795 795 file->f_pos = pos; 796 796 cprm->written += n; 797 + cprm->pos += n; 797 798 nr -= n; 798 799 } 799 800 return 1; ··· 809 808 if (dump_interrupted() || 810 809 file->f_op->llseek(file, nr, SEEK_CUR) < 0) 811 810 return 0; 811 + cprm->pos += nr; 812 812 return 1; 813 813 } else { 814 814 while (nr > PAGE_SIZE) { ··· 824 822 825 823 int dump_align(struct coredump_params *cprm, int align) 826 824 { 827 - unsigned mod = cprm->file->f_pos & (align - 1); 825 + unsigned mod = cprm->pos & (align - 1); 828 826 if (align & (align - 1)) 829 827 return 0; 830 828 return mod ? dump_skip(cprm, align - mod) : 1;
+2 -2
fs/dcache.c
··· 1636 1636 struct dentry *dentry = __d_alloc(parent->d_sb, name); 1637 1637 if (!dentry) 1638 1638 return NULL; 1639 - 1639 + dentry->d_flags |= DCACHE_RCUACCESS; 1640 1640 spin_lock(&parent->d_lock); 1641 1641 /* 1642 1642 * don't need child lock because it is not subject ··· 2358 2358 { 2359 2359 BUG_ON(!d_unhashed(entry)); 2360 2360 hlist_bl_lock(b); 2361 - entry->d_flags |= DCACHE_RCUACCESS; 2362 2361 hlist_bl_add_head_rcu(&entry->d_hash, b); 2363 2362 hlist_bl_unlock(b); 2364 2363 } ··· 2842 2843 /* ... and switch them in the tree */ 2843 2844 if (IS_ROOT(dentry)) { 2844 2845 /* splicing a tree */ 2846 + dentry->d_flags |= DCACHE_RCUACCESS; 2845 2847 dentry->d_parent = target->d_parent; 2846 2848 target->d_parent = target; 2847 2849 list_del_init(&target->d_child);
+15 -46
fs/namei.c
··· 3030 3030 } 3031 3031 if (*opened & FILE_CREATED) 3032 3032 fsnotify_create(dir, dentry); 3033 - path->dentry = dentry; 3034 - path->mnt = nd->path.mnt; 3035 - return 1; 3033 + if (unlikely(d_is_negative(dentry))) { 3034 + error = -ENOENT; 3035 + } else { 3036 + path->dentry = dentry; 3037 + path->mnt = nd->path.mnt; 3038 + return 1; 3039 + } 3036 3040 } 3037 3041 } 3038 3042 dput(dentry); ··· 3205 3201 int acc_mode = op->acc_mode; 3206 3202 unsigned seq; 3207 3203 struct inode *inode; 3208 - struct path save_parent = { .dentry = NULL, .mnt = NULL }; 3209 3204 struct path path; 3210 - bool retried = false; 3211 3205 int error; 3212 3206 3213 3207 nd->flags &= ~LOOKUP_PARENT; ··· 3248 3246 return -EISDIR; 3249 3247 } 3250 3248 3251 - retry_lookup: 3252 3249 if (open_flag & (O_CREAT | O_TRUNC | O_WRONLY | O_RDWR)) { 3253 3250 error = mnt_want_write(nd->path.mnt); 3254 3251 if (!error) ··· 3299 3298 got_write = false; 3300 3299 } 3301 3300 3301 + error = follow_managed(&path, nd); 3302 + if (unlikely(error < 0)) 3303 + return error; 3304 + 3302 3305 if (unlikely(d_is_negative(path.dentry))) { 3303 3306 path_to_nameidata(&path, nd); 3304 3307 return -ENOENT; ··· 3318 3313 return -EEXIST; 3319 3314 } 3320 3315 3321 - error = follow_managed(&path, nd); 3322 - if (unlikely(error < 0)) 3323 - return error; 3324 - 3325 3316 seq = 0; /* out of RCU mode, so the value doesn't matter */ 3326 3317 inode = d_backing_inode(path.dentry); 3327 3318 finish_lookup: ··· 3328 3327 if (unlikely(error)) 3329 3328 return error; 3330 3329 3331 - if ((nd->flags & LOOKUP_RCU) || nd->path.mnt != path.mnt) { 3332 - path_to_nameidata(&path, nd); 3333 - } else { 3334 - save_parent.dentry = nd->path.dentry; 3335 - save_parent.mnt = mntget(path.mnt); 3336 - nd->path.dentry = path.dentry; 3337 - 3338 - } 3330 + path_to_nameidata(&path, nd); 3339 3331 nd->inode = inode; 3340 3332 nd->seq = seq; 3341 3333 /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ 3342 3334 finish_open: 3343 3335 error = complete_walk(nd); 3344 - if (error) { 3345 - path_put(&save_parent); 3336 + if (error) 3346 3337 return error; 3347 - } 3348 3338 audit_inode(nd->name, nd->path.dentry, 0); 3349 3339 error = -EISDIR; 3350 3340 if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry)) ··· 3358 3366 goto out; 3359 3367 BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ 3360 3368 error = vfs_open(&nd->path, file, current_cred()); 3361 - if (!error) { 3362 - *opened |= FILE_OPENED; 3363 - } else { 3364 - if (error == -EOPENSTALE) 3365 - goto stale_open; 3369 + if (error) 3366 3370 goto out; 3367 - } 3371 + *opened |= FILE_OPENED; 3368 3372 opened: 3369 3373 error = open_check_o_direct(file); 3370 3374 if (!error) ··· 3376 3388 } 3377 3389 if (got_write) 3378 3390 mnt_drop_write(nd->path.mnt); 3379 - path_put(&save_parent); 3380 3391 return error; 3381 - 3382 - stale_open: 3383 - /* If no saved parent or already retried then can't retry */ 3384 - if (!save_parent.dentry || retried) 3385 - goto out; 3386 - 3387 - BUG_ON(save_parent.dentry != dir); 3388 - path_put(&nd->path); 3389 - nd->path = save_parent; 3390 - nd->inode = dir->d_inode; 3391 - save_parent.mnt = NULL; 3392 - save_parent.dentry = NULL; 3393 - if (got_write) { 3394 - mnt_drop_write(nd->path.mnt); 3395 - got_write = false; 3396 - } 3397 - retried = true; 3398 - goto retry_lookup; 3399 3392 } 3400 3393 3401 3394 static int do_tmpfile(struct nameidata *nd, unsigned flags,
+1
include/linux/binfmts.h
··· 65 65 unsigned long limit; 66 66 unsigned long mm_flags; 67 67 loff_t written; 68 + loff_t pos; 68 69 }; 69 70 70 71 /*