Loading fs/ceph/caps.c +2 −48 Original line number Diff line number Diff line Loading @@ -1927,53 +1927,6 @@ static int caps_are_flushed(struct inode *inode, u64 flush_tid) return ret; } /* * Wait on any unsafe replies for the given inode. First wait on the * newest request, and make that the upper bound. Then, if there are * more requests, keep waiting on the oldest as long as it is still older * than the original request. */ static void sync_write_wait(struct inode *inode) { struct ceph_inode_info *ci = ceph_inode(inode); struct list_head *head = &ci->i_unsafe_writes; struct ceph_osd_request *req; u64 last_tid; if (!S_ISREG(inode->i_mode)) return; spin_lock(&ci->i_unsafe_lock); if (list_empty(head)) goto out; /* set upper bound as _last_ entry in chain */ req = list_last_entry(head, struct ceph_osd_request, r_unsafe_item); last_tid = req->r_tid; do { ceph_osdc_get_request(req); spin_unlock(&ci->i_unsafe_lock); dout("sync_write_wait on tid %llu (until %llu)\n", req->r_tid, last_tid); wait_for_completion(&req->r_safe_completion); spin_lock(&ci->i_unsafe_lock); ceph_osdc_put_request(req); /* * from here on look at first entry in chain, since we * only want to wait for anything older than last_tid */ if (list_empty(head)) break; req = list_first_entry(head, struct ceph_osd_request, r_unsafe_item); } while (req->r_tid < last_tid); out: spin_unlock(&ci->i_unsafe_lock); } /* * wait for any unsafe requests to complete. */ Loading Loading @@ -2026,7 +1979,8 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync) int dirty; dout("fsync %p%s\n", inode, datasync ? " datasync" : ""); sync_write_wait(inode); ceph_sync_write_wait(inode); ret = filemap_write_and_wait_range(inode->i_mapping, start, end); if (ret < 0) Loading fs/ceph/file.c +48 −0 Original line number Diff line number Diff line Loading @@ -821,6 +821,54 @@ static void ceph_sync_write_unsafe(struct ceph_osd_request *req, bool unsafe) } } /* * Wait on any unsafe replies for the given inode. First wait on the * newest request, and make that the upper bound. Then, if there are * more requests, keep waiting on the oldest as long as it is still older * than the original request. */ void ceph_sync_write_wait(struct inode *inode) { struct ceph_inode_info *ci = ceph_inode(inode); struct list_head *head = &ci->i_unsafe_writes; struct ceph_osd_request *req; u64 last_tid; if (!S_ISREG(inode->i_mode)) return; spin_lock(&ci->i_unsafe_lock); if (list_empty(head)) goto out; /* set upper bound as _last_ entry in chain */ req = list_last_entry(head, struct ceph_osd_request, r_unsafe_item); last_tid = req->r_tid; do { ceph_osdc_get_request(req); spin_unlock(&ci->i_unsafe_lock); dout("sync_write_wait on tid %llu (until %llu)\n", req->r_tid, last_tid); wait_for_completion(&req->r_safe_completion); ceph_osdc_put_request(req); spin_lock(&ci->i_unsafe_lock); /* * from here on look at first entry in chain, since we * only want to wait for anything older than last_tid */ if (list_empty(head)) break; req = list_first_entry(head, struct ceph_osd_request, r_unsafe_item); } while (req->r_tid < last_tid); out: spin_unlock(&ci->i_unsafe_lock); } static ssize_t ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, Loading fs/ceph/inode.c +8 −0 Original line number Diff line number Diff line Loading @@ -585,6 +585,14 @@ int ceph_drop_inode(struct inode *inode) return 1; } void ceph_evict_inode(struct inode *inode) { /* wait unsafe sync writes */ ceph_sync_write_wait(inode); truncate_inode_pages_final(&inode->i_data); clear_inode(inode); } static inline blkcnt_t calc_inode_blocks(u64 size) { return (size + (1<<9) - 1) >> 9; Loading fs/ceph/super.c +1 −0 Original line number Diff line number Diff line Loading @@ -731,6 +731,7 @@ static const struct super_operations ceph_super_ops = { .destroy_inode = ceph_destroy_inode, .write_inode = ceph_write_inode, .drop_inode = ceph_drop_inode, .evict_inode = ceph_evict_inode, .sync_fs = ceph_sync_fs, .put_super = ceph_put_super, .show_options = ceph_show_options, Loading fs/ceph/super.h +2 −0 Original line number Diff line number Diff line Loading @@ -749,6 +749,7 @@ extern const struct inode_operations ceph_file_iops; extern struct inode *ceph_alloc_inode(struct super_block *sb); extern void ceph_destroy_inode(struct inode *inode); extern int ceph_drop_inode(struct inode *inode); extern void ceph_evict_inode(struct inode *inode); extern struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino); Loading Loading @@ -927,6 +928,7 @@ extern int ceph_atomic_open(struct inode *dir, struct dentry *dentry, extern int ceph_release(struct inode *inode, struct file *filp); extern void ceph_fill_inline_data(struct inode *inode, struct page *locked_page, char *data, size_t len); extern void ceph_sync_write_wait(struct inode *inode); /* dir.c */ extern const struct file_operations ceph_dir_fops; extern const struct file_operations ceph_snapdir_fops; Loading Loading
fs/ceph/caps.c +2 −48 Original line number Diff line number Diff line Loading @@ -1927,53 +1927,6 @@ static int caps_are_flushed(struct inode *inode, u64 flush_tid) return ret; } /* * Wait on any unsafe replies for the given inode. First wait on the * newest request, and make that the upper bound. Then, if there are * more requests, keep waiting on the oldest as long as it is still older * than the original request. */ static void sync_write_wait(struct inode *inode) { struct ceph_inode_info *ci = ceph_inode(inode); struct list_head *head = &ci->i_unsafe_writes; struct ceph_osd_request *req; u64 last_tid; if (!S_ISREG(inode->i_mode)) return; spin_lock(&ci->i_unsafe_lock); if (list_empty(head)) goto out; /* set upper bound as _last_ entry in chain */ req = list_last_entry(head, struct ceph_osd_request, r_unsafe_item); last_tid = req->r_tid; do { ceph_osdc_get_request(req); spin_unlock(&ci->i_unsafe_lock); dout("sync_write_wait on tid %llu (until %llu)\n", req->r_tid, last_tid); wait_for_completion(&req->r_safe_completion); spin_lock(&ci->i_unsafe_lock); ceph_osdc_put_request(req); /* * from here on look at first entry in chain, since we * only want to wait for anything older than last_tid */ if (list_empty(head)) break; req = list_first_entry(head, struct ceph_osd_request, r_unsafe_item); } while (req->r_tid < last_tid); out: spin_unlock(&ci->i_unsafe_lock); } /* * wait for any unsafe requests to complete. */ Loading Loading @@ -2026,7 +1979,8 @@ int ceph_fsync(struct file *file, loff_t start, loff_t end, int datasync) int dirty; dout("fsync %p%s\n", inode, datasync ? " datasync" : ""); sync_write_wait(inode); ceph_sync_write_wait(inode); ret = filemap_write_and_wait_range(inode->i_mapping, start, end); if (ret < 0) Loading
fs/ceph/file.c +48 −0 Original line number Diff line number Diff line Loading @@ -821,6 +821,54 @@ static void ceph_sync_write_unsafe(struct ceph_osd_request *req, bool unsafe) } } /* * Wait on any unsafe replies for the given inode. First wait on the * newest request, and make that the upper bound. Then, if there are * more requests, keep waiting on the oldest as long as it is still older * than the original request. */ void ceph_sync_write_wait(struct inode *inode) { struct ceph_inode_info *ci = ceph_inode(inode); struct list_head *head = &ci->i_unsafe_writes; struct ceph_osd_request *req; u64 last_tid; if (!S_ISREG(inode->i_mode)) return; spin_lock(&ci->i_unsafe_lock); if (list_empty(head)) goto out; /* set upper bound as _last_ entry in chain */ req = list_last_entry(head, struct ceph_osd_request, r_unsafe_item); last_tid = req->r_tid; do { ceph_osdc_get_request(req); spin_unlock(&ci->i_unsafe_lock); dout("sync_write_wait on tid %llu (until %llu)\n", req->r_tid, last_tid); wait_for_completion(&req->r_safe_completion); ceph_osdc_put_request(req); spin_lock(&ci->i_unsafe_lock); /* * from here on look at first entry in chain, since we * only want to wait for anything older than last_tid */ if (list_empty(head)) break; req = list_first_entry(head, struct ceph_osd_request, r_unsafe_item); } while (req->r_tid < last_tid); out: spin_unlock(&ci->i_unsafe_lock); } static ssize_t ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, Loading
fs/ceph/inode.c +8 −0 Original line number Diff line number Diff line Loading @@ -585,6 +585,14 @@ int ceph_drop_inode(struct inode *inode) return 1; } void ceph_evict_inode(struct inode *inode) { /* wait unsafe sync writes */ ceph_sync_write_wait(inode); truncate_inode_pages_final(&inode->i_data); clear_inode(inode); } static inline blkcnt_t calc_inode_blocks(u64 size) { return (size + (1<<9) - 1) >> 9; Loading
fs/ceph/super.c +1 −0 Original line number Diff line number Diff line Loading @@ -731,6 +731,7 @@ static const struct super_operations ceph_super_ops = { .destroy_inode = ceph_destroy_inode, .write_inode = ceph_write_inode, .drop_inode = ceph_drop_inode, .evict_inode = ceph_evict_inode, .sync_fs = ceph_sync_fs, .put_super = ceph_put_super, .show_options = ceph_show_options, Loading
fs/ceph/super.h +2 −0 Original line number Diff line number Diff line Loading @@ -749,6 +749,7 @@ extern const struct inode_operations ceph_file_iops; extern struct inode *ceph_alloc_inode(struct super_block *sb); extern void ceph_destroy_inode(struct inode *inode); extern int ceph_drop_inode(struct inode *inode); extern void ceph_evict_inode(struct inode *inode); extern struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino); Loading Loading @@ -927,6 +928,7 @@ extern int ceph_atomic_open(struct inode *dir, struct dentry *dentry, extern int ceph_release(struct inode *inode, struct file *filp); extern void ceph_fill_inline_data(struct inode *inode, struct page *locked_page, char *data, size_t len); extern void ceph_sync_write_wait(struct inode *inode); /* dir.c */ extern const struct file_operations ceph_dir_fops; extern const struct file_operations ceph_snapdir_fops; Loading