diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2013-06-14 06:17:15 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2013-06-14 06:17:15 -0400 |
commit | 6d4ade986f9c8df31e68fd30643997f79cc5a5f8 (patch) | |
tree | f0758a7a9b008d0bd3665234a5074e3cf6f4d455 /fs/dcache.c | |
parent | 5a00f3cc978be45b9d2597851bedaa40630bc597 (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.c | 11 |
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 | */ |
1616 | struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry) | 1620 | struct 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 | } |
1643 | EXPORT_SYMBOL(d_splice_alias); | 1650 | EXPORT_SYMBOL(d_splice_alias); |