fs: Replace current_fs_time() with current_time()
[cascardo/linux.git] / fs / ceph / file.c
index 0daaf7c..a37a343 100644 (file)
@@ -708,7 +708,7 @@ static void ceph_aio_complete_req(struct ceph_osd_request *req)
                }
        }
 
-       ceph_put_page_vector(osd_data->pages, num_pages, false);
+       ceph_put_page_vector(osd_data->pages, num_pages, !aio_req->write);
        ceph_osdc_put_request(req);
 
        if (rc < 0)
@@ -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,
@@ -838,7 +886,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
        int num_pages = 0;
        int flags;
        int ret;
-       struct timespec mtime = current_fs_time(inode->i_sb);
+       struct timespec mtime = current_time(inode);
        size_t count = iov_iter_count(iter);
        loff_t pos = iocb->ki_pos;
        bool write = iov_iter_rw(iter) == WRITE;
@@ -964,7 +1012,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
                                len = ret;
                }
 
-               ceph_put_page_vector(pages, num_pages, false);
+               ceph_put_page_vector(pages, num_pages, !write);
 
                ceph_osdc_put_request(req);
                if (ret < 0)
@@ -985,6 +1033,8 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
        }
 
        if (aio_req) {
+               LIST_HEAD(osd_reqs);
+
                if (aio_req->num_reqs == 0) {
                        kfree(aio_req);
                        return ret;
@@ -993,8 +1043,9 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
                ceph_get_cap_refs(ci, write ? CEPH_CAP_FILE_WR :
                                              CEPH_CAP_FILE_RD);
 
-               while (!list_empty(&aio_req->osd_reqs)) {
-                       req = list_first_entry(&aio_req->osd_reqs,
+               list_splice(&aio_req->osd_reqs, &osd_reqs);
+               while (!list_empty(&osd_reqs)) {
+                       req = list_first_entry(&osd_reqs,
                                               struct ceph_osd_request,
                                               r_unsafe_item);
                        list_del_init(&req->r_unsafe_item);
@@ -1040,7 +1091,7 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos,
        int flags;
        int check_caps = 0;
        int ret;
-       struct timespec mtime = current_fs_time(inode->i_sb);
+       struct timespec mtime = current_time(inode);
        size_t count = iov_iter_count(from);
 
        if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
@@ -1448,16 +1499,14 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
 {
        struct inode *inode = file->f_mapping->host;
        loff_t i_size;
-       int ret;
+       loff_t ret;
 
        inode_lock(inode);
 
        if (whence == SEEK_END || whence == SEEK_DATA || whence == SEEK_HOLE) {
                ret = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE, false);
-               if (ret < 0) {
-                       offset = ret;
+               if (ret < 0)
                        goto out;
-               }
        }
 
        i_size = i_size_read(inode);
@@ -1473,7 +1522,7 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
                 * write() or lseek() might have altered it
                 */
                if (offset == 0) {
-                       offset = file->f_pos;
+                       ret = file->f_pos;
                        goto out;
                }
                offset += file->f_pos;
@@ -1493,11 +1542,11 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
                break;
        }
 
-       offset = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
+       ret = vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
 
 out:
        inode_unlock(inode);
-       return offset;
+       return ret;
 }
 
 static inline void ceph_zero_partial_page(
@@ -1583,9 +1632,9 @@ static int ceph_zero_objects(struct inode *inode, loff_t offset, loff_t length)
 {
        int ret = 0;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       s32 stripe_unit = ceph_file_layout_su(ci->i_layout);
-       s32 stripe_count = ceph_file_layout_stripe_count(ci->i_layout);
-       s32 object_size = ceph_file_layout_object_size(ci->i_layout);
+       s32 stripe_unit = ci->i_layout.stripe_unit;
+       s32 stripe_count = ci->i_layout.stripe_count;
+       s32 object_size = ci->i_layout.object_size;
        u64 object_set_size = object_size * stripe_count;
        u64 nearly, t;