ceph: simplify+fix atomic_open
The initial ->atomic_open op was carried over from the old intent code, which was incomplete and didn't really work. Replace it with a fresh method. In particular: * always attempt to do an atomic open+lookup, both for the create case and for lookups of existing files. * fix symlink handling by returning 1 to the VFS so that we can follow the link to its destination. This fixes a longstanding ceph bug (#2392). Signed-off-by: Sage Weil <sage@inktank.com>
This commit is contained in:
@@ -633,44 +633,6 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
|
||||
return dentry;
|
||||
}
|
||||
|
||||
int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||
struct file *file, unsigned flags, umode_t mode,
|
||||
int *opened)
|
||||
{
|
||||
int err;
|
||||
struct dentry *res = NULL;
|
||||
|
||||
if (!(flags & O_CREAT)) {
|
||||
if (dentry->d_name.len > NAME_MAX)
|
||||
return -ENAMETOOLONG;
|
||||
|
||||
err = ceph_init_dentry(dentry);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return ceph_lookup_open(dir, dentry, file, flags, mode, opened);
|
||||
}
|
||||
|
||||
if (d_unhashed(dentry)) {
|
||||
res = ceph_lookup(dir, dentry, 0);
|
||||
if (IS_ERR(res))
|
||||
return PTR_ERR(res);
|
||||
|
||||
if (res)
|
||||
dentry = res;
|
||||
}
|
||||
|
||||
/* We don't deal with positive dentries here */
|
||||
if (dentry->d_inode)
|
||||
return finish_no_open(file, res);
|
||||
|
||||
*opened |= FILE_CREATED;
|
||||
err = ceph_lookup_open(dir, dentry, file, flags, mode, opened);
|
||||
dput(res);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we do a create but get no trace back from the MDS, follow up with
|
||||
* a lookup (the VFS expects us to link up the provided dentry).
|
||||
|
Reference in New Issue
Block a user