lkml.org 
[lkml]   [2022]   [Mar]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH v11 08/51] ceph: add support for fscrypt_auth/fscrypt_file to cap messages
    Date
    Add support for new version 12 cap messages that carry the new
    fscrypt_auth and fscrypt_file fields from the inode.

    Signed-off-by: Jeff Layton <jlayton@kernel.org>
    ---
    fs/ceph/caps.c | 76 +++++++++++++++++++++++++++++++++++++++++---------
    1 file changed, 63 insertions(+), 13 deletions(-)

    diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
    index 7d8ef67a1032..b0b7688331b4 100644
    --- a/fs/ceph/caps.c
    +++ b/fs/ceph/caps.c
    @@ -13,6 +13,7 @@
    #include "super.h"
    #include "mds_client.h"
    #include "cache.h"
    +#include "crypto.h"
    #include <linux/ceph/decode.h>
    #include <linux/ceph/messenger.h>

    @@ -1214,15 +1215,12 @@ struct cap_msg_args {
    umode_t mode;
    bool inline_data;
    bool wake;
    + u32 fscrypt_auth_len;
    + u32 fscrypt_file_len;
    + u8 fscrypt_auth[sizeof(struct ceph_fscrypt_auth)]; // for context
    + u8 fscrypt_file[sizeof(u64)]; // for size
    };

    -/*
    - * cap struct size + flock buffer size + inline version + inline data size +
    - * osd_epoch_barrier + oldest_flush_tid
    - */
    -#define CAP_MSG_SIZE (sizeof(struct ceph_mds_caps) + \
    - 4 + 8 + 4 + 4 + 8 + 4 + 4 + 4 + 8 + 8 + 4)
    -
    /* Marshal up the cap msg to the MDS */
    static void encode_cap_msg(struct ceph_msg *msg, struct cap_msg_args *arg)
    {
    @@ -1238,7 +1236,7 @@ static void encode_cap_msg(struct ceph_msg *msg, struct cap_msg_args *arg)
    arg->size, arg->max_size, arg->xattr_version,
    arg->xattr_buf ? (int)arg->xattr_buf->vec.iov_len : 0);

    - msg->hdr.version = cpu_to_le16(10);
    + msg->hdr.version = cpu_to_le16(12);
    msg->hdr.tid = cpu_to_le64(arg->flush_tid);

    fc = msg->front.iov_base;
    @@ -1309,6 +1307,21 @@ static void encode_cap_msg(struct ceph_msg *msg, struct cap_msg_args *arg)

    /* Advisory flags (version 10) */
    ceph_encode_32(&p, arg->flags);
    +
    + /* dirstats (version 11) - these are r/o on the client */
    + ceph_encode_64(&p, 0);
    + ceph_encode_64(&p, 0);
    +
    +#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
    + /* fscrypt_auth and fscrypt_file (version 12) */
    + ceph_encode_32(&p, arg->fscrypt_auth_len);
    + ceph_encode_copy(&p, arg->fscrypt_auth, arg->fscrypt_auth_len);
    + ceph_encode_32(&p, arg->fscrypt_file_len);
    + ceph_encode_copy(&p, arg->fscrypt_file, arg->fscrypt_file_len);
    +#else /* CONFIG_FS_ENCRYPTION */
    + ceph_encode_32(&p, 0);
    + ceph_encode_32(&p, 0);
    +#endif /* CONFIG_FS_ENCRYPTION */
    }

    /*
    @@ -1430,8 +1443,37 @@ static void __prep_cap(struct cap_msg_args *arg, struct ceph_cap *cap,
    }
    }
    arg->flags = flags;
    +#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
    + if (ci->fscrypt_auth_len &&
    + WARN_ON_ONCE(ci->fscrypt_auth_len != sizeof(struct ceph_fscrypt_auth))) {
    + /* Don't set this if it isn't right size */
    + arg->fscrypt_auth_len = 0;
    + } else {
    + arg->fscrypt_auth_len = ci->fscrypt_auth_len;
    + memcpy(arg->fscrypt_auth, ci->fscrypt_auth,
    + min_t(size_t, ci->fscrypt_auth_len, sizeof(arg->fscrypt_auth)));
    + }
    + /* FIXME: use this to track "real" size */
    + arg->fscrypt_file_len = 0;
    +#endif /* CONFIG_FS_ENCRYPTION */
    }

    +#define CAP_MSG_FIXED_FIELDS (sizeof(struct ceph_mds_caps) + \
    + 4 + 8 + 4 + 4 + 8 + 4 + 4 + 4 + 8 + 8 + 4 + 8 + 8 + 4 + 4)
    +
    +#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
    +static inline int cap_msg_size(struct cap_msg_args *arg)
    +{
    + return CAP_MSG_FIXED_FIELDS + arg->fscrypt_auth_len +
    + arg->fscrypt_file_len;
    +}
    +#else
    +static inline int cap_msg_size(struct cap_msg_args *arg)
    +{
    + return CAP_MSG_FIXED_FIELDS;
    +}
    +#endif /* CONFIG_FS_ENCRYPTION */
    +
    /*
    * Send a cap msg on the given inode.
    *
    @@ -1442,7 +1484,7 @@ static void __send_cap(struct cap_msg_args *arg, struct ceph_inode_info *ci)
    struct ceph_msg *msg;
    struct inode *inode = &ci->vfs_inode;

    - msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, CAP_MSG_SIZE, GFP_NOFS, false);
    + msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, cap_msg_size(arg), GFP_NOFS, false);
    if (!msg) {
    pr_err("error allocating cap msg: ino (%llx.%llx) flushing %s tid %llu, requeuing cap.\n",
    ceph_vinop(inode), ceph_cap_string(arg->dirty),
    @@ -1468,10 +1510,6 @@ static inline int __send_flush_snap(struct inode *inode,
    struct cap_msg_args arg;
    struct ceph_msg *msg;

    - msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, CAP_MSG_SIZE, GFP_NOFS, false);
    - if (!msg)
    - return -ENOMEM;
    -
    arg.session = session;
    arg.ino = ceph_vino(inode).ino;
    arg.cid = 0;
    @@ -1509,6 +1547,18 @@ static inline int __send_flush_snap(struct inode *inode,
    arg.flags = 0;
    arg.wake = false;

    + /*
    + * No fscrypt_auth changes from a capsnap. It will need
    + * to update fscrypt_file on size changes (TODO).
    + */
    + arg.fscrypt_auth_len = 0;
    + arg.fscrypt_file_len = 0;
    +
    + msg = ceph_msg_new(CEPH_MSG_CLIENT_CAPS, cap_msg_size(&arg),
    + GFP_NOFS, false);
    + if (!msg)
    + return -ENOMEM;
    +
    encode_cap_msg(msg, &arg);
    ceph_con_send(&arg.session->s_con, msg);
    return 0;
    --
    2.35.1
    \
     
     \ /
      Last update: 2022-03-22 15:19    [W:4.499 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site