summaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
authorSage Weil2010-03-01 18:57:54 +0100
committerSage Weil2010-03-02 00:28:00 +0100
commit195d3ce2cc9a8ec69827f6369c41b269345b9988 (patch)
tree9ef91489d379ac612895b6ab3118535969aba152 /fs/ceph/caps.c
parentceph: set osd request message front length correctly (diff)
downloadkernel-qcow2-linux-195d3ce2cc9a8ec69827f6369c41b269345b9988.tar.gz
kernel-qcow2-linux-195d3ce2cc9a8ec69827f6369c41b269345b9988.tar.xz
kernel-qcow2-linux-195d3ce2cc9a8ec69827f6369c41b269345b9988.zip
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/caps.c')
-rw-r--r--fs/ceph/caps.c9
1 files changed, 6 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,
struct inode *inode = &ci->vfs_inode;
int ret = 0;
int have, implemented;
+ int file_wanted;
dout("get_cap_refs %p need %s want %s\n", inode,
ceph_cap_string(need), ceph_cap_string(want));
spin_lock(&inode->i_lock);
- /* make sure we _have_ some caps! */
- if (!__ceph_is_any_caps(ci)) {
- dout("get_cap_refs %p no real caps\n", inode);
+ /* make sure file is actually open */
+ file_wanted = __ceph_caps_file_wanted(ci);
+ if ((file_wanted & need) == 0) {
+ dout("try_get_cap_refs need %s file_wanted %s, EBADF\n",
+ ceph_cap_string(need), ceph_cap_string(file_wanted));
*err = -EBADF;
ret = 1;
goto out;