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

Configure Feed

Select the types of activity you want to include in your feed.

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

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
JFS: Free sbi memory in error path
fs/sysv: dereferencing ERR_PTR()
Fix double-free in logfs
Fix the regression created by "set S_DEAD on unlink()..." commit

+49 -26
+1
drivers/usb/core/inode.c
··· 380 380 mutex_lock(&inode->i_mutex); 381 381 dentry_unhash(dentry); 382 382 if (usbfs_empty(dentry)) { 383 + dont_mount(dentry); 383 384 drop_nlink(dentry->d_inode); 384 385 drop_nlink(dentry->d_inode); 385 386 dput(dentry);
+4
fs/configfs/dir.c
··· 645 645 646 646 configfs_detach_group(sd->s_element); 647 647 child->d_inode->i_flags |= S_DEAD; 648 + dont_mount(child); 648 649 649 650 mutex_unlock(&child->d_inode->i_mutex); 650 651 ··· 841 840 mutex_lock(&dentry->d_inode->i_mutex); 842 841 configfs_remove_dir(item); 843 842 dentry->d_inode->i_flags |= S_DEAD; 843 + dont_mount(dentry); 844 844 mutex_unlock(&dentry->d_inode->i_mutex); 845 845 d_delete(dentry); 846 846 } ··· 884 882 if (ret) { 885 883 configfs_detach_item(item); 886 884 dentry->d_inode->i_flags |= S_DEAD; 885 + dont_mount(dentry); 887 886 } 888 887 configfs_adjust_dir_dirent_depth_after_populate(sd); 889 888 mutex_unlock(&dentry->d_inode->i_mutex); ··· 1728 1725 mutex_unlock(&configfs_symlink_mutex); 1729 1726 configfs_detach_group(&group->cg_item); 1730 1727 dentry->d_inode->i_flags |= S_DEAD; 1728 + dont_mount(dentry); 1731 1729 mutex_unlock(&dentry->d_inode->i_mutex); 1732 1730 1733 1731 d_delete(dentry);
+6 -7
fs/jfs/super.c
··· 446 446 /* initialize the mount flag and determine the default error handler */ 447 447 flag = JFS_ERR_REMOUNT_RO; 448 448 449 - if (!parse_options((char *) data, sb, &newLVSize, &flag)) { 450 - kfree(sbi); 451 - return -EINVAL; 452 - } 449 + if (!parse_options((char *) data, sb, &newLVSize, &flag)) 450 + goto out_kfree; 453 451 sbi->flag = flag; 454 452 455 453 #ifdef CONFIG_JFS_POSIX_ACL ··· 456 458 457 459 if (newLVSize) { 458 460 printk(KERN_ERR "resize option for remount only\n"); 459 - return -EINVAL; 461 + goto out_kfree; 460 462 } 461 463 462 464 /* ··· 476 478 inode = new_inode(sb); 477 479 if (inode == NULL) { 478 480 ret = -ENOMEM; 479 - goto out_kfree; 481 + goto out_unload; 480 482 } 481 483 inode->i_ino = 0; 482 484 inode->i_nlink = 1; ··· 548 550 make_bad_inode(sbi->direct_inode); 549 551 iput(sbi->direct_inode); 550 552 sbi->direct_inode = NULL; 551 - out_kfree: 553 + out_unload: 552 554 if (sbi->nls_tab) 553 555 unload_nls(sbi->nls_tab); 556 + out_kfree: 554 557 kfree(sbi); 555 558 return ret; 556 559 }
+7 -7
fs/logfs/super.c
··· 333 333 goto fail; 334 334 335 335 sb->s_root = d_alloc_root(rootdir); 336 - if (!sb->s_root) 337 - goto fail2; 336 + if (!sb->s_root) { 337 + iput(rootdir); 338 + goto fail; 339 + } 338 340 339 341 super->s_erase_page = alloc_pages(GFP_KERNEL, 0); 340 342 if (!super->s_erase_page) 341 - goto fail2; 343 + goto fail; 342 344 memset(page_address(super->s_erase_page), 0xFF, PAGE_SIZE); 343 345 344 346 /* FIXME: check for read-only mounts */ 345 347 err = logfs_make_writeable(sb); 346 348 if (err) 347 - goto fail3; 349 + goto fail1; 348 350 349 351 log_super("LogFS: Finished mounting\n"); 350 352 simple_set_mnt(mnt, sb); 351 353 return 0; 352 354 353 - fail3: 355 + fail1: 354 356 __free_page(super->s_erase_page); 355 - fail2: 356 - iput(rootdir); 357 357 fail: 358 358 iput(logfs_super(sb)->s_master_inode); 359 359 return -EIO;
+13 -8
fs/namei.c
··· 2176 2176 error = security_inode_rmdir(dir, dentry); 2177 2177 if (!error) { 2178 2178 error = dir->i_op->rmdir(dir, dentry); 2179 - if (!error) 2179 + if (!error) { 2180 2180 dentry->d_inode->i_flags |= S_DEAD; 2181 + dont_mount(dentry); 2182 + } 2181 2183 } 2182 2184 } 2183 2185 mutex_unlock(&dentry->d_inode->i_mutex); ··· 2263 2261 if (!error) { 2264 2262 error = dir->i_op->unlink(dir, dentry); 2265 2263 if (!error) 2266 - dentry->d_inode->i_flags |= S_DEAD; 2264 + dont_mount(dentry); 2267 2265 } 2268 2266 } 2269 2267 mutex_unlock(&dentry->d_inode->i_mutex); ··· 2574 2572 return error; 2575 2573 2576 2574 target = new_dentry->d_inode; 2577 - if (target) { 2575 + if (target) 2578 2576 mutex_lock(&target->i_mutex); 2579 - dentry_unhash(new_dentry); 2580 - } 2581 2577 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) 2582 2578 error = -EBUSY; 2583 - else 2579 + else { 2580 + if (target) 2581 + dentry_unhash(new_dentry); 2584 2582 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); 2583 + } 2585 2584 if (target) { 2586 - if (!error) 2585 + if (!error) { 2587 2586 target->i_flags |= S_DEAD; 2587 + dont_mount(new_dentry); 2588 + } 2588 2589 mutex_unlock(&target->i_mutex); 2589 2590 if (d_unhashed(new_dentry)) 2590 2591 d_rehash(new_dentry); ··· 2619 2614 error = old_dir->i_op->rename(old_dir, old_dentry, new_dir, new_dentry); 2620 2615 if (!error) { 2621 2616 if (target) 2622 - target->i_flags |= S_DEAD; 2617 + dont_mount(new_dentry); 2623 2618 if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) 2624 2619 d_move(old_dentry, new_dentry); 2625 2620 }
+3 -3
fs/namespace.c
··· 1432 1432 1433 1433 err = -ENOENT; 1434 1434 mutex_lock(&path->dentry->d_inode->i_mutex); 1435 - if (IS_DEADDIR(path->dentry->d_inode)) 1435 + if (cant_mount(path->dentry)) 1436 1436 goto out_unlock; 1437 1437 1438 1438 err = security_sb_check_sb(mnt, path); ··· 1623 1623 1624 1624 err = -ENOENT; 1625 1625 mutex_lock(&path->dentry->d_inode->i_mutex); 1626 - if (IS_DEADDIR(path->dentry->d_inode)) 1626 + if (cant_mount(path->dentry)) 1627 1627 goto out1; 1628 1628 1629 1629 if (d_unlinked(path->dentry)) ··· 2234 2234 if (!check_mnt(root.mnt)) 2235 2235 goto out2; 2236 2236 error = -ENOENT; 2237 - if (IS_DEADDIR(new.dentry->d_inode)) 2237 + if (cant_mount(old.dentry)) 2238 2238 goto out2; 2239 2239 if (d_unlinked(new.dentry)) 2240 2240 goto out2;
+1 -1
fs/sysv/dir.c
··· 164 164 name, de->name)) 165 165 goto found; 166 166 } 167 + dir_put_page(page); 167 168 } 168 - dir_put_page(page); 169 169 170 170 if (++n >= npages) 171 171 n = 0;
+14
include/linux/dcache.h
··· 186 186 187 187 #define DCACHE_FSNOTIFY_PARENT_WATCHED 0x0080 /* Parent inode is watched by some fsnotify listener */ 188 188 189 + #define DCACHE_CANT_MOUNT 0x0100 190 + 189 191 extern spinlock_t dcache_lock; 190 192 extern seqlock_t rename_lock; 191 193 ··· 358 356 static inline int d_unlinked(struct dentry *dentry) 359 357 { 360 358 return d_unhashed(dentry) && !IS_ROOT(dentry); 359 + } 360 + 361 + static inline int cant_mount(struct dentry *dentry) 362 + { 363 + return (dentry->d_flags & DCACHE_CANT_MOUNT); 364 + } 365 + 366 + static inline void dont_mount(struct dentry *dentry) 367 + { 368 + spin_lock(&dentry->d_lock); 369 + dentry->d_flags |= DCACHE_CANT_MOUNT; 370 + spin_unlock(&dentry->d_lock); 361 371 } 362 372 363 373 static inline struct dentry *dget_parent(struct dentry *dentry)