diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2012-06-05 09:10:25 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-07-14 08:33:16 -0400 |
commit | 2d83bde9a16e18eafdc73a3a1f4a8eb110e49672 (patch) | |
tree | 04e2277dba94d252f4b74cf1acb728880b606c2e /fs/ceph/file.c | |
parent | 3819219b592159725069eb16a7a46f58e4ecef32 (diff) |
ceph: implement i_op->atomic_open()
Add an ->atomic_open implementation which replaces the atomic lookup+open+create
operation implemented via ->lookup and ->create operations.
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
CC: Sage Weil <sage@newdream.net>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ceph/file.c')
-rw-r--r-- | fs/ceph/file.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 4bf9773e6a36..e34dc22e75a9 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -213,21 +213,15 @@ out: | |||
213 | * may_open() fails, the struct *file gets cleaned up (i.e. | 213 | * may_open() fails, the struct *file gets cleaned up (i.e. |
214 | * ceph_release gets called). So fear not! | 214 | * ceph_release gets called). So fear not! |
215 | */ | 215 | */ |
216 | /* | 216 | struct file *ceph_lookup_open(struct inode *dir, struct dentry *dentry, |
217 | * flags | 217 | struct opendata *od, unsigned flags, umode_t mode) |
218 | * path_lookup_open -> LOOKUP_OPEN | ||
219 | * path_lookup_create -> LOOKUP_OPEN|LOOKUP_CREATE | ||
220 | */ | ||
221 | struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry, | ||
222 | struct nameidata *nd, int mode) | ||
223 | { | 218 | { |
224 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); | 219 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); |
225 | struct ceph_mds_client *mdsc = fsc->mdsc; | 220 | struct ceph_mds_client *mdsc = fsc->mdsc; |
226 | struct file *file; | 221 | struct file *file = NULL; |
227 | struct ceph_mds_request *req; | 222 | struct ceph_mds_request *req; |
228 | struct dentry *ret; | 223 | struct dentry *ret; |
229 | int err; | 224 | int err; |
230 | int flags = nd->intent.open.flags; | ||
231 | 225 | ||
232 | dout("ceph_lookup_open dentry %p '%.*s' flags %d mode 0%o\n", | 226 | dout("ceph_lookup_open dentry %p '%.*s' flags %d mode 0%o\n", |
233 | dentry, dentry->d_name.len, dentry->d_name.name, flags, mode); | 227 | dentry, dentry->d_name.len, dentry->d_name.name, flags, mode); |
@@ -253,14 +247,19 @@ struct dentry *ceph_lookup_open(struct inode *dir, struct dentry *dentry, | |||
253 | err = ceph_handle_notrace_create(dir, dentry); | 247 | err = ceph_handle_notrace_create(dir, dentry); |
254 | if (err) | 248 | if (err) |
255 | goto out; | 249 | goto out; |
256 | file = lookup_instantiate_filp(nd, req->r_dentry, ceph_open); | 250 | file = finish_open(od, req->r_dentry, ceph_open); |
257 | if (IS_ERR(file)) | 251 | if (IS_ERR(file)) |
258 | err = PTR_ERR(file); | 252 | err = PTR_ERR(file); |
259 | out: | 253 | out: |
260 | ret = ceph_finish_lookup(req, dentry, err); | 254 | ret = ceph_finish_lookup(req, dentry, err); |
261 | ceph_mdsc_put_request(req); | 255 | ceph_mdsc_put_request(req); |
262 | dout("ceph_lookup_open result=%p\n", ret); | 256 | dout("ceph_lookup_open result=%p\n", ret); |
263 | return ret; | 257 | |
258 | if (IS_ERR(ret)) | ||
259 | return ERR_CAST(ret); | ||
260 | |||
261 | dput(ret); | ||
262 | return err ? ERR_PTR(err) : file; | ||
264 | } | 263 | } |
265 | 264 | ||
266 | int ceph_release(struct inode *inode, struct file *file) | 265 | int ceph_release(struct inode *inode, struct file *file) |