]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
ceph: define argument structure for handle_cap_grant
authorYan, Zheng <zyan@redhat.com>
Fri, 27 Apr 2018 02:29:44 +0000 (10:29 +0800)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Tue, 2 Jul 2019 16:30:46 +0000 (18:30 +0200)
BugLink: https://bugs.launchpad.net/bugs/1834235
The data structure includes the versioned feilds of cap message.

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
(cherry picked from commit a1c6b8358171c16db0f858a7fbb28aa574b07c09)
Signed-off-by: Connor Kuehl <connor.kuehl@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
fs/ceph/caps.c

index ad3525bc6b834a96fc292dff00759752586debf0..84d6ac8b373124c0c5480ae992bac9c0ef6816b9 100644 (file)
@@ -2909,24 +2909,32 @@ static void invalidate_aliases(struct inode *inode)
                dput(prev);
 }
 
+struct cap_extra_info {
+       struct ceph_string *pool_ns;
+       /* inline data */
+       u64 inline_version;
+       void *inline_data;
+       u32 inline_len;
+       /* currently issued */
+       int issued;
+};
+
 /*
  * Handle a cap GRANT message from the MDS.  (Note that a GRANT may
  * actually be a revocation if it specifies a smaller cap set.)
  *
  * caller holds s_mutex and i_ceph_lock, we drop both.
  */
-static void handle_cap_grant(struct ceph_mds_client *mdsc,
-                            struct inode *inode, struct ceph_mds_caps *grant,
-                            struct ceph_string **pns, u64 inline_version,
-                            void *inline_data, u32 inline_len,
-                            struct ceph_buffer *xattr_buf,
+static void handle_cap_grant(struct inode *inode,
                             struct ceph_mds_session *session,
-                            struct ceph_cap *cap, int issued)
+                            struct ceph_cap *cap,
+                            struct ceph_mds_caps *grant,
+                            struct ceph_buffer *xattr_buf,
+                            struct cap_extra_info *extra_info)
        __releases(ci->i_ceph_lock)
-       __releases(mdsc->snap_rwsem)
+       __releases(session->s_mdsc->snap_rwsem)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
-       int mds = session->s_mds;
        int seq = le32_to_cpu(grant->seq);
        int newcaps = le32_to_cpu(grant->caps);
        int used, wanted, dirty;
@@ -2942,7 +2950,7 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
        bool fill_inline = false;
 
        dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
-            inode, cap, mds, seq, ceph_cap_string(newcaps));
+            inode, cap, session->s_mds, seq, ceph_cap_string(newcaps));
        dout(" size %llu max_size %llu, i_size %llu\n", size, max_size,
                inode->i_size);
 
@@ -2988,7 +2996,7 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
        __check_cap_issue(ci, cap, newcaps);
 
        if ((newcaps & CEPH_CAP_AUTH_SHARED) &&
-           (issued & CEPH_CAP_AUTH_EXCL) == 0) {
+           (extra_info->issued & CEPH_CAP_AUTH_EXCL) == 0) {
                inode->i_mode = le32_to_cpu(grant->mode);
                inode->i_uid = make_kuid(&init_user_ns, le32_to_cpu(grant->uid));
                inode->i_gid = make_kgid(&init_user_ns, le32_to_cpu(grant->gid));
@@ -2998,14 +3006,15 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
        }
 
        if ((newcaps & CEPH_CAP_AUTH_SHARED) &&
-           (issued & CEPH_CAP_LINK_EXCL) == 0) {
+           (extra_info->issued & CEPH_CAP_LINK_EXCL) == 0) {
                set_nlink(inode, le32_to_cpu(grant->nlink));
                if (inode->i_nlink == 0 &&
                    (newcaps & (CEPH_CAP_LINK_SHARED | CEPH_CAP_LINK_EXCL)))
                        deleted_inode = true;
        }
 
