struct group_info *uc_ginfo;
struct md_identity *uc_identity;
char uc_jobid[LUSTRE_JOBID_SIZE];
+ lnet_nid_t uc_nid;
};
struct lu_ucred *lu_ucred(const struct lu_env *env);
LLOG_F_IS_FIXSIZE = 0x10,
LLOG_F_EXT_EXTRA_FLAGS = 0x20,
LLOG_F_EXT_X_UIDGID = 0x40,
+ LLOG_F_EXT_X_NID = 0x80,
/* Note: Flags covered by LLOG_F_EXT_MASK will be inherited from
* catlog to plain log, so do not add LLOG_F_IS_FIXSIZE here,
* because the catlog record is usually fixed size, but its plain
* log record can be variable */
LLOG_F_EXT_MASK = LLOG_F_EXT_JOBID | LLOG_F_EXT_EXTRA_FLAGS |
- LLOG_F_EXT_X_UIDGID,
+ LLOG_F_EXT_X_UIDGID | LLOG_F_EXT_X_NID,
};
/* On-disk header structure of each log object, stored in little endian order */
enum changelog_rec_extra_flags {
CLFE_INVALID = 0,
CLFE_UIDGID = 0x0001,
- CLFE_SUPPORTED = CLFE_UIDGID
+ CLFE_NID = 0x0002,
+ CLFE_SUPPORTED = CLFE_UIDGID | CLFE_NID
};
enum changelog_send_flag {
enum changelog_send_extra_flag {
/* Pack uid/gid into the changelog record */
CHANGELOG_EXTRA_FLAG_UIDGID = 0x01,
+ /* Pack nid into the changelog record */
+ CHANGELOG_EXTRA_FLAG_NID = 0x02,
};
#define CR_MAXSIZE cfs_size_round(2 * NAME_MAX + 2 + \
__u64 cr_gid;
};
+/* Changelog extra extension to include NID. */
+struct changelog_ext_nid {
+ /* have __u64 instead of lnet_nid_t type for use by client api */
+ __u64 cr_nid;
+ /* for use when IPv6 support is added */
+ __u64 extra;
+ __u32 padding;
+};
+
static inline struct changelog_ext_extra_flags *changelog_rec_extra_flags(
const struct changelog_rec *rec);
size += sizeof(struct changelog_ext_extra_flags);
if (cref & CLFE_UIDGID)
size += sizeof(struct changelog_ext_uidgid);
+ if (cref & CLFE_NID)
+ size += sizeof(struct changelog_ext_nid);
}
return size;
CLFE_INVALID));
}
+/* The nid is the second extra extension */
+static inline
+struct changelog_ext_nid *changelog_rec_nid(const struct changelog_rec *rec)
+{
+ enum changelog_rec_flags crf = rec->cr_flags &
+ (CLF_VERSION | CLF_RENAME | CLF_JOBID | CLF_EXTRA_FLAGS);
+ enum changelog_rec_extra_flags cref = CLFE_INVALID;
+
+ if (rec->cr_flags & CLF_EXTRA_FLAGS)
+ cref = changelog_rec_extra_flags(rec)->cr_extra_flags &
+ CLFE_UIDGID;
+
+ return (struct changelog_ext_nid *)((char *)rec +
+ changelog_rec_offset(crf, cref));
+}
+
/* The name follows the rename, jobid and extra flags extns, if present */
static inline char *changelog_rec_name(const struct changelog_rec *rec)
{
enum changelog_rec_flags crf_wanted,
enum changelog_rec_extra_flags cref_want)
{
+ char *nid_mov = NULL;
char *uidgid_mov = NULL;
char *ef_mov;
char *jid_mov;
/* Locations of extensions in the remapped record */
if (rec->cr_flags & CLF_EXTRA_FLAGS) {
+ nid_mov = (char *)rec +
+ changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
+ cref_want & ~CLFE_NID);
uidgid_mov = (char *)rec +
changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
- CLFE_INVALID);
+ cref_want & ~(CLFE_UIDGID |
+ CLFE_NID));
cref = changelog_rec_extra_flags(rec)->cr_extra_flags;
}
/* Move the extension fields to the desired positions */
if ((crf_wanted & CLF_EXTRA_FLAGS) &&
(rec->cr_flags & CLF_EXTRA_FLAGS)) {
+ if ((cref_want & CLFE_NID) && (cref & CLFE_NID))
+ memmove(nid_mov, changelog_rec_nid(rec),
+ sizeof(struct changelog_ext_nid));
+
if ((cref_want & CLFE_UIDGID) && (cref & CLFE_UIDGID))
memmove(uidgid_mov, changelog_rec_uidgid(rec),
sizeof(struct changelog_ext_uidgid));
sizeof(struct changelog_ext_rename));
/* Clear newly added fields */
+ if (nid_mov && (cref_want & CLFE_NID) &&
+ !(cref & CLFE_NID))
+ memset(nid_mov, 0, sizeof(struct changelog_ext_nid));
+
if (uidgid_mov && (cref_want & CLFE_UIDGID) &&
!(cref & CLFE_UIDGID))
memset(uidgid_mov, 0, sizeof(struct changelog_ext_uidgid));
LLOG_F_IS_CAT |
LLOG_F_EXT_JOBID |
LLOG_F_EXT_EXTRA_FLAGS |
- LLOG_F_EXT_X_UIDGID,
+ LLOG_F_EXT_X_UIDGID |
+ LLOG_F_EXT_X_NID,
NULL);
if (rc) {
CERROR("%s: fail to init llog handle: rc = %d\n",
{
const struct lu_ucred *uc = lu_ucred(env);
enum changelog_rec_flags crf = CLF_EXTRA_FLAGS;
- enum changelog_rec_extra_flags crfe = CLFE_UIDGID;
+ enum changelog_rec_extra_flags crfe = CLFE_UIDGID | CLFE_NID;
if (sname != NULL)
crf |= CLF_RENAME;
uidgid->cr_gid = gid;
}
+void mdd_changelog_rec_extra_nid(struct changelog_rec *rec,
+ lnet_nid_t nid)
+{
+ struct changelog_ext_nid *clnid = changelog_rec_nid(rec);
+
+ clnid->cr_nid = nid;
+}
+
/** Store a namespace change changelog record
* If this fails, we must fail the whole transaction; we don't
* want the change to commit without the log entry.
if (uc->uc_jobid[0] != '\0')
crf |= CLF_JOBID;
xflags |= CLFE_UIDGID;
+ xflags |= CLFE_NID;
}
if (sname != NULL)
if (xflags & CLFE_UIDGID)
mdd_changelog_rec_extra_uidgid(&rec->cr,
uc->uc_uid, uc->uc_gid);
+ if (xflags & CLFE_NID)
+ mdd_changelog_rec_extra_nid(&rec->cr, uc->uc_nid);
}
rec->cr.cr_type = (__u32)type;
void mdd_changelog_rec_ext_extra_flags(struct changelog_rec *rec, __u64 eflags);
void mdd_changelog_rec_extra_uidgid(struct changelog_rec *rec,
__u64 uid, __u64 gid);
+void mdd_changelog_rec_extra_nid(struct changelog_rec *rec,
+ lnet_nid_t nid);
int mdd_changelog_store(const struct lu_env *env, struct mdd_device *mdd,
struct llog_changelog_rec *rec, struct thandle *th);
int mdd_changelog_data_store(const struct lu_env *env, struct mdd_device *mdd,
if (uc->uc_jobid[0] != '\0')
flags |= CLF_JOBID;
xflags |= CLFE_UIDGID;
+ xflags |= CLFE_NID;
}
reclen = llog_data_len(LLOG_CHANGELOG_HDR_SZ +
if (xflags & CLFE_UIDGID)
mdd_changelog_rec_extra_uidgid(&rec->cr,
uc->uc_uid, uc->uc_gid);
+ if (xflags & CLFE_NID)
+ mdd_changelog_rec_extra_nid(&rec->cr, uc->uc_nid);
}
rc = mdd_changelog_store(env, mdd, rec, handle);
uc->uc_jobid[0] = '\0';
}
+static void ucred_set_nid(struct mdt_thread_info *info, struct lu_ucred *uc)
+{
+ if (info && info->mti_exp && info->mti_exp->exp_connection)
+ uc->uc_nid = info->mti_exp->exp_connection->c_peer.nid;
+ else
+ uc->uc_nid = LNET_NID_ANY;
+}
+
static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
void *buf, bool drop_fs_cap)
{
ucred->uc_cap = pud->pud_cap;
ucred->uc_valid = UCRED_NEW;
ucred_set_jobid(info, ucred);
+ ucred_set_nid(info, ucred);
EXIT;
uc->uc_cap &= ~CFS_CAP_FS_MASK;
uc->uc_valid = UCRED_OLD;
ucred_set_jobid(info, uc);
+ ucred_set_nid(info, uc);
EXIT;
*/
static void changelog_block_trim_ext(struct llog_rec_hdr *hdr,
struct llog_rec_hdr *last_hdr,
- enum changelog_rec_flags flags,
- enum changelog_rec_extra_flags extra_flags)
+ struct llog_handle *loghandle)
{
+ enum changelog_rec_flags flags = CLF_SUPPORTED;
+ enum changelog_rec_extra_flags extra_flags = CLFE_SUPPORTED;
+
+ if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_NID))
+ extra_flags &= ~CLFE_NID;
+ if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_UIDGID))
+ extra_flags &= ~CLFE_UIDGID;
+ if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_EXTRA_FLAGS))
+ flags &= ~CLF_EXTRA_FLAGS;
+ if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_JOBID))
+ flags &= ~CLF_JOBID;
+
+ if (flags == CLF_SUPPORTED && extra_flags == CLFE_SUPPORTED)
+ return;
+
if (hdr->lrh_type != CHANGELOG_REC)
return;
int last_idx = *cur_idx;
__u64 last_offset = *cur_offset;
bool force_mini_rec = false;
- enum changelog_rec_flags flags;
- enum changelog_rec_extra_flags xflags;
ENTRY;
}
/* Trim unsupported extensions for compat w/ older clients */
- flags = CLF_SUPPORTED;
- xflags = CLFE_SUPPORTED;
- if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_UIDGID))
- xflags &= ~CLFE_UIDGID;
- if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_EXTRA_FLAGS))
- flags &= ~CLF_EXTRA_FLAGS;
- if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_JOBID))
- flags &= ~CLF_JOBID;
- if (flags != CLF_SUPPORTED || xflags != CLFE_SUPPORTED)
- changelog_block_trim_ext(rec, last_rec, flags, xflags);
+ changelog_block_trim_ext(rec, last_rec, loghandle);
GOTO(out, rc = 0);
struct dt_device *dt;
loff_t cur_offset;
__u32 chunk_size;
- enum changelog_rec_flags flags;
- enum changelog_rec_extra_flags xflags;
int rc;
ENTRY;
}
/* Trim unsupported extensions for compat w/ older clients */
- flags = CLF_SUPPORTED;
- xflags = CLFE_SUPPORTED;
- if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_X_UIDGID))
- xflags &= ~CLFE_UIDGID;
- if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_EXTRA_FLAGS))
- flags &= ~CLF_EXTRA_FLAGS;
- if (!(loghandle->lgh_hdr->llh_flags & LLOG_F_EXT_JOBID))
- flags &= ~CLF_JOBID;
- if (flags != CLF_SUPPORTED || xflags != CLFE_SUPPORTED)
- changelog_block_trim_ext(rec, last_rec, flags, xflags);
+ changelog_block_trim_ext(rec, last_rec, loghandle);
GOTO(out, rc = 0);
}
#include <lustre/lustreapi.h>
#include <linux/lustre/lustre_ver.h>
#include <linux/lustre/lustre_param.h>
+#include <linux/lnet/nidstr.h>
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof((a)[0])))
}
rc = llapi_changelog_set_xflags(changelog_priv,
- CHANGELOG_EXTRA_FLAG_UIDGID);
+ CHANGELOG_EXTRA_FLAG_UIDGID |
+ CHANGELOG_EXTRA_FLAG_NID);
if (rc < 0) {
fprintf(stderr, "Can't set xflags for changelog: %s\n",
strerror(errno = -rc));
printf(" u=%llu:%llu",
uidgid->cr_uid, uidgid->cr_gid);
}
+ if (ef->cr_extra_flags & CLFE_NID) {
+ struct changelog_ext_nid *nid =
+ changelog_rec_nid(rec);
+
+ printf(" nid=%s",
+ libcfs_nid2str(nid->cr_nid));
+ }
}
if (rec->cr_namelen)
rec_fmt |= CLF_EXTRA_FLAGS;
if (cp->clp_send_extra_flags & CHANGELOG_EXTRA_FLAG_UIDGID)
rec_extra_fmt |= CLFE_UIDGID;
+ if (cp->clp_send_extra_flags & CHANGELOG_EXTRA_FLAG_NID)
+ rec_extra_fmt |= CLFE_NID;
}
if (cp->clp_buf + cp->clp_buf_len <= cp->clp_buf_pos) {
}
rc = llapi_changelog_set_xflags(changelog_priv,
- CHANGELOG_EXTRA_FLAG_UIDGID);
+ CHANGELOG_EXTRA_FLAG_UIDGID |
+ CHANGELOG_EXTRA_FLAG_NID);
if (rc < 0) {
fprintf(stderr, "Error setting xflag in changelog for fs %s.\n",
status->ls_source_fs);