#define MDS_ATTR_BLOCKS 0x8000ULL /* = 32768 */
#define MDS_ATTR_PROJID 0x10000ULL /* = 65536 */
-#ifndef FMODE_READ
-#define FMODE_READ 00000001
-#define FMODE_WRITE 00000002
-#endif
-
-#define MDS_FMODE_CLOSED 00000000
-#define MDS_FMODE_EXEC 00000004
-/* MDS_FMODE_EPOCH 01000000 obsolete since 2.8.0 */
-/* MDS_FMODE_TRUNC 02000000 obsolete since 2.8.0 */
-/* MDS_FMODE_SOM 04000000 obsolete since 2.8.0 */
-
-#define MDS_OPEN_CREATED 00000010
-#define MDS_OPEN_CROSS 00000020
-
-#define MDS_OPEN_CREAT 00000100
-#define MDS_OPEN_EXCL 00000200
-#define MDS_OPEN_TRUNC 00001000
-#define MDS_OPEN_APPEND 00002000
-#define MDS_OPEN_SYNC 00010000
-#define MDS_OPEN_DIRECTORY 00200000
-
-#define MDS_OPEN_BY_FID 040000000 /* open_by_fid for known object */
-#define MDS_OPEN_DELAY_CREATE 0100000000 /* delay initial object create */
-#define MDS_OPEN_OWNEROVERRIDE 0200000000 /* NFSD rw-reopen ro file for owner */
-#define MDS_OPEN_JOIN_FILE 0400000000 /* open for join file.
- * We do not support JOIN FILE
- * anymore, reserve this flags
- * just for preventing such bit
- * to be reused. */
-
-#define MDS_OPEN_LOCK 04000000000 /* This open requires open lock */
-#define MDS_OPEN_HAS_EA 010000000000 /* specify object create pattern */
-#define MDS_OPEN_HAS_OBJS 020000000000 /* Just set the EA the obj exist */
-#define MDS_OPEN_NORESTORE 0100000000000ULL /* Do not restore file at open */
-#define MDS_OPEN_NEWSTRIPE 0200000000000ULL /* New stripe needed (restripe or
- * hsm restore) */
-#define MDS_OPEN_VOLATILE 0400000000000ULL /* File is volatile = created
- unlinked */
-#define MDS_OPEN_LEASE 01000000000000ULL /* Open the file and grant lease
- * delegation, succeed if it's not
- * being opened with conflict mode.
- */
-#define MDS_OPEN_RELEASE 02000000000000ULL /* Open the file for HSM release */
-
-#define MDS_OPEN_RESYNC 04000000000000ULL /* FLR: file resync */
-
-/* lustre internal open flags, which should not be set from user space */
-#define MDS_OPEN_FL_INTERNAL (MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS | \
- MDS_OPEN_OWNEROVERRIDE | MDS_OPEN_LOCK | \
- MDS_OPEN_BY_FID | MDS_OPEN_LEASE | \
- MDS_OPEN_RELEASE | MDS_OPEN_RESYNC)
-
enum mds_op_bias {
MDS_CHECK_SPLIT = 1 << 0,
MDS_CROSS_REF = 1 << 1,
#define CHANGELOG_ALLMASK 0XFFFFFFFF
/** default \a changelog_rec_type mask. Allow all of them, except
* CL_ATIME since it can really be time consuming, and not necessary
- * under normal use. */
-#define CHANGELOG_DEFMASK (CHANGELOG_ALLMASK & ~(1 << CL_ATIME))
+ * under normal use.
+ * Remove also CL_OPEN from default list as it can be costly and only necessary
+ * for audit purpose.
+ */
+#define CHANGELOG_DEFMASK (CHANGELOG_ALLMASK & ~(1 << CL_ATIME | 1 << CL_OPEN))
/* changelog llog name, needed by client replicators */
#define CHANGELOG_CATALOG "changelog_catalog"
LLOG_F_EXT_EXTRA_FLAGS = 0x20,
LLOG_F_EXT_X_UIDGID = 0x40,
LLOG_F_EXT_X_NID = 0x80,
+ LLOG_F_EXT_X_OMODE = 0x100,
/* 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_NID,
+ LLOG_F_EXT_X_UIDGID | LLOG_F_EXT_X_NID |
+ LLOG_F_EXT_X_OMODE,
};
/* On-disk header structure of each log object, stored in little endian order */
LA_REMOTE_ATTR_SET = (LA_UID | LA_GID | LA_PROJID | LA_LAYOUT_VERSION)
};
+#ifndef FMODE_READ
+#define FMODE_READ 00000001
+#define FMODE_WRITE 00000002
+#endif
+
+#define MDS_FMODE_CLOSED 00000000
+#define MDS_FMODE_EXEC 00000004
+/* MDS_FMODE_EPOCH 01000000 obsolete since 2.8.0 */
+/* MDS_FMODE_TRUNC 02000000 obsolete since 2.8.0 */
+/* MDS_FMODE_SOM 04000000 obsolete since 2.8.0 */
+
+#define MDS_OPEN_CREATED 00000010
+#define MDS_OPEN_CROSS 00000020
+
+#define MDS_OPEN_CREAT 00000100
+#define MDS_OPEN_EXCL 00000200
+#define MDS_OPEN_TRUNC 00001000
+#define MDS_OPEN_APPEND 00002000
+#define MDS_OPEN_SYNC 00010000
+#define MDS_OPEN_DIRECTORY 00200000
+
+#define MDS_OPEN_BY_FID 040000000 /* open_by_fid for known object */
+#define MDS_OPEN_DELAY_CREATE 0100000000 /* delay initial object create */
+#define MDS_OPEN_OWNEROVERRIDE 0200000000 /* NFSD rw-reopen ro file for owner */
+#define MDS_OPEN_JOIN_FILE 0400000000 /* open for join file.
+ * We do not support JOIN FILE
+ * anymore, reserve this flags
+ * just for preventing such bit
+ * to be reused. */
+
+#define MDS_OPEN_LOCK 04000000000 /* This open requires open lock */
+#define MDS_OPEN_HAS_EA 010000000000 /* specify object create pattern */
+#define MDS_OPEN_HAS_OBJS 020000000000 /* Just set the EA the obj exist */
+#define MDS_OPEN_NORESTORE 0100000000000ULL /* Do not restore file at open */
+#define MDS_OPEN_NEWSTRIPE 0200000000000ULL /* New stripe needed (restripe or
+ * hsm restore) */
+#define MDS_OPEN_VOLATILE 0400000000000ULL /* File is volatile = created
+ unlinked */
+#define MDS_OPEN_LEASE 01000000000000ULL /* Open the file and grant lease
+ * delegation, succeed if it's not
+ * being opened with conflict mode.
+ */
+#define MDS_OPEN_RELEASE 02000000000000ULL /* Open the file for HSM release */
+
+#define MDS_OPEN_RESYNC 04000000000000ULL /* FLR: file resync */
+
+/* lustre internal open flags, which should not be set from user space */
+#define MDS_OPEN_FL_INTERNAL (MDS_OPEN_HAS_EA | MDS_OPEN_HAS_OBJS | \
+ MDS_OPEN_OWNEROVERRIDE | MDS_OPEN_LOCK | \
+ MDS_OPEN_BY_FID | MDS_OPEN_LEASE | \
+ MDS_OPEN_RELEASE | MDS_OPEN_RESYNC)
+
+
/********* Changelogs **********/
/** Changelog record types */
enum changelog_rec_type {
CLFE_INVALID = 0,
CLFE_UIDGID = 0x0001,
CLFE_NID = 0x0002,
- CLFE_SUPPORTED = CLFE_UIDGID | CLFE_NID
+ CLFE_OPEN = 0x0004,
+ CLFE_SUPPORTED = CLFE_UIDGID | CLFE_NID | CLFE_OPEN
};
enum changelog_send_flag {
CHANGELOG_EXTRA_FLAG_UIDGID = 0x01,
/* Pack nid into the changelog record */
CHANGELOG_EXTRA_FLAG_NID = 0x02,
+ /* Pack open mode into the changelog record */
+ CHANGELOG_EXTRA_FLAG_OMODE = 0x04,
};
#define CR_MAXSIZE cfs_size_round(2 * NAME_MAX + 2 + \
__u32 padding;
};
+/* Changelog extra extension to include OPEN mode. */
+struct changelog_ext_openmode {
+ __u32 cr_openflags;
+};
+
static inline struct changelog_ext_extra_flags *changelog_rec_extra_flags(
const struct changelog_rec *rec);
size += sizeof(struct changelog_ext_uidgid);
if (cref & CLFE_NID)
size += sizeof(struct changelog_ext_nid);
+ if (cref & CLFE_OPEN)
+ size += sizeof(struct changelog_ext_openmode);
}
return size;
changelog_rec_offset(crf, cref));
}
+/* The OPEN mode is the third extra extension */
+static inline
+struct changelog_ext_openmode *changelog_rec_openmode(
+ 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 | CLFE_NID);
+
+ return (struct changelog_ext_openmode *)((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 *omd_mov = NULL;
char *nid_mov = NULL;
char *uidgid_mov = NULL;
char *ef_mov;
/* Locations of extensions in the remapped record */
if (rec->cr_flags & CLF_EXTRA_FLAGS) {
+ omd_mov = (char *)rec +
+ changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
+ cref_want & ~CLFE_OPEN);
nid_mov = (char *)rec +
changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
- cref_want & ~CLFE_NID);
+ cref_want & ~(CLFE_NID |
+ CLFE_OPEN));
uidgid_mov = (char *)rec +
changelog_rec_offset(crf_wanted & CLF_SUPPORTED,
cref_want & ~(CLFE_UIDGID |
- CLFE_NID));
+ CLFE_NID |
+ CLFE_OPEN));
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_OPEN) && (cref & CLFE_OPEN))
+ memmove(omd_mov, changelog_rec_openmode(rec),
+ sizeof(struct changelog_ext_openmode));
+
if ((cref_want & CLFE_NID) && (cref & CLFE_NID))
memmove(nid_mov, changelog_rec_nid(rec),
sizeof(struct changelog_ext_nid));
sizeof(struct changelog_ext_rename));
/* Clear newly added fields */
+ if (omd_mov && (cref_want & CLFE_OPEN) &&
+ !(cref & CLFE_OPEN))
+ memset(omd_mov, 0, sizeof(struct changelog_ext_openmode));
+
if (nid_mov && (cref_want & CLFE_NID) &&
!(cref & CLFE_NID))
memset(nid_mov, 0, sizeof(struct changelog_ext_nid));
LLOG_F_EXT_JOBID |
LLOG_F_EXT_EXTRA_FLAGS |
LLOG_F_EXT_X_UIDGID |
- LLOG_F_EXT_X_NID,
+ LLOG_F_EXT_X_NID |
+ LLOG_F_EXT_X_OMODE,
NULL);
if (rc) {
CERROR("%s: fail to init llog handle: rc = %d\n",
clnid->cr_nid = nid;
}
+void mdd_changelog_rec_extra_omode(struct changelog_rec *rec, int flags)
+{
+ struct changelog_ext_openmode *omd = changelog_rec_openmode(rec);
+
+ omd->cr_openflags = (__u32)flags;
+}
+
/** 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.
__u64 uid, __u64 gid);
void mdd_changelog_rec_extra_nid(struct changelog_rec *rec,
lnet_nid_t nid);
+void mdd_changelog_rec_extra_omode(struct changelog_rec *rec, int flags);
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,
xflags |= CLFE_UIDGID;
xflags |= CLFE_NID;
}
+ if (type == CL_OPEN)
+ xflags |= CLFE_OPEN;
reclen = llog_data_len(LLOG_CHANGELOG_HDR_SZ +
changelog_rec_offset(flags & CLF_SUPPORTED,
uc->uc_uid, uc->uc_gid);
if (xflags & CLFE_NID)
mdd_changelog_rec_extra_nid(&rec->cr, uc->uc_nid);
+ if (xflags & CLFE_OPEN)
+ mdd_changelog_rec_extra_omode(&rec->cr, flags);
}
rc = mdd_changelog_store(env, mdd, rec, handle);
-
RETURN(rc);
}
int flags)
{
struct mdd_object *mdd_obj = md2mdd_obj(obj);
+ struct md_device *md_dev = lu2md_dev(mdd2lu_dev(mdo2mdd(obj)));
struct lu_attr *attr = MDD_ENV_VAR(env, cattr);
int rc = 0;
GOTO(out, rc);
mdd_obj->mod_count++;
+
+ mdd_changelog(env, CL_OPEN, flags, md_dev, mdo2fid(mdd_obj));
+
EXIT;
out:
mdd_write_unlock(env, mdd_obj);
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_OMODE))
+ extra_flags &= ~CLFE_OPEN;
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))
rc = llapi_changelog_set_xflags(changelog_priv,
CHANGELOG_EXTRA_FLAG_UIDGID |
- CHANGELOG_EXTRA_FLAG_NID);
+ CHANGELOG_EXTRA_FLAG_NID |
+ CHANGELOG_EXTRA_FLAG_OMODE);
if (rc < 0) {
fprintf(stderr, "Can't set xflags for changelog: %s\n",
strerror(errno = -rc));
printf(" nid=%s",
libcfs_nid2str(nid->cr_nid));
}
+
+ if (ef->cr_extra_flags & CLFE_OPEN) {
+ struct changelog_ext_openmode *omd =
+ changelog_rec_openmode(rec);
+ char mode[] = "---";
+
+ /* exec mode must be exclusive */
+ if (omd->cr_openflags & MDS_FMODE_EXEC) {
+ mode[2] = 'x';
+ } else {
+ if (omd->cr_openflags & FMODE_READ)
+ mode[0] = 'r';
+ if (omd->cr_openflags &
+ (FMODE_WRITE |
+ MDS_OPEN_TRUNC |
+ MDS_OPEN_APPEND))
+ mode[1] = 'w';
+ }
+
+ if (strcmp(mode, "---") != 0)
+ printf(" m=%s", mode);
+
+ }
}
if (rec->cr_namelen)
rec_extra_fmt |= CLFE_UIDGID;
if (cp->clp_send_extra_flags & CHANGELOG_EXTRA_FLAG_NID)
rec_extra_fmt |= CLFE_NID;
+ if (cp->clp_send_extra_flags & CHANGELOG_EXTRA_FLAG_OMODE)
+ rec_extra_fmt |= CLFE_OPEN;
}
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_NID);
+ CHANGELOG_EXTRA_FLAG_NID |
+ CHANGELOG_EXTRA_FLAG_OMODE);
if (rc < 0) {
fprintf(stderr, "Error setting xflag in changelog for fs %s.\n",
status->ls_source_fs);