Commit 7e05b807b93cc553bc2aa5ae8fac620cece34720
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull VFS fixes from Al Viro: "A bunch of assorted fixes, most of them followups to overlayfs merge" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: ovl: initialize ->is_cursor Return short read or 0 at end of a raw device, not EIO isofs: don't bother with ->d_op for normal case isofs_cmp(): we'll never see a dentry for . or .. overlayfs: fix lockdep misannotation ovl: fix check for cursor overlayfs: barriers for opening upper-layer directory rcu: Provide counterpart to rcu_dereference() for non-RCU situations staging: android: logger: Fix log corruption regression
Showing 9 changed files Side-by-side Diff
drivers/char/raw.c
... | ... | @@ -285,7 +285,7 @@ |
285 | 285 | |
286 | 286 | static const struct file_operations raw_fops = { |
287 | 287 | .read = new_sync_read, |
288 | - .read_iter = generic_file_read_iter, | |
288 | + .read_iter = blkdev_read_iter, | |
289 | 289 | .write = new_sync_write, |
290 | 290 | .write_iter = blkdev_write_iter, |
291 | 291 | .fsync = blkdev_fsync, |
drivers/staging/android/logger.c
... | ... | @@ -420,7 +420,7 @@ |
420 | 420 | struct logger_log *log = file_get_log(iocb->ki_filp); |
421 | 421 | struct logger_entry header; |
422 | 422 | struct timespec now; |
423 | - size_t len, count; | |
423 | + size_t len, count, w_off; | |
424 | 424 | |
425 | 425 | count = min_t(size_t, iocb->ki_nbytes, LOGGER_ENTRY_MAX_PAYLOAD); |
426 | 426 | |
427 | 427 | |
428 | 428 | |
... | ... | @@ -452,11 +452,14 @@ |
452 | 452 | memcpy(log->buffer + log->w_off, &header, len); |
453 | 453 | memcpy(log->buffer, (char *)&header + len, sizeof(header) - len); |
454 | 454 | |
455 | - len = min(count, log->size - log->w_off); | |
455 | + /* Work with a copy until we are ready to commit the whole entry */ | |
456 | + w_off = logger_offset(log, log->w_off + sizeof(struct logger_entry)); | |
456 | 457 | |
457 | - if (copy_from_iter(log->buffer + log->w_off, len, from) != len) { | |
458 | + len = min(count, log->size - w_off); | |
459 | + | |
460 | + if (copy_from_iter(log->buffer + w_off, len, from) != len) { | |
458 | 461 | /* |
459 | - * Note that by not updating w_off, this abandons the | |
462 | + * Note that by not updating log->w_off, this abandons the | |
460 | 463 | * portion of the new entry that *was* successfully |
461 | 464 | * copied, just above. This is intentional to avoid |
462 | 465 | * message corruption from missing fragments. |
... | ... | @@ -470,7 +473,7 @@ |
470 | 473 | return -EFAULT; |
471 | 474 | } |
472 | 475 | |
473 | - log->w_off = logger_offset(log, log->w_off + count); | |
476 | + log->w_off = logger_offset(log, w_off + count); | |
474 | 477 | mutex_unlock(&log->mutex); |
475 | 478 | |
476 | 479 | /* wake up any blocked readers */ |
fs/block_dev.c
... | ... | @@ -1585,7 +1585,7 @@ |
1585 | 1585 | } |
1586 | 1586 | EXPORT_SYMBOL_GPL(blkdev_write_iter); |
1587 | 1587 | |
1588 | -static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) | |
1588 | +ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to) | |
1589 | 1589 | { |
1590 | 1590 | struct file *file = iocb->ki_filp; |
1591 | 1591 | struct inode *bd_inode = file->f_mapping->host; |
... | ... | @@ -1599,6 +1599,7 @@ |
1599 | 1599 | iov_iter_truncate(to, size); |
1600 | 1600 | return generic_file_read_iter(iocb, to); |
1601 | 1601 | } |
1602 | +EXPORT_SYMBOL_GPL(blkdev_read_iter); | |
1602 | 1603 | |
1603 | 1604 | /* |
1604 | 1605 | * Try to release a page associated with block device when the system |
fs/isofs/inode.c
... | ... | @@ -29,13 +29,9 @@ |
29 | 29 | #define BEQUIET |
30 | 30 | |
31 | 31 | static int isofs_hashi(const struct dentry *parent, struct qstr *qstr); |
32 | -static int isofs_hash(const struct dentry *parent, struct qstr *qstr); | |
33 | 32 | static int isofs_dentry_cmpi(const struct dentry *parent, |
34 | 33 | const struct dentry *dentry, |
35 | 34 | unsigned int len, const char *str, const struct qstr *name); |
36 | -static int isofs_dentry_cmp(const struct dentry *parent, | |
37 | - const struct dentry *dentry, | |
38 | - unsigned int len, const char *str, const struct qstr *name); | |
39 | 35 | |
40 | 36 | #ifdef CONFIG_JOLIET |
41 | 37 | static int isofs_hashi_ms(const struct dentry *parent, struct qstr *qstr); |
... | ... | @@ -135,10 +131,6 @@ |
135 | 131 | |
136 | 132 | static const struct dentry_operations isofs_dentry_ops[] = { |
137 | 133 | { |
138 | - .d_hash = isofs_hash, | |
139 | - .d_compare = isofs_dentry_cmp, | |
140 | - }, | |
141 | - { | |
142 | 134 | .d_hash = isofs_hashi, |
143 | 135 | .d_compare = isofs_dentry_cmpi, |
144 | 136 | }, |
145 | 137 | |
... | ... | @@ -258,25 +250,12 @@ |
258 | 250 | } |
259 | 251 | |
260 | 252 | static int |
261 | -isofs_hash(const struct dentry *dentry, struct qstr *qstr) | |
262 | -{ | |
263 | - return isofs_hash_common(qstr, 0); | |
264 | -} | |
265 | - | |
266 | -static int | |
267 | 253 | isofs_hashi(const struct dentry *dentry, struct qstr *qstr) |
268 | 254 | { |
269 | 255 | return isofs_hashi_common(qstr, 0); |
270 | 256 | } |
271 | 257 | |
272 | 258 | static int |
273 | -isofs_dentry_cmp(const struct dentry *parent, const struct dentry *dentry, | |
274 | - unsigned int len, const char *str, const struct qstr *name) | |
275 | -{ | |
276 | - return isofs_dentry_cmp_common(len, str, name, 0, 0); | |
277 | -} | |
278 | - | |
279 | -static int | |
280 | 259 | isofs_dentry_cmpi(const struct dentry *parent, const struct dentry *dentry, |
281 | 260 | unsigned int len, const char *str, const struct qstr *name) |
282 | 261 | { |
... | ... | @@ -930,7 +909,8 @@ |
930 | 909 | if (opt.check == 'r') |
931 | 910 | table++; |
932 | 911 | |
933 | - s->s_d_op = &isofs_dentry_ops[table]; | |
912 | + if (table) | |
913 | + s->s_d_op = &isofs_dentry_ops[table - 1]; | |
934 | 914 | |
935 | 915 | /* get the root dentry */ |
936 | 916 | s->s_root = d_make_root(inode); |
fs/isofs/namei.c
... | ... | @@ -18,25 +18,10 @@ |
18 | 18 | isofs_cmp(struct dentry *dentry, const char *compare, int dlen) |
19 | 19 | { |
20 | 20 | struct qstr qstr; |
21 | - | |
22 | - if (!compare) | |
23 | - return 1; | |
24 | - | |
25 | - /* check special "." and ".." files */ | |
26 | - if (dlen == 1) { | |
27 | - /* "." */ | |
28 | - if (compare[0] == 0) { | |
29 | - if (!dentry->d_name.len) | |
30 | - return 0; | |
31 | - compare = "."; | |
32 | - } else if (compare[0] == 1) { | |
33 | - compare = ".."; | |
34 | - dlen = 2; | |
35 | - } | |
36 | - } | |
37 | - | |
38 | 21 | qstr.name = compare; |
39 | 22 | qstr.len = dlen; |
23 | + if (likely(!dentry->d_op)) | |
24 | + return dentry->d_name.len != dlen || memcmp(dentry->d_name.name, compare, dlen); | |
40 | 25 | return dentry->d_op->d_compare(NULL, NULL, dentry->d_name.len, dentry->d_name.name, &qstr); |
41 | 26 | } |
42 | 27 | |
... | ... | @@ -146,7 +131,8 @@ |
146 | 131 | (!(de->flags[-sbi->s_high_sierra] & 1))) && |
147 | 132 | (sbi->s_showassoc || |
148 | 133 | (!(de->flags[-sbi->s_high_sierra] & 4)))) { |
149 | - match = (isofs_cmp(dentry, dpnt, dlen) == 0); | |
134 | + if (dpnt && (dlen > 1 || dpnt[0] > 1)) | |
135 | + match = (isofs_cmp(dentry, dpnt, dlen) == 0); | |
150 | 136 | } |
151 | 137 | if (match) { |
152 | 138 | isofs_normalize_block_and_offset(de, |
fs/namei.c
... | ... | @@ -2497,7 +2497,7 @@ |
2497 | 2497 | } |
2498 | 2498 | |
2499 | 2499 | mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT); |
2500 | - mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD); | |
2500 | + mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT2); | |
2501 | 2501 | return NULL; |
2502 | 2502 | } |
2503 | 2503 | EXPORT_SYMBOL(lock_rename); |
fs/overlayfs/readdir.c
... | ... | @@ -21,9 +21,10 @@ |
21 | 21 | unsigned int len; |
22 | 22 | unsigned int type; |
23 | 23 | u64 ino; |
24 | - bool is_whiteout; | |
25 | 24 | struct list_head l_node; |
26 | 25 | struct rb_node node; |
26 | + bool is_whiteout; | |
27 | + bool is_cursor; | |
27 | 28 | char name[]; |
28 | 29 | }; |
29 | 30 | |
... | ... | @@ -92,6 +93,7 @@ |
92 | 93 | p->type = d_type; |
93 | 94 | p->ino = ino; |
94 | 95 | p->is_whiteout = false; |
96 | + p->is_cursor = false; | |
95 | 97 | } |
96 | 98 | |
97 | 99 | return p; |
... | ... | @@ -251,7 +253,7 @@ |
251 | 253 | |
252 | 254 | mutex_lock(&dir->d_inode->i_mutex); |
253 | 255 | list_for_each_entry(p, rdd->list, l_node) { |
254 | - if (!p->name) | |
256 | + if (p->is_cursor) | |
255 | 257 | continue; |
256 | 258 | |
257 | 259 | if (p->type != DT_CHR) |
... | ... | @@ -307,7 +309,6 @@ |
307 | 309 | } |
308 | 310 | out: |
309 | 311 | return err; |
310 | - | |
311 | 312 | } |
312 | 313 | |
313 | 314 | static void ovl_seek_cursor(struct ovl_dir_file *od, loff_t pos) |
... | ... | @@ -316,7 +317,7 @@ |
316 | 317 | loff_t off = 0; |
317 | 318 | |
318 | 319 | list_for_each_entry(p, &od->cache->entries, l_node) { |
319 | - if (!p->name) | |
320 | + if (p->is_cursor) | |
320 | 321 | continue; |
321 | 322 | if (off >= pos) |
322 | 323 | break; |
... | ... | @@ -389,7 +390,7 @@ |
389 | 390 | |
390 | 391 | p = list_entry(od->cursor.l_node.next, struct ovl_cache_entry, l_node); |
391 | 392 | /* Skip cursors */ |
392 | - if (p->name) { | |
393 | + if (!p->is_cursor) { | |
393 | 394 | if (!p->is_whiteout) { |
394 | 395 | if (!dir_emit(ctx, p->name, p->len, p->ino, p->type)) |
395 | 396 | break; |
396 | 397 | |
... | ... | @@ -454,12 +455,13 @@ |
454 | 455 | if (!od->is_upper && ovl_path_type(dentry) == OVL_PATH_MERGE) { |
455 | 456 | struct inode *inode = file_inode(file); |
456 | 457 | |
457 | - realfile = od->upperfile; | |
458 | + realfile =lockless_dereference(od->upperfile); | |
458 | 459 | if (!realfile) { |
459 | 460 | struct path upperpath; |
460 | 461 | |
461 | 462 | ovl_path_upper(dentry, &upperpath); |
462 | 463 | realfile = ovl_path_open(&upperpath, O_RDONLY); |
464 | + smp_mb__before_spinlock(); | |
463 | 465 | mutex_lock(&inode->i_mutex); |
464 | 466 | if (!od->upperfile) { |
465 | 467 | if (IS_ERR(realfile)) { |
... | ... | @@ -518,6 +520,7 @@ |
518 | 520 | od->realfile = realfile; |
519 | 521 | od->is_real = (type != OVL_PATH_MERGE); |
520 | 522 | od->is_upper = (type != OVL_PATH_LOWER); |
523 | + od->cursor.is_cursor = true; | |
521 | 524 | file->private_data = od; |
522 | 525 | |
523 | 526 | return 0; |
... | ... | @@ -569,7 +572,7 @@ |
569 | 572 | { |
570 | 573 | struct ovl_cache_entry *p; |
571 | 574 | |
572 | - mutex_lock_nested(&upper->d_inode->i_mutex, I_MUTEX_PARENT); | |
575 | + mutex_lock_nested(&upper->d_inode->i_mutex, I_MUTEX_CHILD); | |
573 | 576 | list_for_each_entry(p, list, l_node) { |
574 | 577 | struct dentry *dentry; |
575 | 578 |
include/linux/fs.h
... | ... | @@ -639,11 +639,13 @@ |
639 | 639 | * 2: child/target |
640 | 640 | * 3: xattr |
641 | 641 | * 4: second non-directory |
642 | - * The last is for certain operations (such as rename) which lock two | |
642 | + * 5: second parent (when locking independent directories in rename) | |
643 | + * | |
644 | + * I_MUTEX_NONDIR2 is for certain operations (such as rename) which lock two | |
643 | 645 | * non-directories at once. |
644 | 646 | * |
645 | 647 | * The locking order between these classes is |
646 | - * parent -> child -> normal -> xattr -> second non-directory | |
648 | + * parent[2] -> child -> grandchild -> normal -> xattr -> second non-directory | |
647 | 649 | */ |
648 | 650 | enum inode_i_mutex_lock_class |
649 | 651 | { |
... | ... | @@ -651,7 +653,8 @@ |
651 | 653 | I_MUTEX_PARENT, |
652 | 654 | I_MUTEX_CHILD, |
653 | 655 | I_MUTEX_XATTR, |
654 | - I_MUTEX_NONDIR2 | |
656 | + I_MUTEX_NONDIR2, | |
657 | + I_MUTEX_PARENT2, | |
655 | 658 | }; |
656 | 659 | |
657 | 660 | void lock_two_nondirectories(struct inode *, struct inode*); |
... | ... | @@ -2466,6 +2469,7 @@ |
2466 | 2469 | extern ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos); |
2467 | 2470 | |
2468 | 2471 | /* fs/block_dev.c */ |
2472 | +extern ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to); | |
2469 | 2473 | extern ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from); |
2470 | 2474 | extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end, |
2471 | 2475 | int datasync); |
include/linux/rcupdate.h
... | ... | @@ -617,6 +617,21 @@ |
617 | 617 | #define RCU_INITIALIZER(v) (typeof(*(v)) __force __rcu *)(v) |
618 | 618 | |
619 | 619 | /** |
620 | + * lockless_dereference() - safely load a pointer for later dereference | |
621 | + * @p: The pointer to load | |
622 | + * | |
623 | + * Similar to rcu_dereference(), but for situations where the pointed-to | |
624 | + * object's lifetime is managed by something other than RCU. That | |
625 | + * "something other" might be reference counting or simple immortality. | |
626 | + */ | |
627 | +#define lockless_dereference(p) \ | |
628 | +({ \ | |
629 | + typeof(p) _________p1 = ACCESS_ONCE(p); \ | |
630 | + smp_read_barrier_depends(); /* Dependency order vs. p above. */ \ | |
631 | + (_________p1); \ | |
632 | +}) | |
633 | + | |
634 | +/** | |
620 | 635 | * rcu_assign_pointer() - assign to RCU-protected pointer |
621 | 636 | * @p: pointer to assign to |
622 | 637 | * @v: value to assign (publish) |