diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 84 |
1 files changed, 53 insertions, 31 deletions
diff --git a/fs/namei.c b/fs/namei.c index 8dc2b038d5d9..22f6e8d16aa8 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -104,7 +104,7 @@ | |||
104 | */ | 104 | */ |
105 | /* | 105 | /* |
106 | * [Sep 2001 AV] Single-semaphore locking scheme (kudos to David Holland) | 106 | * [Sep 2001 AV] Single-semaphore locking scheme (kudos to David Holland) |
107 | * implemented. Let's see if raised priority of ->s_vfs_rename_sem gives | 107 | * implemented. Let's see if raised priority of ->s_vfs_rename_mutex gives |
108 | * any extra contention... | 108 | * any extra contention... |
109 | */ | 109 | */ |
110 | 110 | ||
@@ -546,6 +546,22 @@ struct path { | |||
546 | struct dentry *dentry; | 546 | struct dentry *dentry; |
547 | }; | 547 | }; |
548 | 548 | ||
549 | static inline void dput_path(struct path *path, struct nameidata *nd) | ||
550 | { | ||
551 | dput(path->dentry); | ||
552 | if (path->mnt != nd->mnt) | ||
553 | mntput(path->mnt); | ||
554 | } | ||
555 | |||
556 | static inline void path_to_nameidata(struct path *path, struct nameidata *nd) | ||
557 | { | ||
558 | dput(nd->dentry); | ||
559 | if (nd->mnt != path->mnt) | ||
560 | mntput(nd->mnt); | ||
561 | nd->mnt = path->mnt; | ||
562 | nd->dentry = path->dentry; | ||
563 | } | ||
564 | |||
549 | static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd) | 565 | static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd) |
550 | { | 566 | { |
551 | int error; | 567 | int error; |
@@ -555,8 +571,11 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata | |||
555 | touch_atime(path->mnt, dentry); | 571 | touch_atime(path->mnt, dentry); |
556 | nd_set_link(nd, NULL); | 572 | nd_set_link(nd, NULL); |
557 | 573 | ||
558 | if (path->mnt == nd->mnt) | 574 | if (path->mnt != nd->mnt) { |
559 | mntget(path->mnt); | 575 | path_to_nameidata(path, nd); |
576 | dget(dentry); | ||
577 | } | ||
578 | mntget(path->mnt); | ||
560 | cookie = dentry->d_inode->i_op->follow_link(dentry, nd); | 579 | cookie = dentry->d_inode->i_op->follow_link(dentry, nd); |
561 | error = PTR_ERR(cookie); | 580 | error = PTR_ERR(cookie); |
562 | if (!IS_ERR(cookie)) { | 581 | if (!IS_ERR(cookie)) { |
@@ -573,22 +592,6 @@ static __always_inline int __do_follow_link(struct path *path, struct nameidata | |||
573 | return error; | 592 | return error; |
574 | } | 593 | } |
575 | 594 | ||
576 | static inline void dput_path(struct path *path, struct nameidata *nd) | ||
577 | { | ||
578 | dput(path->dentry); | ||
579 | if (path->mnt != nd->mnt) | ||
580 | mntput(path->mnt); | ||
581 | } | ||
582 | |||
583 | static inline void path_to_nameidata(struct path *path, struct nameidata *nd) | ||
584 | { | ||
585 | dput(nd->dentry); | ||
586 | if (nd->mnt != path->mnt) | ||
587 | mntput(nd->mnt); | ||
588 | nd->mnt = path->mnt; | ||
589 | nd->dentry = path->dentry; | ||
590 | } | ||
591 | |||
592 | /* | 595 | /* |
593 | * This limits recursive symlink follows to 8, while | 596 | * This limits recursive symlink follows to 8, while |
594 | * limiting consecutive symlinks to 40. | 597 | * limiting consecutive symlinks to 40. |
@@ -1353,6 +1356,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir) | |||
1353 | return -ENOENT; | 1356 | return -ENOENT; |
1354 | 1357 | ||
1355 | BUG_ON(victim->d_parent->d_inode != dir); | 1358 | BUG_ON(victim->d_parent->d_inode != dir); |
1359 | audit_inode_child(victim->d_name.name, victim->d_inode, dir->i_ino); | ||
1356 | 1360 | ||
1357 | error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); | 1361 | error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); |
1358 | if (error) | 1362 | if (error) |
@@ -1422,7 +1426,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) | |||
1422 | return NULL; | 1426 | return NULL; |
1423 | } | 1427 | } |
1424 | 1428 | ||
1425 | down(&p1->d_inode->i_sb->s_vfs_rename_sem); | 1429 | mutex_lock(&p1->d_inode->i_sb->s_vfs_rename_mutex); |
1426 | 1430 | ||
1427 | for (p = p1; p->d_parent != p; p = p->d_parent) { | 1431 | for (p = p1; p->d_parent != p; p = p->d_parent) { |
1428 | if (p->d_parent == p2) { | 1432 | if (p->d_parent == p2) { |
@@ -1450,7 +1454,7 @@ void unlock_rename(struct dentry *p1, struct dentry *p2) | |||
1450 | mutex_unlock(&p1->d_inode->i_mutex); | 1454 | mutex_unlock(&p1->d_inode->i_mutex); |
1451 | if (p1 != p2) { | 1455 | if (p1 != p2) { |
1452 | mutex_unlock(&p2->d_inode->i_mutex); | 1456 | mutex_unlock(&p2->d_inode->i_mutex); |
1453 | up(&p1->d_inode->i_sb->s_vfs_rename_sem); | 1457 | mutex_unlock(&p1->d_inode->i_sb->s_vfs_rename_mutex); |
1454 | } | 1458 | } |
1455 | } | 1459 | } |
1456 | 1460 | ||
@@ -1472,7 +1476,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1472 | DQUOT_INIT(dir); | 1476 | DQUOT_INIT(dir); |
1473 | error = dir->i_op->create(dir, dentry, mode, nd); | 1477 | error = dir->i_op->create(dir, dentry, mode, nd); |
1474 | if (!error) | 1478 | if (!error) |
1475 | fsnotify_create(dir, dentry->d_name.name); | 1479 | fsnotify_create(dir, dentry); |
1476 | return error; | 1480 | return error; |
1477 | } | 1481 | } |
1478 | 1482 | ||
@@ -1628,6 +1632,12 @@ do_last: | |||
1628 | goto exit; | 1632 | goto exit; |
1629 | } | 1633 | } |
1630 | 1634 | ||
1635 | if (IS_ERR(nd->intent.open.file)) { | ||
1636 | mutex_unlock(&dir->d_inode->i_mutex); | ||
1637 | error = PTR_ERR(nd->intent.open.file); | ||
1638 | goto exit_dput; | ||
1639 | } | ||
1640 | |||
1631 | /* Negative dentry, just create the file */ | 1641 | /* Negative dentry, just create the file */ |
1632 | if (!path.dentry->d_inode) { | 1642 | if (!path.dentry->d_inode) { |
1633 | if (!IS_POSIXACL(dir->d_inode)) | 1643 | if (!IS_POSIXACL(dir->d_inode)) |
@@ -1793,7 +1803,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
1793 | DQUOT_INIT(dir); | 1803 | DQUOT_INIT(dir); |
1794 | error = dir->i_op->mknod(dir, dentry, mode, dev); | 1804 | error = dir->i_op->mknod(dir, dentry, mode, dev); |
1795 | if (!error) | 1805 | if (!error) |
1796 | fsnotify_create(dir, dentry->d_name.name); | 1806 | fsnotify_create(dir, dentry); |
1797 | return error; | 1807 | return error; |
1798 | } | 1808 | } |
1799 | 1809 | ||
@@ -1870,7 +1880,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
1870 | DQUOT_INIT(dir); | 1880 | DQUOT_INIT(dir); |
1871 | error = dir->i_op->mkdir(dir, dentry, mode); | 1881 | error = dir->i_op->mkdir(dir, dentry, mode); |
1872 | if (!error) | 1882 | if (!error) |
1873 | fsnotify_mkdir(dir, dentry->d_name.name); | 1883 | fsnotify_mkdir(dir, dentry); |
1874 | return error; | 1884 | return error; |
1875 | } | 1885 | } |
1876 | 1886 | ||
@@ -2133,7 +2143,7 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, i | |||
2133 | DQUOT_INIT(dir); | 2143 | DQUOT_INIT(dir); |
2134 | error = dir->i_op->symlink(dir, dentry, oldname); | 2144 | error = dir->i_op->symlink(dir, dentry, oldname); |
2135 | if (!error) | 2145 | if (!error) |
2136 | fsnotify_create(dir, dentry->d_name.name); | 2146 | fsnotify_create(dir, dentry); |
2137 | return error; | 2147 | return error; |
2138 | } | 2148 | } |
2139 | 2149 | ||
@@ -2210,7 +2220,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de | |||
2210 | error = dir->i_op->link(old_dentry, dir, new_dentry); | 2220 | error = dir->i_op->link(old_dentry, dir, new_dentry); |
2211 | mutex_unlock(&old_dentry->d_inode->i_mutex); | 2221 | mutex_unlock(&old_dentry->d_inode->i_mutex); |
2212 | if (!error) | 2222 | if (!error) |
2213 | fsnotify_create(dir, new_dentry->d_name.name); | 2223 | fsnotify_create(dir, new_dentry); |
2214 | return error; | 2224 | return error; |
2215 | } | 2225 | } |
2216 | 2226 | ||
@@ -2277,17 +2287,17 @@ asmlinkage long sys_link(const char __user *oldname, const char __user *newname) | |||
2277 | * a) we can get into loop creation. Check is done in is_subdir(). | 2287 | * a) we can get into loop creation. Check is done in is_subdir(). |
2278 | * b) race potential - two innocent renames can create a loop together. | 2288 | * b) race potential - two innocent renames can create a loop together. |
2279 | * That's where 4.4 screws up. Current fix: serialization on | 2289 | * That's where 4.4 screws up. Current fix: serialization on |
2280 | * sb->s_vfs_rename_sem. We might be more accurate, but that's another | 2290 | * sb->s_vfs_rename_mutex. We might be more accurate, but that's another |
2281 | * story. | 2291 | * story. |
2282 | * c) we have to lock _three_ objects - parents and victim (if it exists). | 2292 | * c) we have to lock _three_ objects - parents and victim (if it exists). |
2283 | * And that - after we got ->i_mutex on parents (until then we don't know | 2293 | * And that - after we got ->i_mutex on parents (until then we don't know |
2284 | * whether the target exists). Solution: try to be smart with locking | 2294 | * whether the target exists). Solution: try to be smart with locking |
2285 | * order for inodes. We rely on the fact that tree topology may change | 2295 | * order for inodes. We rely on the fact that tree topology may change |
2286 | * only under ->s_vfs_rename_sem _and_ that parent of the object we | 2296 | * only under ->s_vfs_rename_mutex _and_ that parent of the object we |
2287 | * move will be locked. Thus we can rank directories by the tree | 2297 | * move will be locked. Thus we can rank directories by the tree |
2288 | * (ancestors first) and rank all non-directories after them. | 2298 | * (ancestors first) and rank all non-directories after them. |
2289 | * That works since everybody except rename does "lock parent, lookup, | 2299 | * That works since everybody except rename does "lock parent, lookup, |
2290 | * lock child" and rename is under ->s_vfs_rename_sem. | 2300 | * lock child" and rename is under ->s_vfs_rename_mutex. |
2291 | * HOWEVER, it relies on the assumption that any object with ->lookup() | 2301 | * HOWEVER, it relies on the assumption that any object with ->lookup() |
2292 | * has no more than 1 dentry. If "hybrid" objects will ever appear, | 2302 | * has no more than 1 dentry. If "hybrid" objects will ever appear, |
2293 | * we'd better make sure that there's no link(2) for them. | 2303 | * we'd better make sure that there's no link(2) for them. |
@@ -2621,16 +2631,27 @@ int __page_symlink(struct inode *inode, const char *symname, int len, | |||
2621 | int err = -ENOMEM; | 2631 | int err = -ENOMEM; |
2622 | char *kaddr; | 2632 | char *kaddr; |
2623 | 2633 | ||
2634 | retry: | ||
2624 | page = find_or_create_page(mapping, 0, gfp_mask); | 2635 | page = find_or_create_page(mapping, 0, gfp_mask); |
2625 | if (!page) | 2636 | if (!page) |
2626 | goto fail; | 2637 | goto fail; |
2627 | err = mapping->a_ops->prepare_write(NULL, page, 0, len-1); | 2638 | err = mapping->a_ops->prepare_write(NULL, page, 0, len-1); |
2639 | if (err == AOP_TRUNCATED_PAGE) { | ||
2640 | page_cache_release(page); | ||
2641 | goto retry; | ||
2642 | } | ||
2628 | if (err) | 2643 | if (err) |
2629 | goto fail_map; | 2644 | goto fail_map; |
2630 | kaddr = kmap_atomic(page, KM_USER0); | 2645 | kaddr = kmap_atomic(page, KM_USER0); |
2631 | memcpy(kaddr, symname, len-1); | 2646 | memcpy(kaddr, symname, len-1); |
2632 | kunmap_atomic(kaddr, KM_USER0); | 2647 | kunmap_atomic(kaddr, KM_USER0); |
2633 | mapping->a_ops->commit_write(NULL, page, 0, len-1); | 2648 | err = mapping->a_ops->commit_write(NULL, page, 0, len-1); |
2649 | if (err == AOP_TRUNCATED_PAGE) { | ||
2650 | page_cache_release(page); | ||
2651 | goto retry; | ||
2652 | } | ||
2653 | if (err) | ||
2654 | goto fail_map; | ||
2634 | /* | 2655 | /* |
2635 | * Notice that we are _not_ going to block here - end of page is | 2656 | * Notice that we are _not_ going to block here - end of page is |
2636 | * unmapped, so this will only try to map the rest of page, see | 2657 | * unmapped, so this will only try to map the rest of page, see |
@@ -2640,7 +2661,8 @@ int __page_symlink(struct inode *inode, const char *symname, int len, | |||
2640 | */ | 2661 | */ |
2641 | if (!PageUptodate(page)) { | 2662 | if (!PageUptodate(page)) { |
2642 | err = mapping->a_ops->readpage(NULL, page); | 2663 | err = mapping->a_ops->readpage(NULL, page); |
2643 | wait_on_page_locked(page); | 2664 | if (err != AOP_TRUNCATED_PAGE) |
2665 | wait_on_page_locked(page); | ||
2644 | } else { | 2666 | } else { |
2645 | unlock_page(page); | 2667 | unlock_page(page); |
2646 | } | 2668 | } |