diff options
author | Yan, Zheng <zheng.z.yan@intel.com> | 2013-07-21 20:25:26 +0800 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-08-09 17:54:33 -0700 |
commit | 85ce127a9adf5ab9e9d57ddf64c858927d5e546d (patch) | |
tree | 81d6d0bc74477cfafa5e249a7d96dee558f3a428 /fs/ceph/inode.c | |
parent | ad88f23f42a9b34a0b29a5b19d37251ccb7dd776 (diff) | |
download | op-kernel-dev-85ce127a9adf5ab9e9d57ddf64c858927d5e546d.zip op-kernel-dev-85ce127a9adf5ab9e9d57ddf64c858927d5e546d.tar.gz |
ceph: wake up writer if vmtruncate work get blocked
To write data, the writer first acquires the i_mutex, then try getting
caps. The writer may sleep while holding the i_mutex. If the MDS revokes
Fb cap in this case, vmtruncate work can't do its job because i_mutex
is locked. We should wake up the writer and let it truncate the pages.
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'fs/ceph/inode.c')
-rw-r--r-- | fs/ceph/inode.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 4906ada..55aaddb 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -1465,7 +1465,14 @@ static void ceph_vmtruncate_work(struct work_struct *work) struct inode *inode = &ci->vfs_inode; dout("vmtruncate_work %p\n", inode); - mutex_lock(&inode->i_mutex); + if (!mutex_trylock(&inode->i_mutex)) { + /* + * the i_mutex can be hold by a writer who is waiting for + * caps. wake up waiters, they will do pending vmtruncate. + */ + wake_up_all(&ci->i_cap_wq); + mutex_lock(&inode->i_mutex); + } __ceph_do_pending_vmtruncate(inode); mutex_unlock(&inode->i_mutex); iput(inode); |