| @@ -2881,6 +2881,17 @@ static void encode_mclientrequest_tail(void **p, · 2880 unmodified lines |
| 2881 | } | 2881 | } |
| 2882 | } | 2882 | } |
| 2883 | | 2883 | |
| | 2884 | static inline u16 mds_supported_head_version(struct ceph_mds_session *session) |
| | 2885 | { |
| | 2886 | if (!test_bit(CEPHFS_FEATURE_32BITS_RETRY_FWD, &session->s_features)) |
| | 2887 | return 1; |
| | 2888 | |
| | 2889 | if (!test_bit(CEPHFS_FEATURE_HAS_OWNER_UIDGID, &session->s_features)) |
| | 2890 | return 2; |
| | 2891 | |
| | 2892 | return CEPH_MDS_REQUEST_HEAD_VERSION; |
| | 2893 | } |
| | 2894 | |
| 2884 | static struct ceph_mds_request_head_legacy * | 2895 | static struct ceph_mds_request_head_legacy * |
| 2885 | find_legacy_request_head(void *p, u64 features) | 2896 | find_legacy_request_head(void *p, u64 features) |
| 2886 | { | 2897 | { |
| @@ -2902,6 +2913,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_session *session, · 15 unmodified lines |
| 2902 | { | 2913 | { |
| 2903 | int mds = session->s_mds; | 2914 | int mds = session->s_mds; |
| 2904 | struct ceph_mds_client *mdsc = session->s_mdsc; | 2915 | struct ceph_mds_client *mdsc = session->s_mdsc; |
| | 2916 | struct ceph_client *cl = mdsc->fsc->client; |
| 2905 | struct ceph_msg *msg; | 2917 | struct ceph_msg *msg; |
| 2906 | struct ceph_mds_request_head_legacy *lhead; | 2918 | struct ceph_mds_request_head_legacy *lhead; |
| 2907 | const char *path1 = NULL; | 2919 | const char *path1 = NULL; |
| @@ -2915,8 +2927,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_session *session, · 7 unmodified lines |
| 2915 | void *p, *end; | 2927 | void *p, *end; |
| 2916 | int ret; | 2928 | int ret; |
| 2917 | bool legacy = !(session->s_con.peer_features & CEPH_FEATURE_FS_BTIME); | 2929 | bool legacy = !(session->s_con.peer_features & CEPH_FEATURE_FS_BTIME); |
| 2918 | bool old_version = !test_bit(CEPHFS_FEATURE_32BITS_RETRY_FWD, | 2930 | u16 request_head_version = mds_supported_head_version(session); |
| 2919 | &session->s_features); | | |
| 2920 | | 2931 | |
| 2921 | ret = set_request_path_attr(mdsc, req->r_inode, req->r_dentry, | 2932 | ret = set_request_path_attr(mdsc, req->r_inode, req->r_dentry, |
| 2922 | req->r_parent, req->r_path1, req->r_ino1.ino, | 2933 | req->r_parent, req->r_path1, req->r_ino1.ino, |
| @@ -2957,8 +2968,10 @@ static struct ceph_msg *create_request_message(struct ceph_mds_session *session, · 34 unmodified lines |
| 2957 | */ | 2968 | */ |
| 2958 | if (legacy) | 2969 | if (legacy) |
| 2959 | len = sizeof(struct ceph_mds_request_head_legacy); | 2970 | len = sizeof(struct ceph_mds_request_head_legacy); |
| 2960 | else if (old_version) | 2971 | else if (request_head_version == 1) |
| 2961 | len = sizeof(struct ceph_mds_request_head_old); | 2972 | len = sizeof(struct ceph_mds_request_head_old); |
| | 2973 | else if (request_head_version == 2) |
| | 2974 | len = offsetofend(struct ceph_mds_request_head, ext_num_fwd); |
| 2962 | else | 2975 | else |
| 2963 | len = sizeof(struct ceph_mds_request_head); | 2976 | len = sizeof(struct ceph_mds_request_head); |
| 2964 | | 2977 | |
| @@ -3008,6 +3021,18 @@ static struct ceph_msg *create_request_message(struct ceph_mds_session *session, · 43 unmodified lines |
| 3008 | lhead = find_legacy_request_head(msg->front.iov_base, | 3021 | lhead = find_legacy_request_head(msg->front.iov_base, |
| 3009 | session->s_con.peer_features); | 3022 | session->s_con.peer_features); |
| 3010 | | 3023 | |
| | 3024 | if ((req->r_mnt_idmap != &nop_mnt_idmap) && |
| | 3025 | !test_bit(CEPHFS_FEATURE_HAS_OWNER_UIDGID, &session->s_features)) { |
| | 3026 | WARN_ON_ONCE(!IS_CEPH_MDS_OP_NEWINODE(req->r_op)); |
| | 3027 | |
| | 3028 | pr_err_ratelimited_client(cl, |
| | 3029 | "idmapped mount is used and CEPHFS_FEATURE_HAS_OWNER_UIDGID" |
| | 3030 | " is not supported by MDS. Fail request with -EIO.\n"); |
| | 3031 | |
| | 3032 | ret = -EIO; |
| | 3033 | goto out_err; |
| | 3034 | } |
| | 3035 | |
| 3011 | /* | 3036 | /* |
| 3012 | * The ceph_mds_request_head_legacy didn't contain a version field, and | 3037 | * The ceph_mds_request_head_legacy didn't contain a version field, and |
| 3013 | * one was added when we moved the message version from 3->4. | 3038 | * one was added when we moved the message version from 3->4. |
| @@ -3015,17 +3040,40 @@ static struct ceph_msg *create_request_message(struct ceph_mds_session *session, · 1 unmodified line |
| 3015 | if (legacy) { | 3040 | if (legacy) { |
| 3016 | msg->hdr.version = cpu_to_le16(3); | 3041 | msg->hdr.version = cpu_to_le16(3); |
| 3017 | p = msg->front.iov_base + sizeof(*lhead); | 3042 | p = msg->front.iov_base + sizeof(*lhead); |
| 3018 | } else if (old_version) { | 3043 | } else if (request_head_version == 1) { |
| 3019 | struct ceph_mds_request_head_old *ohead = msg->front.iov_base; | 3044 | struct ceph_mds_request_head_old *ohead = msg->front.iov_base; |
| 3020 | | 3045 | |
| 3021 | msg->hdr.version = cpu_to_le16(4); | 3046 | msg->hdr.version = cpu_to_le16(4); |
| 3022 | ohead->version = cpu_to_le16(1); | 3047 | ohead->version = cpu_to_le16(1); |
| 3023 | p = msg->front.iov_base + sizeof(*ohead); | 3048 | p = msg->front.iov_base + sizeof(*ohead); |
| | 3049 | } else if (request_head_version == 2) { |
| | 3050 | struct ceph_mds_request_head *nhead = msg->front.iov_base; |
| | 3051 | |
| | 3052 | msg->hdr.version = cpu_to_le16(6); |
| | 3053 | nhead->version = cpu_to_le16(2); |
| | 3054 | |
| | 3055 | p = msg->front.iov_base + offsetofend(struct ceph_mds_request_head, ext_num_fwd); |
| 3024 | } else { | 3056 | } else { |
| 3025 | struct ceph_mds_request_head *nhead = msg->front.iov_base; | 3057 | struct ceph_mds_request_head *nhead = msg->front.iov_base; |
| | 3058 | kuid_t owner_fsuid; |
| | 3059 | kgid_t owner_fsgid; |
| 3026 | | 3060 | |
| 3027 | msg->hdr.version = cpu_to_le16(6); | 3061 | msg->hdr.version = cpu_to_le16(6); |
| 3028 | nhead->version = cpu_to_le16(CEPH_MDS_REQUEST_HEAD_VERSION); | 3062 | nhead->version = cpu_to_le16(CEPH_MDS_REQUEST_HEAD_VERSION); |
| | 3063 | nhead->struct_len = cpu_to_le32(sizeof(struct ceph_mds_request_head)); |
| | 3064 | |
| | 3065 | if (IS_CEPH_MDS_OP_NEWINODE(req->r_op)) { |
| | 3066 | owner_fsuid = from_vfsuid(req->r_mnt_idmap, &init_user_ns, |
| | 3067 | VFSUIDT_INIT(req->r_cred->fsuid)); |
| | 3068 | owner_fsgid = from_vfsgid(req->r_mnt_idmap, &init_user_ns, |
| | 3069 | VFSGIDT_INIT(req->r_cred->fsgid)); |
| | 3070 | nhead->owner_uid = cpu_to_le32(from_kuid(&init_user_ns, owner_fsuid)); |
| | 3071 | nhead->owner_gid = cpu_to_le32(from_kgid(&init_user_ns, owner_fsgid)); |
| | 3072 | } else { |
| | 3073 | nhead->owner_uid = cpu_to_le32(-1); |
| | 3074 | nhead->owner_gid = cpu_to_le32(-1); |
| | 3075 | } |
| | 3076 | |
| 3029 | p = msg->front.iov_base + sizeof(*nhead); | 3077 | p = msg->front.iov_base + sizeof(*nhead); |
| 3030 | } | 3078 | } |
| 3031 | | 3079 | |