-       if ((issued & CEPH_CAP_XATTR_EXCL) == 0 && grant->xattr_len) {
+       if ((extra_info->issued & CEPH_CAP_XATTR_EXCL) == 0 &&
+           grant->xattr_len) {
                int len = le32_to_cpu(grant->xattr_len);
                u64 version = le64_to_cpu(grant->xattr_version);
 
@@ -3025,7 +3034,7 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
                ceph_decode_timespec(&mtime, &grant->mtime);
                ceph_decode_timespec(&atime, &grant->atime);
                ceph_decode_timespec(&ctime, &grant->ctime);
-               ceph_fill_file_time(inode, issued,
+               ceph_fill_file_time(inode, extra_info->issued,
                                    le32_to_cpu(grant->time_warp_seq),
                                    &ctime, &mtime, &atime);
        }
@@ -3038,15 +3047,16 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
                ceph_file_layout_from_legacy(&ci->i_layout, &grant->layout);
                old_ns = rcu_dereference_protected(ci->i_layout.pool_ns,
                                        lockdep_is_held(&ci->i_ceph_lock));
-               rcu_assign_pointer(ci->i_layout.pool_ns, *pns);
+               rcu_assign_pointer(ci->i_layout.pool_ns, extra_info->pool_ns);
 
-               if (ci->i_layout.pool_id != old_pool || *pns != old_ns)
+               if (ci->i_layout.pool_id != old_pool ||
+                   extra_info->pool_ns != old_ns)
                        ci->i_ceph_flags &= ~CEPH_I_POOL_PERM;
 
-               *pns = old_ns;
+               extra_info->pool_ns = old_ns;
 
                /* size/truncate_seq? */
-               queue_trunc = ceph_fill_file_size(inode, issued,
+               queue_trunc = ceph_fill_file_size(inode, extra_info->issued,
                                        le32_to_cpu(grant->truncate_seq),
                                        le64_to_cpu(grant->truncate_size),
                                        size);
@@ -3125,24 +3135,26 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc,
        }
        BUG_ON(cap->issued & ~cap->implemented);
 
-       if (inline_version > 0 && inline_version >= ci->i_inline_version) {
-               ci->i_inline_version = inline_version;
+       if (extra_info->inline_version > 0 &&
+           extra_info->inline_version >= ci->i_inline_version) {
+               ci->i_inline_version = extra_info->inline_version;
                if (ci->i_inline_version != CEPH_INLINE_NONE &&
                    (newcaps & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)))
                        fill_inline = true;
        }
 
        if (le32_to_cpu(grant->op) == CEPH_CAP_OP_IMPORT) {
-               if (newcaps & ~issued)
+               if (newcaps & ~extra_info->issued)
                        wake = true;
-               kick_flushing_inode_caps(mdsc, session, inode);
-               up_read(&mdsc->snap_rwsem);
+               kick_flushing_inode_caps(session->s_mdsc, session, inode);
+               up_read(&session->s_mdsc->snap_rwsem);
        } else {
                spin_unlock(&ci->i_ceph_lock);
        }
 
        if (fill_inline)
-               ceph_fill_inline_data(inode, NULL, inline_data, inline_len);
+               ceph_fill_inline_data(inode, NULL, extra_info->inline_data,
+                                     extra_info->inline_len);
 
        if (queue_trunc)
                ceph_queue_vmtruncate(inode);
@@ -3599,31 +3611,24 @@ void ceph_handle_caps(struct ceph_mds_session *session,
                      struct ceph_msg *msg)
 {
        struct ceph_mds_client *mdsc = session->s_mdsc;
-       struct super_block *sb = mdsc->fsc->sb;
        struct inode *inode;
        struct ceph_inode_info *ci;
        struct ceph_cap *cap;
        struct ceph_mds_caps *h;
        struct ceph_mds_cap_peer *peer = NULL;
        struct ceph_snap_realm *realm = NULL;
-       struct ceph_string *pool_ns = NULL;
-       int mds = session->s_mds;
-       int op, issued;
+       int op;
        u32 seq, mseq;
        struct ceph_vino vino;
-       u64 tid;
-       u64 inline_version = 0;
-       void *inline_data = NULL;
-       u32  inline_len = 0;
        void *snaptrace;
        size_t snaptrace_len;
        void *p, *end;
+       struct cap_extra_info extra_info = {};
 
-       dout("handle_caps from mds%d\n", mds);
+       dout("handle_caps from mds%d\n", session->s_mds);
 
        /* decode */
        end = msg->front.iov_base + msg->front.iov_len;
-       tid = le64_to_cpu(msg->hdr.tid);
        if (msg->front.iov_len < sizeof(*h))
                goto bad;
        h = msg->front.iov_base;
@@ -3658,12 +3663,12 @@ void ceph_handle_caps(struct ceph_mds_session *session,
        }
 
        if (le16_to_cpu(msg->hdr.version) >= 4) {
-               ceph_decode_64_safe(&p, end, inline_version, bad);
-               ceph_decode_32_safe(&p, end, inline_len, bad);
-               if (p + inline_len > end)
+               ceph_decode_64_safe(&p, end, extra_info.inline_version, bad);
+               ceph_decode_32_safe(&p, end, extra_info.inline_len, bad);
+               if (p + extra_info.inline_len > end)
                        goto bad;
-               inline_data = p;
-               p += inline_len;
+               extra_info.inline_data = p;
+               p += extra_info.inline_len;
        }
 
        if (le16_to_cpu(msg->hdr.version) >= 5) {
@@ -3688,13 +3693,14 @@ void ceph_handle_caps(struct ceph_mds_session *session,
                ceph_decode_32_safe(&p, end, pool_ns_len, bad);
                if (pool_ns_len > 0) {
                        ceph_decode_need(&p, end, pool_ns_len, bad);
-                       pool_ns = ceph_find_or_create_string(p, pool_ns_len);
+                       extra_info.pool_ns =
+                               ceph_find_or_create_string(p, pool_ns_len);
                        p += pool_ns_len;
                }
        }
 
        /* lookup ino */
-       inode = ceph_find_inode(sb, vino);
+       inode = ceph_find_inode(mdsc->fsc->sb, vino);
        ci = ceph_inode(inode);
        dout(" op %s ino %llx.%llx inode %p\n", ceph_cap_op_name(op), vino.ino,
             vino.snap, inode);
@@ -3727,7 +3733,8 @@ void ceph_handle_caps(struct ceph_mds_session *session,
        /* these will work even if we don't have a cap yet */
        switch (op) {
        case CEPH_CAP_OP_FLUSHSNAP_ACK:
-               handle_cap_flushsnap_ack(inode, tid, h, session);
+               handle_cap_flushsnap_ack(inode, le64_to_cpu(msg->hdr.tid),
+                                        h, session);
                goto done;
 
        case CEPH_CAP_OP_EXPORT:
@@ -3746,10 +3753,9 @@ void ceph_handle_caps(struct ceph_mds_session *session,
                        down_read(&mdsc->snap_rwsem);
                }
                handle_cap_import(mdsc, inode, h, peer, session,
-                                 &cap, &issued);
-               handle_cap_grant(mdsc, inode, h, &pool_ns,
-                                inline_version, inline_data, inline_len,
-                                msg->middle, session, cap, issued);
+                                 &cap, &extra_info.issued);
+               handle_cap_grant(inode, session, cap,
+                                h, msg->middle, &extra_info);
                if (realm)
                        ceph_put_snap_realm(mdsc, realm);
                goto done_unlocked;
@@ -3757,10 +3763,11 @@ void ceph_handle_caps(struct ceph_mds_session *session,
 
        /* the rest require a cap */
        spin_lock(&ci->i_ceph_lock);
-       cap = __get_cap_for_mds(ceph_inode(inode), mds);
+       cap = __get_cap_for_mds(ceph_inode(inode), session->s_mds);
        if (!cap) {
                dout(" no cap on %p ino %llx.%llx from mds%d\n",
-                    inode, ceph_ino(inode), ceph_snap(inode), mds);
+                    inode, ceph_ino(inode), ceph_snap(inode),
+                    session->s_mds);
                spin_unlock(&ci->i_ceph_lock);
                goto flush_cap_releases;
        }
@@ -3769,15 +3776,15 @@ void ceph_handle_caps(struct ceph_mds_session *session,
        switch (op) {
        case CEPH_CAP_OP_REVOKE:
        case CEPH_CAP_OP_GRANT:
-               __ceph_caps_issued(ci, &issued);
-               issued |= __ceph_caps_dirty(ci);
-               handle_cap_grant(mdsc, inode, h, &pool_ns,
-                                inline_version, inline_data, inline_len,
-                                msg->middle, session, cap, issued);
+               __ceph_caps_issued(ci, &extra_info.issued);
+               extra_info.issued |= __ceph_caps_dirty(ci);
+               handle_cap_grant(inode, session, cap,
+                                h, msg->middle, &extra_info);
                goto done_unlocked;
 
        case CEPH_CAP_OP_FLUSH_ACK:
-               handle_cap_flush_ack(inode, tid, h, session, cap);
+               handle_cap_flush_ack(inode, le64_to_cpu(msg->hdr.tid),
+                                    h, session, cap);
                break;
 
        case CEPH_CAP_OP_TRUNC:
@@ -3804,7 +3811,7 @@ done:
        mutex_unlock(&session->s_mutex);
 done_unlocked:
        iput(inode);
-       ceph_put_string(pool_ns);
+       ceph_put_string(extra_info.pool_ns);
        return;
 
 bad: