Whamcloud - gitweb
LU-7003 utils: must quote the value of the context option
[fs/lustre-release.git] / lustre / utils / mount_utils_ldiskfs.c
index 4f662fa..54b62fe 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2012, 2014, Intel Corporation.
+ * Copyright (c) 2012, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -93,8 +93,11 @@ extern char *progname;
 #define DUMMY_FILE_NAME_LEN             25
 #define EXT3_DIRENT_SIZE                DUMMY_FILE_NAME_LEN
 
+static void append_unique(char *buf, char *prefix, char *key, char *val,
+                         size_t maxbuflen);
+
 /*
- * Concatenate context of the temporary mount point iff selinux is enabled
+ * Concatenate context of the temporary mount point if selinux is enabled
  */
 #ifdef HAVE_SELINUX
 static void append_context_for_mount(char *mntpt, struct mkfs_opts *mop)
@@ -109,8 +112,9 @@ static void append_context_for_mount(char *mntpt, struct mkfs_opts *mop)
        }
 
        if (fcontext != NULL) {
-               strcat(mop->mo_ldd.ldd_mount_opts, ",context=");
-               strcat(mop->mo_ldd.ldd_mount_opts, fcontext);
+               append_unique(mop->mo_ldd.ldd_mount_opts,
+                             ",", "context", fcontext,
+                             sizeof(mop->mo_ldd.ldd_mount_opts));
                freecon(fcontext);
        }
 }
@@ -262,7 +266,8 @@ int ldiskfs_write_ldd(struct mkfs_opts *mop)
                dev = mop->mo_loopdev;
 
        ret = mount(dev, mntpt, MT_STR(&mop->mo_ldd), 0,
-                   mop->mo_ldd.ldd_mount_opts);
+               (mop->mo_mountopts == NULL) ?
+               "errors=remount-ro" : mop->mo_mountopts);
        if (ret) {
                fprintf(stderr, "%s: Unable to mount %s: %s\n",
                        progname, dev, strerror(errno));
@@ -548,8 +553,9 @@ static void append_unique(char *buf, char *prefix, char *key, char *val,
 
                strscat(buf, key, maxbuflen);
                if (val != NULL) {
-                       strscat(buf, "=", maxbuflen);
+                       strscat(buf, "=\"", maxbuflen);
                        strscat(buf, val, maxbuflen);
+                       strscat(buf, "\"", maxbuflen);
                }
        }
 }
