aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/caps.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r--fs/ceph/caps.c76
1 files changed, 36 insertions, 40 deletions
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 27b566874bc1..c69e1253b47b 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1655,9 +1655,8 @@ retry_locked:
1655 !S_ISDIR(inode->i_mode) && /* ignore readdir cache */ 1655 !S_ISDIR(inode->i_mode) && /* ignore readdir cache */
1656 ci->i_wrbuffer_ref == 0 && /* no dirty pages... */ 1656 ci->i_wrbuffer_ref == 0 && /* no dirty pages... */
1657 inode->i_data.nrpages && /* have cached pages */ 1657 inode->i_data.nrpages && /* have cached pages */
1658 (file_wanted == 0 || /* no open files */ 1658 (revoking & (CEPH_CAP_FILE_CACHE|
1659 (revoking & (CEPH_CAP_FILE_CACHE| 1659 CEPH_CAP_FILE_LAZYIO)) && /* or revoking cache */
1660 CEPH_CAP_FILE_LAZYIO))) && /* or revoking cache */
1661 !tried_invalidate) { 1660 !tried_invalidate) {
1662 dout("check_caps trying to invalidate on %p\n", inode); 1661 dout("check_caps trying to invalidate on %p\n", inode);
1663 if (try_nonblocking_invalidate(inode) < 0) { 1662 if (try_nonblocking_invalidate(inode) < 0) {
@@ -1971,49 +1970,46 @@ out:
1971} 1970}
1972 1971
1973/* 1972/*
1974 * wait for any uncommitted directory operations to commit. 1973 * wait for any unsafe requests to complete.
1975 */ 1974 */
1976static int unsafe_dirop_wait(struct inode *inode) 1975static int unsafe_request_wait(struct inode *inode)
1977{ 1976{
1978 struct ceph_inode_info *ci = ceph_inode(inode); 1977 struct ceph_inode_info *ci = ceph_inode(inode);
1979 struct list_head *head = &ci->i_unsafe_dirops; 1978 struct ceph_mds_request *req1 = NULL, *req2 = NULL;
1980 struct ceph_mds_request *req; 1979 int ret, err = 0;
1981 u64 last_tid;
1982 int ret = 0;
1983
1984 if (!S_ISDIR(inode->i_mode))
1985 return 0;
1986 1980
1987 spin_lock(&ci->i_unsafe_lock); 1981 spin_lock(&ci->i_unsafe_lock);
1988 if (list_empty(head)) 1982 if (S_ISDIR(inode->i_mode) && !list_empty(&ci->i_unsafe_dirops)) {
1989 goto out; 1983 req1 = list_last_entry(&ci->i_unsafe_dirops,
1990 1984 struct ceph_mds_request,
1991 req = list_last_entry(head, struct ceph_mds_request, 1985 r_unsafe_dir_item);
1992 r_unsafe_dir_item); 1986 ceph_mdsc_get_request(req1);
1993 last_tid = req->r_tid; 1987 }
1994 1988 if (!list_empty(&ci->i_unsafe_iops)) {
1995 do { 1989 req2 = list_last_entry(&ci->i_unsafe_iops,
1996 ceph_mdsc_get_request(req); 1990 struct ceph_mds_request,
1997 spin_unlock(&ci->i_unsafe_lock); 1991 r_unsafe_target_item);
1992 ceph_mdsc_get_request(req2);
1993 }
1994 spin_unlock(&ci->i_unsafe_lock);
1998 1995
1999 dout("unsafe_dirop_wait %p wait on tid %llu (until %llu)\n", 1996 dout("unsafe_requeset_wait %p wait on tid %llu %llu\n",
2000 inode, req->r_tid, last_tid); 1997 inode, req1 ? req1->r_tid : 0ULL, req2 ? req2->r_tid : 0ULL);
2001 ret = !wait_for_completion_timeout(&req->r_safe_completion, 1998 if (req1) {
2002 ceph_timeout_jiffies(req->r_timeout)); 1999 ret = !wait_for_completion_timeout(&req1->r_safe_completion,
2000 ceph_timeout_jiffies(req1->r_timeout));
2003 if (ret) 2001 if (ret)
2004 ret = -EIO; /* timed out */ 2002 err = -EIO;
2005 2003 ceph_mdsc_put_request(req1);
2006 ceph_mdsc_put_request(req); 2004 }
2007 2005 if (req2) {
2008 spin_lock(&ci->i_unsafe_lock); 2006 ret = !wait_for_completion_timeout(&req2->r_safe_completion,
2009 if (ret || list_empty(head)) 2007 ceph_timeout_jiffies(req2->r_timeout));
2010 break; 2008 if (ret)
2011 req = list_first_entry(head, struct ceph_mds_request, 2009 err = -EIO;
2012 r_unsafe_dir_item); 2010 ceph_mdsc_put_request(req2);
2013 } while (req->r_tid < last_tid); 2011 }
2014out: 2012 return err;
2015 spin_unlock(&ci->i_unsafe_lock);
2016 return ret;
2017} 2013}
2018 2014
2019int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync) 2015int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
@@ -2039,7 +2035,7 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync)
2039 dirty = try_flush_caps(inode, &flush_tid); 2035 dirty = try_flush_caps(inode, &flush_tid);
2040 dout("fsync dirty caps are %s\n", ceph_cap_string(dirty)); 2036 dout("fsync dirty caps are %s\n", ceph_cap_string(dirty));
2041 2037
2042 ret = unsafe_dirop_wait(inode); 2038 ret = unsafe_request_wait(inode);
2043 2039
2044 /* 2040 /*
2045 * only wait on non-file metadata writeback (the mds 2041 * only wait on non-file metadata writeback (the mds