+#include <lustre/libiam.h>
+
+#define LDISKFS_IOC_GETVERSION _IOR('f', 3, long)
+
+#ifndef TUNEFS /* mkfs.lustre */
+static int mkfs_iam_insert(int key_need_convert, char *keybuf,
+ int rec_need_convert, char *recbuf, char *filename)
+{
+ int fd;
+ int ret;
+ struct iam_uapi_info ua;
+
+ fd = iam_open(filename, &ua);
+ if (fd < 0) {
+ fprintf(stderr, "failed to iam_open %s\n", filename);
+ return 1;
+ }
+
+ ret = iam_insert(fd, &ua,
+ key_need_convert, keybuf,
+ rec_need_convert, recbuf);
+ iam_close(fd);
+ if (ret) {
+ fprintf(stderr, "failed to iam_insert %s\n", filename);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int touch_file(char *filename)
+{
+ int fd;
+
+ if (filename == NULL) {
+ return 1;
+ }
+
+ fd = open(filename, O_CREAT | O_TRUNC, 0600);
+ if (fd < 0) {
+ return 1;
+ } else {
+ close(fd);
+ return 0;
+ }
+}
+
+static int get_generation(char *filename, unsigned long *result)
+{
+ int fd;
+ int ret;
+
+ if (filename == NULL) {
+ return 1;
+ }
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "%s: failed to open %s\n",
+ __FUNCTION__, filename);
+ return 1;
+ }
+
+ ret = ioctl(fd, LDISKFS_IOC_GETVERSION, result);
+ close(fd);
+
+ return ((ret < 0) ? ret : 0);
+}
+
+static int mkfs_mdt(struct mkfs_opts *mop)
+{
+ char mntpt[] = "/tmp/mntXXXXXX";
+ char fstype[] = "ldiskfs";
+ char filepnm[128];
+ char recbuf[64];
+ char *source;
+ int ret;
+ unsigned long generation;
+ struct stat st;
+
+ source = mop->mo_device;
+ if (mop->mo_flags & MO_IS_LOOP) {
+ source = mop->mo_loopdev;
+ }
+
+ if ((source == NULL) || (*source == 0)) {
+ return 1;
+ }
+
+ if (!mkdtemp(mntpt)) {
+ fprintf(stderr, "%s: failed to mkdtemp %s\n",
+ __FUNCTION__, mntpt);
+ return errno;
+ }
+
+ ret = mount(source, mntpt, fstype, 0, NULL);
+ if (ret) {
+ goto out_rmdir;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, "seq_ctl");
+ ret = touch_file(filepnm);
+ if (ret) {
+ goto out_umount;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, "seq_srv");
+ ret = touch_file(filepnm);
+ if (ret) {
+ goto out_umount;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, "last_received");
+ ret = touch_file(filepnm);
+ if (ret) {
+ goto out_umount;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, "lov_objid");
+ ret = touch_file(filepnm);
+ if (ret) {
+ goto out_umount;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, "root");
+ ret = iam_creat(filepnm, FMT_LVAR, L_BLOCK_SIZE, 4, 17, 4);
+ if (ret) {
+ goto out_umount;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, "fld");
+ ret = iam_creat(filepnm, FMT_LFIX, L_BLOCK_SIZE, 8, 8, 4);
+ if (ret) {
+ goto out_umount;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, "orphans");
+ ret = iam_creat(filepnm, FMT_LFIX, L_BLOCK_SIZE, 20, 8, 4);
+ if (ret) {
+ goto out_umount;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, "oi.16");
+ ret = iam_creat(filepnm, FMT_LFIX, L_BLOCK_SIZE, 16, 8, 4);
+ if (ret) {
+ goto out_umount;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, "oi.5");
+ ret = iam_creat(filepnm, FMT_LFIX, L_BLOCK_SIZE, 5, 8, 4);
+ if (ret) {
+ goto out_umount;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, CAPA_KEYS);
+ ret = touch_file(filepnm);
+ if (ret) {
+ goto out_umount;
+ }
+
+ umount(mntpt);
+ ret = mount(source, mntpt, fstype, 0, NULL);
+ if (ret) {
+ goto out_rmdir;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, "root");
+ ret = iam_polymorph(filepnm, 040755);
+ if (ret) {
+ perror("IAM_IOC_POLYMORPH");
+ goto out_umount;
+ }
+
+ umount(mntpt);
+ ret = mount(source, mntpt, fstype, 0, NULL);
+ if (ret) {
+ goto out_rmdir;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, "fld");
+ ret = mkfs_iam_insert(1, "0000000000000002", 1, "0000000000000000", filepnm);
+ if (ret) {
+ goto out_umount;
+ }
+
+ ret = mkfs_iam_insert(1, "0000000000000001", 1, "0000000000000000", filepnm);
+ if (ret) {
+ goto out_umount;
+ }
+
+ snprintf(filepnm, sizeof(filepnm) - 1, "%s/%s", mntpt, "root");
+ ret = stat(filepnm, &st);
+ if (ret) {
+ goto out_umount;
+ }
+
+ ret = get_generation(filepnm, &generation);
+ if (ret) {
+ goto out_umount;
+ }
+
+ snprintf(recbuf, sizeof(recbuf) - 1, "110000000000000001%8.8x%8.8x",
+ (unsigned int)st.st_ino, (unsigned int)generation);
+ ret = mkfs_iam_insert(0, ".", 1, recbuf, filepnm);
+ if (ret) {
+ goto out_umount;
+ }
+
+ ret = mkfs_iam_insert(0, "..", 1, recbuf, filepnm);
+ if (ret) {
+ goto out_umount;
+ }
+
+out_umount:
+ umount(mntpt);
+out_rmdir:
+ rmdir(mntpt);
+ return ret;
+}
+#endif
+