@@ -615,7 +621,8 @@ static int enable_default_ext4_features(struct mkfs_opts *mop, char *anchor,
 
                append_unique(anchor, ",", "flex_bg", NULL, maxbuflen);
 
-               if (IS_OST(&mop->mo_ldd)) {
+               if (IS_OST(&mop->mo_ldd) &&
+                   strstr(mop->mo_mkfsopts, "-G") == NULL) {
                        snprintf(tmp_buf, sizeof(tmp_buf), " -G %u",
                                 (1 << 20) / L_BLOCK_SIZE);
                        strscat(anchor, tmp_buf, maxbuflen);
@@ -694,9 +701,9 @@ int ldiskfs_make_lustre(struct mkfs_opts *mop)
        }
 
        if (mop->mo_device_kb != 0) {
-               if (mop->mo_device_kb < 8096) {
+               if (mop->mo_device_kb < 32384) {
                        fprintf(stderr, "%s: size of filesystem must be larger "
-                               "than 8MB, but is set to %lldKB\n",
+                               "than 32MB, but is set to %lldKB\n",
                                progname, (long long)mop->mo_device_kb);
                        return EINVAL;
                }
@@ -740,17 +747,32 @@ int ldiskfs_make_lustre(struct mkfs_opts *mop)
                        }
                }
 
-               /* Inode size (for extended attributes).  The LOV EA size is
-                * 32 (EA hdr) + 32 (lov_mds_md) + stripes * 24 (lov_ost_data),
-                * and we want some margin above that for ACLs, other EAs... */
+               /* Inode size includes:
+                *   ldiskfs inode size: 156
+                *   extended attributes size, including:
+                *      ext4_xattr_header: 32
+                *      LOV EA size: 32(lov_mds_md) +
+                *                   stripes * 24(lov_ost_data) +
+                *                   16(xattr_entry) + 3(lov)
+                *      LMA EA size: 24(lustre_mdt_attrs) +
+                *                   16(xattr_entry) + 3(lma)
+                *      link EA size: 24(link_ea_header) + 18(link_ea_entry) +
+                *                    (filename) + 16(xattr_entry) + 4(link)
+                *   and some margin for 4-byte alignment, ACLs and other EAs.
+                *
+                * If we say the average filename length is about 32 bytes,
+                * the calculation looks like:
+                * 156 + 32 + (32+24*N+19) + (24+19) + (24+18+~32+20) + other <=
+                * 512*2^m, {m=0,1,2,3}
+                */
                if (strstr(mop->mo_mkfsopts, "-I") == NULL) {
                        if (IS_MDT(&mop->mo_ldd)) {
-                               if (mop->mo_stripe_count > 72)
+                               if (mop->mo_stripe_count > 69)
                                        inode_size = 512; /* bz 7241 */
                                /* see also "-i" below for EA blocks */
-                               else if (mop->mo_stripe_count > 32)
+                               else if (mop->mo_stripe_count > 26)
                                        inode_size = 2048;
-                               else if (mop->mo_stripe_count > 10)
+                               else if (mop->mo_stripe_count > 5)
                                        inode_size = 1024;
                                else
                                        inode_size = 512;
@@ -780,7 +802,7 @@ int ldiskfs_make_lustre(struct mkfs_opts *mop)
                        if (IS_MDT(&mop->mo_ldd)) {
                                bytes_per_inode = inode_size + 1536;
 
-                               if (mop->mo_stripe_count > 72) {
+                               if (mop->mo_stripe_count > 69) {
                                        int extra = mop->mo_stripe_count * 24;
                                        extra = ((extra - 1) | 4095) + 1;
                                        bytes_per_inode += extra;
@@ -904,8 +926,8 @@ int ldiskfs_make_lustre(struct mkfs_opts *mop)
 
        vprint("formatting backing filesystem %s on %s\n",
               MT_STR(&mop->mo_ldd), dev);
-       vprint("\ttarget name  %s\n", mop->mo_ldd.ldd_svname);
-       vprint("\t4k blocks     "LPU64"\n", block_count);
+       vprint("\ttarget name   %s\n", mop->mo_ldd.ldd_svname);
+       vprint("\t4k blocks     %ju\n", (uintmax_t)block_count);
        vprint("\toptions       %s\n", mop->mo_mkfsopts);
 
        /* mkfs_cmd's trailing space is important! */
@@ -913,7 +935,8 @@ int ldiskfs_make_lustre(struct mkfs_opts *mop)
        strscat(mkfs_cmd, " ", sizeof(mkfs_cmd));
        strscat(mkfs_cmd, dev, sizeof(mkfs_cmd));
        if (block_count != 0) {
-               sprintf(buf, " "LPU64, block_count);
+               snprintf(buf, sizeof(buf), " %ju",
+                        (uintmax_t)block_count);
                strscat(mkfs_cmd, buf, sizeof(mkfs_cmd));
        }
 
@@ -927,8 +950,7 @@ int ldiskfs_make_lustre(struct mkfs_opts *mop)
 }
 
 int ldiskfs_prepare_lustre(struct mkfs_opts *mop,
-                          char *default_mountopts, int default_len,
-                          char *always_mountopts, int always_len)
+                          char *wanted_mountopts, size_t len)
 {
        struct lustre_disk_data *ldd = &mop->mo_ldd;
        int ret;
@@ -941,9 +963,16 @@ int ldiskfs_prepare_lustre(struct mkfs_opts *mop,
                mop->mo_flags |= MO_IS_LOOP;
        }
 
-       strscat(default_mountopts, ",errors=remount-ro", default_len);
        if (IS_MDT(ldd) || IS_MGS(ldd))
-               strscat(always_mountopts, ",user_xattr", always_len);
+               strscat(wanted_mountopts, ",user_xattr", len);
+
+       return 0;
+}
+
+int ldiskfs_fix_mountopts(struct mkfs_opts *mop, char *mountopts, size_t len)
+{
+       if (strstr(mountopts, "errors=") == NULL)
+               strscat(mountopts, ",errors=remount-ro", len);
 
        return 0;
 }
@@ -973,15 +1002,16 @@ static int read_file(const char *path, char *buf, int size)
 
 static int write_file(const char *path, const char *buf)
 {
-       FILE *fd;
+       int fd, rc;
 
-       fd = fopen(path, "w");
-       if (fd == NULL)
+       fd = open(path, O_WRONLY);
+       if (fd < 0)
                return errno;
 
-       fputs(buf, fd);
-       fclose(fd);
-       return 0;
+       rc = write(fd, buf, strlen(buf));
+       close(fd);
+
+       return rc < 0 ? errno : 0;
 }
 
 static int set_blockdev_scheduler(const char *path, const char *scheduler)
@@ -1155,7 +1185,7 @@ set_params:
                        snprintf(buf, sizeof(buf), "%d",
                                 mop->mo_md_stripe_cache_size);
                        rc = write_file(real_path, buf);
-                       if (rc && verbose)
+                       if (rc != 0 && verbose)
                                fprintf(stderr, "warning: opening %s: %s\n",
                                        real_path, strerror(errno));
                }
@@ -1193,10 +1223,14 @@ set_params:
                if (newval == 0 || newval == ULLONG_MAX || end == buf)
                        goto subdevs;
 
-               /* Don't increase IO request size limit past 32MB.  It is about
-                * 2x PTLRPC_MAX_BRW_SIZE, but that isn't defined publicly. */
-               if (newval > 32 * 1024)
-                       newval = 32 * 1024;
+               /* Don't increase IO request size limit past 16MB.  It is about
+                * PTLRPC_MAX_BRW_SIZE, but that isn't in a public header.
+                * Note that even though the block layer allows larger values,
+                * setting max_sectors_kb = 32768 causes crashes (LU-6974). */
+               if (newval > 16 * 1024) {
+                       newval = 16 * 1024;
+                       snprintf(buf, sizeof(buf), "%llu", newval);
+               }
 
                oldval = strtoull(oldbuf, &end, 0);
                /* Don't shrink the current limit. */
@@ -1204,7 +1238,7 @@ set_params:
                        goto subdevs;
 
                rc = write_file(real_path, buf);
-               if (rc) {
+               if (rc != 0) {
                        if (verbose)
                                fprintf(stderr, "warning: writing to %s: %s\n",
                                        real_path, strerror(errno));