diff options
Diffstat (limited to 'fs/ceph/caps.c')
-rw-r--r-- | fs/ceph/caps.c | 76 |
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 | */ |
1976 | static int unsafe_dirop_wait(struct inode *inode) | 1975 | static 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 | } |
2014 | out: | 2012 | return err; |
2015 | spin_unlock(&ci->i_unsafe_lock); | ||
2016 | return ret; | ||
2017 | } | 2013 | } |
2018 | 2014 | ||
2019 | int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync) | 2015 | int 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 |