aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /fs/nfs/dir.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c78
1 files changed, 36 insertions, 42 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 7cb298525eef..a7bb5c694aa3 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -560,7 +560,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
560 desc->entry = &my_entry; 560 desc->entry = &my_entry;
561 561
562 nfs_block_sillyrename(dentry); 562 nfs_block_sillyrename(dentry);
563 res = nfs_revalidate_mapping_nolock(inode, filp->f_mapping); 563 res = nfs_revalidate_mapping(inode, filp->f_mapping);
564 if (res < 0) 564 if (res < 0)
565 goto out; 565 goto out;
566 566
@@ -837,6 +837,8 @@ out_zap_parent:
837 /* If we have submounts, don't unhash ! */ 837 /* If we have submounts, don't unhash ! */
838 if (have_submounts(dentry)) 838 if (have_submounts(dentry))
839 goto out_valid; 839 goto out_valid;
840 if (dentry->d_flags & DCACHE_DISCONNECTED)
841 goto out_valid;
840 shrink_dcache_parent(dentry); 842 shrink_dcache_parent(dentry);
841 } 843 }
842 d_drop(dentry); 844 d_drop(dentry);
@@ -1025,12 +1027,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
1025 res = NULL; 1027 res = NULL;
1026 goto out; 1028 goto out;
1027 /* This turned out not to be a regular file */ 1029 /* This turned out not to be a regular file */
1030 case -EISDIR:
1028 case -ENOTDIR: 1031 case -ENOTDIR:
1029 goto no_open; 1032 goto no_open;
1030 case -ELOOP: 1033 case -ELOOP:
1031 if (!(nd->intent.open.flags & O_NOFOLLOW)) 1034 if (!(nd->intent.open.flags & O_NOFOLLOW))
1032 goto no_open; 1035 goto no_open;
1033 /* case -EISDIR: */
1034 /* case -EINVAL: */ 1036 /* case -EINVAL: */
1035 default: 1037 default:
1036 goto out; 1038 goto out;
@@ -1050,7 +1052,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd)
1050 struct inode *dir; 1052 struct inode *dir;
1051 int openflags, ret = 0; 1053 int openflags, ret = 0;
1052 1054
1053 if (!is_atomic_open(nd)) 1055 if (!is_atomic_open(nd) || d_mountpoint(dentry))
1054 goto no_open; 1056 goto no_open;
1055 parent = dget_parent(dentry); 1057 parent = dget_parent(dentry);
1056 dir = parent->d_inode; 1058 dir = parent->d_inode;
@@ -1579,55 +1581,47 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
1579 struct dentry *dentry = NULL, *rehash = NULL; 1581 struct dentry *dentry = NULL, *rehash = NULL;
1580 int error = -EBUSY; 1582 int error = -EBUSY;
1581 1583
1582 /*
1583 * To prevent any new references to the target during the rename,
1584 * we unhash the dentry and free the inode in advance.
1585 */
1586 if (!d_unhashed(new_dentry)) {
1587 d_drop(new_dentry);
1588 rehash = new_dentry;
1589 }
1590
1591 dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n", 1584 dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n",
1592 old_dentry->d_parent->d_name.name, old_dentry->d_name.name, 1585 old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
1593 new_dentry->d_parent->d_name.name, new_dentry->d_name.name, 1586 new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
1594 atomic_read(&new_dentry->d_count)); 1587 atomic_read(&new_dentry->d_count));
1595 1588
1596 /* 1589 /*
1597 * First check whether the target is busy ... we can't 1590 * For non-directories, check whether the target is busy and if so,
1598 * safely do _any_ rename if the target is in use. 1591 * make a copy of the dentry and then do a silly-rename. If the
1599 * 1592 * silly-rename succeeds, the copied dentry is hashed and becomes
1600 * For files, make a copy of the dentry and then do a 1593 * the new target.
1601 * silly-rename. If the silly-rename succeeds, the
1602 * copied dentry is hashed and becomes the new target.
1603 */ 1594 */
1604 if (!new_inode) 1595 if (new_inode && !S_ISDIR(new_inode->i_mode)) {
1605 goto go_ahead; 1596 /*
1606 if (S_ISDIR(new_inode->i_mode)) { 1597 * To prevent any new references to the target during the
1607 error = -EISDIR; 1598 * rename, we unhash the dentry in advance.
1608 if (!S_ISDIR(old_inode->i_mode)) 1599 */
1609 goto out; 1600 if (!d_unhashed(new_dentry)) {
1610 } else if (atomic_read(&new_dentry->d_count) > 2) { 1601 d_drop(new_dentry);
1611 int err; 1602 rehash = new_dentry;
1612 /* copy the target dentry's name */ 1603 }
1613 dentry = d_alloc(new_dentry->d_parent, 1604
1614 &new_dentry->d_name); 1605 if (atomic_read(&new_dentry->d_count) > 2) {
1615 if (!dentry) 1606 int err;
1616 goto out; 1607
1608 /* copy the target dentry's name */
1609 dentry = d_alloc(new_dentry->d_parent,
1610 &new_dentry->d_name);
1611 if (!dentry)
1612 goto out;
1617 1613
1618 /* silly-rename the existing target ... */ 1614 /* silly-rename the existing target ... */
1619 err = nfs_sillyrename(new_dir, new_dentry); 1615 err = nfs_sillyrename(new_dir, new_dentry);
1620 if (!err) { 1616 if (err)
1621 new_dentry = rehash = dentry; 1617 goto out;
1618
1619 new_dentry = dentry;
1620 rehash = NULL;
1622 new_inode = NULL; 1621 new_inode = NULL;
1623 /* instantiate the replacement target */ 1622 }
1624 d_instantiate(new_dentry, NULL);
1625 } else if (atomic_read(&new_dentry->d_count) > 1)
1626 /* dentry still busy? */
1627 goto out;
1628 } 1623 }
1629 1624
1630go_ahead:
1631 /* 1625 /*
1632 * ... prune child dentries and writebacks if needed. 1626 * ... prune child dentries and writebacks if needed.
1633 */ 1627 */
@@ -1797,7 +1791,7 @@ static int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, str
1797 cache = nfs_access_search_rbtree(inode, cred); 1791 cache = nfs_access_search_rbtree(inode, cred);
1798 if (cache == NULL) 1792 if (cache == NULL)
1799 goto out; 1793 goto out;
1800 if (!nfs_have_delegation(inode, FMODE_READ) && 1794 if (!nfs_have_delegated_attributes(inode) &&
1801 !time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo)) 1795 !time_in_range_open(jiffies, cache->jiffies, cache->jiffies + nfsi->attrtimeo))
1802 goto out_stale; 1796 goto out_stale;
1803 res->jiffies = cache->jiffies; 1797 res->jiffies = cache->jiffies;