aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-03-01 12:57:54 -0500
committerSage Weil <sage@newdream.net>2010-03-01 18:28:00 -0500
commit195d3ce2cc9a8ec69827f6369c41b269345b9988 (patch)
tree9ef91489d379ac612895b6ab3118535969aba152 /fs/ceph
parent6f863e712d4114e8ae2f02de64ebeac0546ebaa0 (diff)
ceph: return EBADF if waiting for caps on closed file
Verify the file is actually open for the given caps when we are waiting for caps. This ensures we will wake up and return EBADF if another thread closes the file out from under us. Note that EBADF is also the correct return code from write(2) when called on a file handle opened for reading (although the vfs should catch that). Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/caps.c9
-rw-r--r--fs/ceph/file.c3
2 files changed, 9 insertions, 3 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 9afa8d37a6e3..06f197983be6 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1923,14 +1923,17 @@ static int try_get_cap_refs(struct ceph_inode_info *ci, int need, int want,
1923 struct inode *inode = &ci->vfs_inode; 1923 struct inode *inode = &ci->vfs_inode;
1924 int ret = 0; 1924 int ret = 0;
1925 int have, implemented; 1925 int have, implemented;
1926 int file_wanted;
1926 1927
1927 dout("get_cap_refs %p need %s want %s\n", inode, 1928 dout("get_cap_refs %p need %s want %s\n", inode,
1928 ceph_cap_string(need), ceph_cap_string(want)); 1929 ceph_cap_string(need), ceph_cap_string(want));
1929 spin_lock(&inode->i_lock); 1930 spin_lock(&inode->i_lock);
1930 1931
1931 /* make sure we _have_ some caps! */ 1932 /* make sure file is actually open */
1932 if (!__ceph_is_any_caps(ci)) { 1933 file_wanted = __ceph_caps_file_wanted(ci);
1933 dout("get_cap_refs %p no real caps\n", inode); 1934 if ((file_wanted & need) == 0) {
1935 dout("try_get_cap_refs need %s file_wanted %s, EBADF\n",
1936 ceph_cap_string(need), ceph_cap_string(file_wanted));
1934 *err = -EBADF; 1937 *err = -EBADF;
1935 ret = 1; 1938 ret = 1;
1936 goto out; 1939 goto out;
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 88932c9145e9..5d2af8464f6a 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -262,6 +262,9 @@ int ceph_release(struct inode *inode, struct file *file)
262 kfree(cf->dir_info); 262 kfree(cf->dir_info);
263 dput(cf->dentry); 263 dput(cf->dentry);
264 kmem_cache_free(ceph_file_cachep, cf); 264 kmem_cache_free(ceph_file_cachep, cf);
265
266 /* wake up anyone waiting for caps on this inode */
267 wake_up(&ci->i_cap_wq);
265 return 0; 268 return 0;
266} 269}
267 270