fs: remove mapping->backing_dev_info
[linux-block.git] / fs / ceph / inode.c
index 72607c17e6fd479d246fcf164db8c948488270ae..6b51736051541ea54b6956cf6dce57576f8ffe6f 100644 (file)
@@ -387,6 +387,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb)
        spin_lock_init(&ci->i_ceph_lock);
 
        ci->i_version = 0;
+       ci->i_inline_version = 0;
        ci->i_time_warp_seq = 0;
        ci->i_ceph_flags = 0;
        ci->i_ordered_count = 0;
@@ -658,7 +659,7 @@ void ceph_fill_file_time(struct inode *inode, int issued,
  * Populate an inode based on info from mds.  May be called on new or
  * existing inodes.
  */
-static int fill_inode(struct inode *inode,
+static int fill_inode(struct inode *inode, struct page *locked_page,
                      struct ceph_mds_reply_info_in *iinfo,
                      struct ceph_mds_reply_dirfrag *dirinfo,
                      struct ceph_mds_session *session,
@@ -676,6 +677,7 @@ static int fill_inode(struct inode *inode,
        bool wake = false;
        bool queue_trunc = false;
        bool new_version = false;
+       bool fill_inline = false;
 
        dout("fill_inode %p ino %llx.%llx v %llu had %llu\n",
             inode, ceph_vinop(inode), le64_to_cpu(info->version),
@@ -781,8 +783,6 @@ static int fill_inode(struct inode *inode,
        }
 
        inode->i_mapping->a_ops = &ceph_aops;
-       inode->i_mapping->backing_dev_info =
-               &ceph_sb_to_client(inode->i_sb)->backing_dev_info;
 
        switch (inode->i_mode & S_IFMT) {
        case S_IFIFO:
@@ -875,8 +875,23 @@ static int fill_inode(struct inode *inode,
                           ceph_vinop(inode));
                __ceph_get_fmode(ci, cap_fmode);
        }
+
+       if (iinfo->inline_version > 0 &&
+           iinfo->inline_version >= ci->i_inline_version) {
+               int cache_caps = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO;
+               ci->i_inline_version = iinfo->inline_version;
+               if (ci->i_inline_version != CEPH_INLINE_NONE &&
+                   (locked_page ||
+                    (le32_to_cpu(info->cap.caps) & cache_caps)))
+                       fill_inline = true;
+       }
+
        spin_unlock(&ci->i_ceph_lock);
 
+       if (fill_inline)
+               ceph_fill_inline_data(inode, locked_page,
+                                     iinfo->inline_data, iinfo->inline_len);
+
        if (wake)
                wake_up_all(&ci->i_cap_wq);
 
@@ -969,7 +984,7 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in,
        /* dn must be unhashed */
        if (!d_unhashed(dn))
                d_drop(dn);
-       realdn = d_materialise_unique(dn, in);
+       realdn = d_splice_alias(in, dn);
        if (IS_ERR(realdn)) {
                pr_err("splice_dentry error %ld %p inode %p ino %llx.%llx\n",
                       PTR_ERR(realdn), dn, in, ceph_vinop(in));
@@ -1064,7 +1079,8 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                struct inode *dir = req->r_locked_dir;
 
                if (dir) {
-                       err = fill_inode(dir, &rinfo->diri, rinfo->dirfrag,
+                       err = fill_inode(dir, NULL,
+                                        &rinfo->diri, rinfo->dirfrag,
                                         session, req->r_request_started, -1,
                                         &req->r_caps_reservation);
                        if (err < 0)
@@ -1134,7 +1150,7 @@ retry_lookup:
                }
                req->r_target_inode = in;
 
-               err = fill_inode(in, &rinfo->targeti, NULL,
+               err = fill_inode(in, req->r_locked_page, &rinfo->targeti, NULL,
                                session, req->r_request_started,
                                (!req->r_aborted && rinfo->head->result == 0) ?
                                req->r_fmode : -1,
@@ -1188,20 +1204,18 @@ retry_lookup:
                        struct inode *olddir = req->r_old_dentry_dir;
                        BUG_ON(!olddir);
 
-                       dout(" src %p '%.*s' dst %p '%.*s'\n",
+                       dout(" src %p '%pd' dst %p '%pd'\n",
+                            req->r_old_dentry,
                             req->r_old_dentry,
-                            req->r_old_dentry->d_name.len,
-                            req->r_old_dentry->d_name.name,
-                            dn, dn->d_name.len, dn->d_name.name);
+                            dn, dn);
                        dout("fill_trace doing d_move %p -> %p\n",
                             req->r_old_dentry, dn);
 
                        d_move(req->r_old_dentry, dn);
-                       dout(" src %p '%.*s' dst %p '%.*s'\n",
+                       dout(" src %p '%pd' dst %p '%pd'\n",
                             req->r_old_dentry,
-                            req->r_old_dentry->d_name.len,
-                            req->r_old_dentry->d_name.name,
-                            dn, dn->d_name.len, dn->d_name.name);
+                            req->r_old_dentry,
+                            dn, dn);
 
                        /* ensure target dentry is invalidated, despite
                           rehashing bug in vfs_rename_dir */
@@ -1305,7 +1319,7 @@ static int readdir_prepopulate_inodes_only(struct ceph_mds_request *req,
                        dout("new_inode badness got %d\n", err);
                        continue;
                }
-               rc = fill_inode(in, &rinfo->dir_in[i], NULL, session,
+               rc = fill_inode(in, NULL, &rinfo->dir_in[i], NULL, session,
                                req->r_request_started, -1,
                                &req->r_caps_reservation);
                if (rc < 0) {
@@ -1402,7 +1416,7 @@ retry_lookup:
                        /* reorder parent's d_subdirs */
                        spin_lock(&parent->d_lock);
                        spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED);
-                       list_move(&dn->d_u.d_child, &parent->d_subdirs);
+                       list_move(&dn->d_child, &parent->d_subdirs);
                        spin_unlock(&dn->d_lock);
                        spin_unlock(&parent->d_lock);
                }
@@ -1421,7 +1435,7 @@ retry_lookup:
                        }
                }
 
-               if (fill_inode(in, &rinfo->dir_in[i], NULL, session,
+               if (fill_inode(in, NULL, &rinfo->dir_in[i], NULL, session,
                               req->r_request_started, -1,
                               &req->r_caps_reservation) < 0) {
                        pr_err("fill_inode badness on %p\n", in);
@@ -1904,7 +1918,8 @@ out_put:
  * Verify that we have a lease on the given mask.  If not,
  * do a getattr against an mds.
  */
-int ceph_do_getattr(struct inode *inode, int mask, bool force)
+int __ceph_do_getattr(struct inode *inode, struct page *locked_page,
+                     int mask, bool force)
 {
        struct ceph_fs_client *fsc = ceph_sb_to_client(inode->i_sb);
        struct ceph_mds_client *mdsc = fsc->mdsc;
@@ -1916,7 +1931,8 @@ int ceph_do_getattr(struct inode *inode, int mask, bool force)
                return 0;
        }
 
-       dout("do_getattr inode %p mask %s mode 0%o\n", inode, ceph_cap_string(mask), inode->i_mode);
+       dout("do_getattr inode %p mask %s mode 0%o\n",
+            inode, ceph_cap_string(mask), inode->i_mode);
        if (!force && ceph_caps_issued_mask(ceph_inode(inode), mask, 1))
                return 0;
 
@@ -1927,7 +1943,19 @@ int ceph_do_getattr(struct inode *inode, int mask, bool force)
        ihold(inode);
        req->r_num_caps = 1;
        req->r_args.getattr.mask = cpu_to_le32(mask);
+       req->r_locked_page = locked_page;
        err = ceph_mdsc_do_request(mdsc, NULL, req);
+       if (locked_page && err == 0) {
+               u64 inline_version = req->r_reply_info.targeti.inline_version;
+               if (inline_version == 0) {
+                       /* the reply is supposed to contain inline data */
+                       err = -EINVAL;
+               } else if (inline_version == CEPH_INLINE_NONE) {
+                       err = -ENODATA;
+               } else {
+                       err = req->r_reply_info.targeti.inline_len;
+               }
+       }
        ceph_mdsc_put_request(req);
        dout("do_getattr result=%d\n", err);
        return err;