aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 51cfc9c3ed00..98dc2e134362 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
@@ -1423,7 +1423,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
1423 return NULL; 1423 return NULL;
1424 } 1424 }
1425 1425
1426 down(&p1->d_inode->i_sb->s_vfs_rename_sem); 1426 mutex_lock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
1427 1427
1428 for (p = p1; p->d_parent != p; p = p->d_parent) { 1428 for (p = p1; p->d_parent != p; p = p->d_parent) {
1429 if (p->d_parent == p2) { 1429 if (p->d_parent == p2) {
@@ -1451,7 +1451,7 @@ void unlock_rename(struct dentry *p1, struct dentry *p2)
1451 mutex_unlock(&p1->d_inode->i_mutex); 1451 mutex_unlock(&p1->d_inode->i_mutex);
1452 if (p1 != p2) { 1452 if (p1 != p2) {
1453 mutex_unlock(&p2->d_inode->i_mutex); 1453 mutex_unlock(&p2->d_inode->i_mutex);
1454 up(&p1->d_inode->i_sb->s_vfs_rename_sem); 1454 mutex_unlock(&p1->d_inode->i_sb->s_vfs_rename_mutex);
1455 } 1455 }
1456} 1456}
1457 1457
@@ -1629,6 +1629,12 @@ do_last:
1629 goto exit; 1629 goto exit;
1630 } 1630 }
1631 1631
1632 if (IS_ERR(nd->intent.open.file)) {
1633 mutex_unlock(&dir->d_inode->i_mutex);
1634 error = PTR_ERR(nd->intent.open.file);
1635 goto exit_dput;
1636 }
1637
1632 /* Negative dentry, just create the file */ 1638 /* Negative dentry, just create the file */
1633 if (!path.dentry->d_inode) { 1639 if (!path.dentry->d_inode) {
1634 if (!IS_POSIXACL(dir->d_inode)) 1640 if (!IS_POSIXACL(dir->d_inode))
@@ -2278,17 +2284,17 @@ asmlinkage long sys_link(const char __user *oldname, const char __user *newname)
2278 * a) we can get into loop creation. Check is done in is_subdir(). 2284 * a) we can get into loop creation. Check is done in is_subdir().
2279 * b) race potential - two innocent renames can create a loop together. 2285 * b) race potential - two innocent renames can create a loop together.
2280 * That's where 4.4 screws up. Current fix: serialization on 2286 * That's where 4.4 screws up. Current fix: serialization on
2281 * sb->s_vfs_rename_sem. We might be more accurate, but that's another 2287 * sb->s_vfs_rename_mutex. We might be more accurate, but that's another
2282 * story. 2288 * story.
2283 * c) we have to lock _three_ objects - parents and victim (if it exists). 2289 * c) we have to lock _three_ objects - parents and victim (if it exists).
2284 * And that - after we got ->i_mutex on parents (until then we don't know 2290 * And that - after we got ->i_mutex on parents (until then we don't know
2285 * whether the target exists). Solution: try to be smart with locking 2291 * whether the target exists). Solution: try to be smart with locking
2286 * order for inodes. We rely on the fact that tree topology may change 2292 * order for inodes. We rely on the fact that tree topology may change
2287 * only under ->s_vfs_rename_sem _and_ that parent of the object we 2293 * only under ->s_vfs_rename_mutex _and_ that parent of the object we
2288 * move will be locked. Thus we can rank directories by the tree 2294 * move will be locked. Thus we can rank directories by the tree
2289 * (ancestors first) and rank all non-directories after them. 2295 * (ancestors first) and rank all non-directories after them.
2290 * That works since everybody except rename does "lock parent, lookup, 2296 * That works since everybody except rename does "lock parent, lookup,
2291 * lock child" and rename is under ->s_vfs_rename_sem. 2297 * lock child" and rename is under ->s_vfs_rename_mutex.
2292 * HOWEVER, it relies on the assumption that any object with ->lookup() 2298 * HOWEVER, it relies on the assumption that any object with ->lookup()
2293 * has no more than 1 dentry. If "hybrid" objects will ever appear, 2299 * has no more than 1 dentry. If "hybrid" objects will ever appear,
2294 * we'd better make sure that there's no link(2) for them. 2300 * we'd better make sure that there's no link(2) for them.
@@ -2622,16 +2628,27 @@ int __page_symlink(struct inode *inode, const char *symname, int len,
2622 int err = -ENOMEM; 2628 int err = -ENOMEM;
2623 char *kaddr; 2629 char *kaddr;
2624 2630
2631retry:
2625 page = find_or_create_page(mapping, 0, gfp_mask); 2632 page = find_or_create_page(mapping, 0, gfp_mask);
2626 if (!page) 2633 if (!page)
2627 goto fail; 2634 goto fail;
2628 err = mapping->a_ops->prepare_write(NULL, page, 0, len-1); 2635 err = mapping->a_ops->prepare_write(NULL, page, 0, len-1);
2636 if (err == AOP_TRUNCATED_PAGE) {
2637 page_cache_release(page);
2638 goto retry;
2639 }
2629 if (err) 2640 if (err)
2630 goto fail_map; 2641 goto fail_map;
2631 kaddr = kmap_atomic(page, KM_USER0); 2642 kaddr = kmap_atomic(page, KM_USER0);
2632 memcpy(kaddr, symname, len-1); 2643 memcpy(kaddr, symname, len-1);
2633 kunmap_atomic(kaddr, KM_USER0); 2644 kunmap_atomic(kaddr, KM_USER0);
2634 mapping->a_ops->commit_write(NULL, page, 0, len-1); 2645 err = mapping->a_ops->commit_write(NULL, page, 0, len-1);
2646 if (err == AOP_TRUNCATED_PAGE) {
2647 page_cache_release(page);
2648 goto retry;
2649 }
2650 if (err)
2651 goto fail_map;
2635 /* 2652 /*
2636 * Notice that we are _not_ going to block here - end of page is 2653 * Notice that we are _not_ going to block here - end of page is
2637 * unmapped, so this will only try to map the rest of page, see 2654 * unmapped, so this will only try to map the rest of page, see
@@ -2641,7 +2658,8 @@ int __page_symlink(struct inode *inode, const char *symname, int len,
2641 */ 2658 */
2642 if (!PageUptodate(page)) { 2659 if (!PageUptodate(page)) {
2643 err = mapping->a_ops->readpage(NULL, page); 2660 err = mapping->a_ops->readpage(NULL, page);
2644 wait_on_page_locked(page); 2661 if (err != AOP_TRUNCATED_PAGE)
2662 wait_on_page_locked(page);
2645 } else { 2663 } else {
2646 unlock_page(page); 2664 unlock_page(page);
2647 } 2665 }