aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2013-06-14 06:17:15 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2013-06-14 06:17:15 -0400
commit6d4ade986f9c8df31e68fd30643997f79cc5a5f8 (patch)
treef0758a7a9b008d0bd3665234a5074e3cf6f4d455 /fs/dcache.c
parent5a00f3cc978be45b9d2597851bedaa40630bc597 (diff)
GFS2: Add atomic_open support
I've restricted atomic_open to only operate on regular files, although I still don't understand why atomic_open should not be possible also for directories on GFS2. That can always be added in later though, if it makes sense. The ->atomic_open function can be passed negative dentries, which in most cases means either ENOENT (->lookup) or a call to d_instantiate (->create). In the GFS2 case though, we need to actually perform the look up, since we do not know whether there has been a new inode created on another node. The look up calls d_splice_alias which then tries to rehash the dentry - so the solution here is to simply check for that in d_splice_alias. The same issue is likely to affect any other cluster filesystem implementing ->atomic_open Signed-off-by: Steven Whitehouse <swhiteho@redhat.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: "J. Bruce Fields" <bfields fieldses org> Cc: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index f09b9085f7d8..5a23073138df 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1612,6 +1612,10 @@ EXPORT_SYMBOL(d_obtain_alias);
1612 * If a dentry was found and moved, then it is returned. Otherwise NULL 1612 * If a dentry was found and moved, then it is returned. Otherwise NULL
1613 * is returned. This matches the expected return value of ->lookup. 1613 * is returned. This matches the expected return value of ->lookup.
1614 * 1614 *
1615 * Cluster filesystems may call this function with a negative, hashed dentry.
1616 * In that case, we know that the inode will be a regular file, and also this
1617 * will only occur during atomic_open. So we need to check for the dentry
1618 * being already hashed only in the final case.
1615 */ 1619 */
1616struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) 1620struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
1617{ 1621{
@@ -1636,8 +1640,11 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
1636 security_d_instantiate(dentry, inode); 1640 security_d_instantiate(dentry, inode);
1637 d_rehash(dentry); 1641 d_rehash(dentry);
1638 } 1642 }
1639 } else 1643 } else {
1640 d_add(dentry, inode); 1644 d_instantiate(dentry, inode);
1645 if (d_unhashed(dentry))
1646 d_rehash(dentry);
1647 }
1641 return new; 1648 return new;
1642} 1649}
1643EXPORT_SYMBOL(d_splice_alias); 1650EXPORT_SYMBOL(d_splice_alias);