#!/bin/ksh93
#  ALTRAN_PROLOG_BEGIN_TAG                                                    
#  This is an automatically generated prolog.                                  
#                                                                              
#  Copyright (C) Altran ACT S.A.S. 2017,2019,2020,2021.  All rights reserved.  
#                                                                              
#  ALTRAN_PROLOG_END_TAG                                                      
#                                                                              
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r721 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_file_system.sh 1.19 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2012,2016 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)  ddac8c3 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_file_system.sh, 726, 2147A_aha726, Apr 23 2021 12:25 AM

# Start of POD-formatted documentation. Viewing suggestions:
#      perldoc <FILENAME>
#      pod2text -c <FILENAME>
#      pod2text -c --code <FILENAME>
#      pod2html <FILENAME>
function devDoc {
    : <<'=cut' >/dev/null 2>&1

=head1 NAME

 KLIB_HACMP_add_file_system

=head1 SYNOPSIS

 clmgr add file_system <fsname> \
             VOLUME_GROUP=<volume_group> \
             TYPE=enhanced \
             UNITS=### \
                 [ SIZE_PER_UNIT={megabytes|gigabytes|512bytes} ] \
             [ PERMISSIONS={rw|ro} ] \
             [ OPTIONS={nodev|nosuid|all} ] \
             [ BLOCK_SIZE={4096|512|1024|2048} ] \
             [ LV_FOR_LOG={ <lvname> | "INLINE" } ] \
                 [ INLINE_LOG_SIZE=#### ] \
             [ EXT_ATTR_FORMAT={v1|v2} ] \
             [ ENABLE_QUOTA_MGMT={no|all|user|group} ] \
             [ EFS={yes|true} ]

 NOTE: a new logical volume will be created for the file system.
 NOTE: "BLOCK_SIZE" is in bytes; "INLINE_LOG_SIZE" is in megabytes
 NOTE: "INLINE_LOG_SIZE" may only be used if "LV_FOR_LOG" is set
       to "INLINE".
 NOTE: the mininmum size for an enhanced file system is 16MB.

 clmgr add file_system <fsname> \
             TYPE=enhanced \
             LOGICAL_VOLUME=<logical_volume> \
             [ PERMISSIONS={rw|ro} ] \
             [ OPTIONS={nodev,nosuid} ] \
             [ BLOCK_SIZE={4096|512|1024|2048} ] \
             [ LV_FOR_LOG={ <lvname> | "INLINE" } ] \
                 [ INLINE_LOG_SIZE=#### ] \
             [ EXT_ATTR_FORMAT={v1|v2} ] \
             [ ENABLE_QUOTA_MGMT={no|all|user|group} ] \
             [ EFS={yes|true} ]

 clmgr add file_system <fsname> \
             VOLUME_GROUP=<volume_group> \
             TYPE={standard|compressed|large} \
             UNITS=### \
                 [ SIZE_PER_UNIT={megabytes|gigabytes|512bytes} ] \
             [ PERMISSIONS={rw|ro} ] \
             [ OPTIONS={nodev,nosuid} ] \
             [ DISK_ACCOUNTING={false|true} ] \
             [ FRAGMENT_SIZE={4096|512|1024|2048} ] \
             [ BYTES_PER_INODE={4096|512|1024|2048|8192|
                                16384|32768|65536|131072} ] \
             [ ALLOC_GROUP_SIZE={8|16|32|64} ] \
             [ LV_FOR_LOG=<lvname> ]

 NOTE: FRAGMENT_SIZE is only valid for standard and compressed
       file systems.

 clmgr add file_system <fsname> \
             TYPE={standard|compressed|large} \
             LOGICAL_VOLUME=<logical_volume> \
             [ PERMISSIONS={rw|ro} ] \
             [ OPTIONS={nodev|nosuid} ] \
             [ DISK_ACCOUNTING={false|true} ] \
             [ FRAGMENT_SIZE={4096|512|1024|2048} ] \
             [ BYTES_PER_INODE={4096|512|1024|2048|8192|
                                16384|32768|65536|131072} ] \
             [ ALLOC_GROUP_SIZE={8|16|32|64} ] \
             [ LV_FOR_LOG=<lvname> ]

 NOTE: an alias for "file_system" is "fs".

=head1 DESCRIPTION

Attempts to add a new file system.

=head1 ARGUMENTS

 1. properties [REQUIRED] [hash ref]
    An associative array within which data about the
    created object can be returned to the caller.

 2. file_system [REQUIRED] [string]
    The mount point for this file system.

 3. volume_group [REQUIRED] [string]
    The volume group that this file system will be
    created within.

 4. type [REQUIRED] [set]
    The type of file system that is to be created.

    Valid values: standard, compressed, large, enhanced

 5. units [REQUIRED] [posint]
    The number of units of the specified unit size
    (which defaults to megabytes). Combined, these
    determine the size of the file system.

 6. size_per_unit [OPTIONAL] [set]
    The size of each of the specified units defaulting
    to megabytes. Combined, these determine the size of
    the file system.

    Valid values: 512 byte blocks, megabytes, gigabytes                          
 7. permissions [OPTIONAL] [set]
    Sets the permissions for the file system, defaulting
    to "rw" (read/write).

    Valid values: rw (read/write), ro (read only)

 8. options [OPTIONAL] [set]
    The security-related mount options. More than one
    option may be specified concurrently.

    Valid values: nosuid, nodev

        nosuid - Prevents execution of setuid and setgid
                 programs from this mount.

        nodev  - Prevents open system calls of devices
                 from this mount. 

 9. block_size [OPTIONAL] [posint]
    The file system block size, in bytes, defaulting to
    4096. A smaller block size uses less disk space for
    small files, but may degrade performance.

    Valid values: 512, 1024, 2048, or 4096

    NOTE: this option is only valid with enhanced
          file systems.

 10. lv_for_log [OPTIONAL] [string]
    The logical volume to be used for the logging
    device for the new file system. If set to the
    special value of "INLINE" (only valid with
    enhanced file systems), that indicates that
    the journal log for the file system resides
    within the file system itself.

 11. inline_log_size [OPTIONAL] [posint]
    The size, in megabytes, for the optional inline
    journal log. The default is the size of the file
    system divided by 256.

    NOTE: this option is only valid with enhanced
          file systems.

 12. ext_attr_format [OPTIONAL] [set]
    The extended attribute format, used for storing
    named extended attributes in the JFS2 filesystem.
    Version 2 provides support for scalable named
    extended attributes and support for NFS4 ACLs.
    Version 1 is compatible with AIX version 5.2 or
    earlier. The default is Version 1.

    Valid values: v1, v2

    NOTE: this option is only valid with enhanced
          file systems.

 13. enable_quota_mgmt [OPTIONAL] [set]
    Specifies that file and block usage statistics be
    maintained and limits enforced by the file system
    for a particular quota type or for all types. The
    default value is "no".

    Valid values: no, all, user, group

    NOTE: this option is only valid with enhanced
          file systems.

 14. enable_efs [OPTIONAL] [boolean]
    Enter "yes" to enable encryption for this file
    system (EFS).

    Valid values: yes, true, enable and 1.

    NOTE: this option is only valid with enhanced
          file systems.

 15. disk_accounting [OPTIONAL] [boolean]
    Indicates whether or not to start disk accounting on
    this file system, defaulting to no.

    Valid values: no, yes

    NOTE: this option is not valid with enhanced
          file systems.

 16. fragment_size [OPTIONAL] [posint]
    Specifies the file system fragment size in bytes.
    Decreasing the fragment size below a full block
    (4096 bytes) allows partial blocks to be allocated
    at the end of a file. You can set the fragment size
    to 512, 1024, 2048, or 4096 bytes. If a file system
    is compressed, you must specify a fragment size of
    512, 1024, or 2048 bytes. Defaults to 4096.

    Valid values: 4096, 512, 1024, 2048

    NOTE: this option is only valid for standard and
          compressed file systems.

 17. bytes_per_inode [OPTIONAL] [set]
    The ratio of file system size, in bytes, to the number
    of i-nodes. Increasing the number of bytes per i-node
    (NBPI) decreases the total number of i-nodes in a file
    system.

    Valid values: 512, 1024, 2048, 4096, 8192,
                  16384, 32768, 65536, 131072

 18. alloc_group_size [OPTIONAL] [set]
    The Allocation Group size determines the allowed range
    of NBPI values for a file system according to the
    following table:

    Allocation Group Size NBPI Range:
        8: 512, 1024, 2048, 4096, 8192, 16384
       16: 1024, 2048, 4096, 8192, 16384, 32768
       32: 2048, 4096, 8192, 16384, 32768, 65536
       64: 4096, 8192, 16384, 32768, 65536, 131072

    Valid values: 8, 16, 32, 64

 19. logical_volume [OPTIONAL] [string]
    An existing logical volume to create the new file system
    within. If not specified, a new logical volume is created
    automatically.


=head1 RETURN

 0: no errors were detected; the operation appears to have been successful
 1: a general error has occurred
 2: a specified resource does not exist, or could not be found
 3: some required input was missing
 4: some detected input was incorrect in some way
 5: a required dependency does not exist
 6: a specified search failed to match any data

=cut
} # End of POD-formatted documentation.


function KLIB_HACMP_add_file_system {
    . $HALIBROOT/log_entry "$0()" "$CL"
    : version=@(#)  ddac8c3 43haes/lib/ksh93/hacmp/KLIB_HACMP_add_file_system.sh, 726, 2147A_aha726, Apr 23 2021 12:25 AM
    : INPUTS: $*

    typeset -n properties=$1
    typeset file_system=${2//\"/}
    typeset volume_group=${3//\"/}
    typeset -l type=${4//\"/}
    typeset units=${5//\"/}
    typeset size_per_unit=${6//\"/}
    typeset -l permissions=${7//\"/}
    typeset -l options=${8//\"/}
    typeset block_size=${9//\"/}
    typeset lv_for_log=${10//\"/}
    typeset inline_log_size=${11//\"/}
    typeset -l ext_attr_format=${12//\"/}
    typeset -l enable_quota_mgmt=${13//\"/}
    typeset -l enable_efs=${14//\"/}
    typeset -l disk_accounting=${15//\"/}
    typeset fragment_size=${16//\"/}
    typeset bytes_per_inode=${17//\"/}
    typeset alloc_group_size=${18//\"/}
    typeset logical_volume=${19//\"/}


    [[ $CLMGR_LOGGING == 'med' ]] && set +x  # Only trace param values

    #===================================
    : Declare and initialize variables
    #===================================
    typeset -i rc=$RC_UNKNOWN
    typeset INPUT="" ATTR="" VALUE=""
    typeset -l type_lc=$type


    [[ -z $_CSPOC_CALLED_FROM_SMIT ]] && _CSPOC_CALLED_FROM_SMIT=true
    export _CSPOC_CALLED_FROM_SMIT

    #=================
    : Validate input
    #=================
    if [[ -n $type_lc ]]; then
        case $type_lc in
            e*) typeOpt=" -v jfs2" ;;
            s*) typeOpt=" -v jfs"  ;;
            c*) typeOpt=" -v jfs"  ;;
            b*) typeOpt=" -v jfs"  ;;  # Same as "large"
            l*) typeOpt=" -v jfs"  ;;  # Same as "big"
            *) dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\"\n" TYPE "$type" 1>&2
               dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "enhanced, standard, compressed, big" 1>&2
               rc=$RC_INCORRECT_INPUT
            ;;
        esac
    else
        dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" TYPE 1>&2
        dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "enhanced, standard, compressed, big" 1>&2
        rc=$RC_MISSING_INPUT
    fi
   
    if [[ -n $logical_volume ]]; then
        CL=$LINENO KLIB_HACMP_is_known_logical_volume $logical_volume
        if (( $? == RC_SUCCESS )); then
            if [[ -z $volume_group ]]; then
                print "$0()[$LINENO]($SECONDS): $HASBIN/cl_lslv $logical_volume | /bin/grep \"VOLUME GROUP:\"" >>$CLMGR_TMPLOG
                volume_group=$($HASBIN/cl_lslv $logical_volume | /bin/grep "VOLUME GROUP:")
                print "$0()[$LINENO]($SECONDS): cl_lslv RC: $?; $logical_volume volume group == \"$volume_group\"" >>$CLMGR_TMPLOG
                volume_group=${volume_group##*VOLUME GROUP:+([[:space:]])}
                volume_group=${volume_group%%+([[:space:]])*}
            fi
        else
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$logical_volume" 1>&2
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 160 "Available Logical Volumes:\n\n" 1>&2

            typeset available
            CL=$LINENO KLIB_HACMP_list_logical_volumes available VOLUME_GROUP=$volume_group
            for (( i=0; i<${#available[*]}; i++ )); do
                if [[ ${available[$i]} != *([[:space:]]) ]]; then
                    print -u2 "\t${available[$i]}"
                fi
            done
            print -u2 ""

            rc=$RC_NOT_FOUND
        fi

    elif [[ $units == *([[:space:]]) ]]; then
        dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" UNITS 1>&2
        rc=$RC_MISSING_INPUT
    fi
    
    if [[ -n $volume_group ]]; then
          rg=$(clodmget -q "name ="CONCURRENT_VOLUME_GROUP" and value="$volume_group"" -f group HACMPresource)
          if [[ -n $rg ]]; then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 1457 "\nERROR: a file system cannot be created in volume group \"%1\$s\" \n\ because \"%2\$s\" is a OAAN(online on all available nodes) resource group.\n" "$volume_group" "$rg" 1>&2
                rc=$RC_INCORRECT_INPUT
          fi
    fi

    if [[ -z $volume_group && -z $logical_volume ]]; then
        dspmsg -s $CLMGR_SET $CLMGR_MSGS 101 "\nERROR: this operation requires the \"%1\$s\" attribute.\n\n" VOLUME_GROUP 1>&2
        rc=$RC_MISSING_INPUT

    elif [[ -n $volume_group ]]; then
        CL=$LINENO KLIB_HACMP_is_known_volume_group $volume_group >>$CLMGR_TMPLOG 2>&1
        if (( $? != RC_SUCCESS )); then
            (( invalid_nodes++ ))
            dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$volume_group" 1>&2
            dspmsg -s $CLMGR_SET $CLMGR_MSGS 160 "Available Volume Groups:\n\n" 1>&2

            typeset available
            CL=$LINENO KLIB_HACMP_list_volume_groups available
            for (( i=0; i<${#available[*]}; i++ )); do
                if [[ ${available[$i]} != *([[:space:]]) ]]; then
                    print -u2 "\t${available[$i]}"
                fi
            done
            print -u2 ""

            rc=$RC_NOT_FOUND

        else
            : Get the nodes for the volume group $volume_group
            typeset -A vgProps
            CL=$LINENO KLIB_HACMP_get_volume_group_attributes $volume_group vgProps 2>>$CLMGR_TMPLOG
            nodes=${vgProps[NODES]}
        fi
    fi

    if [[ -n $lv_for_log ]]; then
        if [[ $lv_for_log != "INLINE" ]]; then
            CL=$LINENO KLIB_HACMP_is_known_logical_volume $lv_for_log
            if (( $? != RC_SUCCESS )); then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$lv_for_log" 1>&2
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 160 "Available Logical Volumes:\n\n" 1>&2

                typeset available
                CL=$LINENO KLIB_HACMP_list_logical_volumes available VOLUME_GROUP=$volume_group
                for (( i=0; i<${#available[*]}; i++ )); do
                    if [[ ${available[$i]} != *([[:space:]]) ]]; then
                        print -u2 "\t${available[$i]}"
                    fi
                done
                print -u2 ""

                rc=$RC_NOT_FOUND
            fi
        fi
    fi

    if [[ $lv_for_log == "INLINE" ]]; then
        if [[ $inline_log_size == *([[:space:]]) ]]; then
            CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' INLINE_LOG_SIZE LV_FOR_LOG=INLINE 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    #==============================
    : Validate the integer inputs
    #==============================
    for INPUT in UNITS@$units \
                INLINE_LOG_SIZE@$inline_log_size
    do
        print -- "$INPUT" | IFS=@ read ATTR VALUE
        if [[ $VALUE != *([[:space:]]) ]]; then
            CL=$LINENO verify_is_numeric "$VALUE" 2 "$ATTR"
            (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
        fi
    done

    #==============================
    : Validate the boolean inputs
    #==============================
    if [[ -n $disk_accounting ]]; then
        CL=$LINENO verify_in_set DISK_ACCOUNTING "$disk_accounting" "yes true enable 1 no false disable 0" disk_accounting
        if (( $? == RC_SUCCESS )); then
            disk_accounting="no"
            [[ $disk_accounting == @(y|t|1)* ]] && disk_accounting="yes"
        else
            rc=$RC_INCORRECT_INPUT
        fi
    fi
    if [[ -n $enable_efs ]]; then
        CL=$LINENO verify_in_set EFS "$enable_efs" "yes true enable 1" enable_efs
        if (( $? == RC_SUCCESS )); then
            [[ $enable_efs == @(y|e|t|1)* ]] && enable_efs="yes"
        else
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    #==========================
    : Validate the set inputs
    #==========================
    if [[ -n $permissions ]]; then
        CL=$LINENO verify_in_set PERMISSIONS "$permissions" "rw ro" permissions
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi
    if [[ -n $block_size ]]; then
        CL=$LINENO verify_in_set BLOCK_SIZE "$block_size" "4096 512 1024 2048" block_size
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi
    if [[ -n $enable_quota_mgmt ]]; then
        CL=$LINENO verify_in_set ENABLE_QUOTA_MGMT "$enable_quota_mgmt" "no all user group" enable_quota_mgmt
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi
    if [[ -n $alloc_group_size ]]; then
        CL=$LINENO verify_in_set ALLOC_GROUP_SIZE "$alloc_group_size" "8 16 32 64" alloc_group_size
        (( $? != RC_SUCCESS )) && rc=$RC_INCORRECT_INPUT
    fi

    if [[ $size_per_unit == *([[:space:]]) ]]; then
        size_per_unit="M"
    else
        typeset -l spu_lc=$size_per_unit
        case $spu_lc in
            m*) size_per_unit="M" ;;
            g*) size_per_unit="G" ;;
            5*) size_per_unit="H" ;;
            h*) size_per_unit="H" ;;
             *) dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" SIZE_PER_UNIT "$size_per_unit" 1>&2
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "megabytes, gigabytes, 512bytes" 1>&2
        esac
    fi

    if [[ $ext_attr_format != *([[:space:]]) ]]; then
        typeset -l eaf_lc=$ext_attr_format
        if [[ $ext_attr_format != *(v)@(1|2) ]]; then
            dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" EXT_ATTR_FORMAT "$ext_attr_format" 1>&2
            dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "megabytes, gigabytes, 512bytes" 1>&2
        fi
    fi

    if [[ $options != *([[:space:]]) ]]; then
        typeset -l opt_lc=$options
        typeset NEW_VALUE=""
        for VALUE in ${opt_lc//,/ }; do
            if [[ $VALUE == nod* ]]; then
                [[ -n $NEW_VALUE ]] && NEW_VALUE="$NEW_VALUE,"
                NEW_VALUE="${NEW_VALUE}nodev"
            elif [[ $VALUE == nos* ]]; then
                [[ -n $NEW_VALUE ]] && NEW_VALUE="$NEW_VALUE,"
                NEW_VALUE="${NEW_VALUE}nosuid"
            elif [[ $VALUE == all ]]; then
                [[ -n $NEW_VALUE ]] && NEW_VALUE="$NEW_VALUE,"
                NEW_VALUE="${NEW_VALUE}nodev,nosuid"
            else
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" OPTIONS "$options" 1>&2
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "nodev, nosuid" 1>&2
            fi
        done
        options=$NEW_VALUE
    fi

    if [[ -n $bytes_per_inode ]]; then
        if [[ $alloc_group_size == 8 ]]; then
            if [[ $bytes_per_inode != @(512|1024|2048|4096|8192|16384) ]]
            then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 '\nERROR: invalid value specified for "%1$s":  "%2$s".\n' "BYTES_PER_INODE (ALLOC_GROUP_SIZE=8)" "$bytes_per_inode" 1>&2
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "(ALLOC_GROUP_SIZE=8) 512, 1024, 2048, 4096, 8192, 16384" 1>&2
                rc=$RC_INCORRECT_INPUT
            fi

        elif [[ $alloc_group_size == 16 ]]; then
            if [[ $bytes_per_inode != @(1024|2048|4096|8192|16384|32768) ]]
            then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 '\nERROR: invalid value specified for "%1$s":  "%2$s".\n' "BYTES_PER_INODE (ALLOC_GROUP_SIZE=16)" "$bytes_per_inode" 1>&2
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "(ALLOC_GROUP_SIZE=16) 1024, 2048, 4096, 8192, 16384, 32768" 1>&2
                rc=$RC_INCORRECT_INPUT
            fi

        elif [[ $alloc_group_size == 32 ]]; then
            if [[ $bytes_per_inode != @(2048|4096|8192|16384|32768|65536) ]]
            then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 '\nERROR: invalid value specified for "%1$s":  "%2$s".\n' "BYTES_PER_INODE (ALLOC_GROUP_SIZE=32)" "$bytes_per_inode" 1>&2
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "(ALLOC_GROUP_SIZE=32) 2048, 4096, 8192, 16384, 32768, 65536" 1>&2
                rc=$RC_INCORRECT_INPUT
            fi

        elif [[ $alloc_group_size == 64 ]]; then
            if [[ $bytes_per_inode != @(4096|8192|16384|32768|65536|131072) ]]
            then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 '\nERROR: invalid value specified for "%1$s":  "%2$s".\n' "BYTES_PER_INODE (ALLOC_GROUP_SIZE=64)" "$bytes_per_inode" 1>&2
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "(ALLOC_GROUP_SIZE=64) 4096, 8192, 16384, 32768, 65536, 131072" 1>&2
                rc=$RC_INCORRECT_INPUT
            fi
        fi
    fi

    #==================================
    : Check for type-specific options
    #==================================
    if [[ $type_lc != e* ]]; then
        if [[ $block_size != *([[:space:]]) ]]; then
            CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' BLOCK_SIZE TYPE=enhanced 1>&2
            rc=$RC_INCORRECT_INPUT
        fi

    else
        for INPUT in DISK_ACCOUNTING@$disk_accounting \
                     BYTES_PER_INODE@$bytes_per_inode \
                     ALLOC_GROUP_SIZE@$alloc_group_size
        do
            print -- "$INPUT" | IFS=@ read ATTR VALUE
            if [[ $VALUE != *([[:space:]]) ]]; then
                CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' "$ATTR" "TYPE=(standard|compressed|large)" 1>&2
                rc=$RC_INCORRECT_INPUT
            fi
        done
    fi

    if [[ $type_lc != @(s|c)* ]]; then
        if [[ $fragment_size != *([[:space:]]) ]]; then
            CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 45 '\nERROR: "%1$s" may only be used with "%2$s".\n\n' FRAGMENT_SIZE "TYPE=(standard|compressed)" 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
    fi

    #========================================================================
    : If no errors have been detected in the input, set defaults, as needed
    #========================================================================
    typeset mandatoryOpts=""
    if [[ $type_lc == e* ]]; then    # "Enhanced" file system
        [[ -z $block_size ]] && block_size=4096
    elif [[ $type_lc == s* ]]; then  # "Standard" file system
        [[ -z $fragment_size    ]] && fragment_size=4096
        [[ -z $alloc_group_size ]] && alloc_group_size=8
        [[ -z $bytes_per_inode  ]] && bytes_per_inode=4096
    elif [[ $type_lc == c* ]]; then  # "Compressed" file system
        [[ -z $fragment_size    ]] && fragment_size=512
        [[ -z $alloc_group_size ]] && alloc_group_size=8
        [[ -z $bytes_per_inode  ]] && bytes_per_inode=512
        mandatoryOpts=" -a compress=LZ"
    elif [[ $type_lc == @(l|b)* ]]; then  # "Large" file system
        [[ -z $alloc_group_size ]] && alloc_group_size=64
        [[ -z $bytes_per_inode  ]] && bytes_per_inode=4096
        mandatoryOpts=" -a bf=true"
    fi

    #======================================================================
    : If no errors have been detected in the input, perform the operation
    #======================================================================
    if (( rc == RC_UNKNOWN )); then
        typeset gOpt="" vOpt=" -v jfs" mOpt="" unitsOpt="" FOpt=" -F M" pOpt=""
        typeset bsOpt="" optOpt="" ilOpt="" lvOpt="" lsOpt="" eafOpt=""
        typeset quotaOpt="" efsOpt="" tOpt="" fragOpt="" nbpiOpt="" agOpt=""
        typeset dOpt=""

        if [[ $type_lc == s* ]]; then
            if [[ $fragment_size == *([[:space:]]) ]]; then
                fragment_size=4096
            fi
        fi

        [[ $volume_group != *([[:space:]]) ]] && gOpt=" -g $volume_group"
        [[ $type_lc == e*                  ]] && vOpt=" -v jfs2"
        [[ $file_system != *([[:space:]])  ]] && mOpt=" -m $file_system"
        [[ $units != *([[:space:]])        ]] && unitsOpt=" -a size=$units"
        [[ $permissions != *([[:space:]])  ]] && pOpt=" -p $permissions" || pOpt=" -p rw"
        [[ $options != *([[:space:]])      ]] && optOpt=" -a options=$options"
        [[ $lv_for_log != *([[:space:]])   ]] && lvOpt=" -a logname=$lv_for_log"
        [[ $enable_efs == "yes"            ]] && efsOpt=" -a efs=yes"
        if [[ -n $disk_accounting ]]; then
            [[ $disk_accounting == "yes"   ]] && tOpt=" -t yes" \
                                              || tOpt=" -t no"
        fi
        [[ $inline_log_size != *([[:space:]])   ]] && lsOpt=" -a logsize=$inline_log_size"
        [[ $enable_quota_mgmt != *([[:space:]]) ]] && quotaOpt=" -a quota=$enable_quota_mgmt"
        [[ $fragment_size != *([[:space:]])     ]] && fragOpt=" -a frag=$fragment_size"
        [[ $bytes_per_inode != *([[:space:]])   ]] && nbpiOpt=" -a nbpi=$bytes_per_inode"
        [[ $alloc_group_size != *([[:space:]])  ]] && agOpt=" -a ag=$alloc_group_size"
        [[ $logical_volume != *([[:space:]])    ]] && dOpt=" -d $logical_volume"

        if [[ $ext_attr_format != *([[:space:]]) ]]; then
            if [[ $ext_attr_format == *2 ]]; then
                eafOpt=" -a ea=v2"
            else
                eafOpt=" -a ea=v1"
            fi
        fi

        if [[ $block_size != *([[:space:]]) ]]; then
            bsOpt=" -a agblksize=$block_size"
        fi

        if [[ $size_per_unit != *([[:space:]]) ]]; then
            typeset uos_lc=$size_per_unit
            [[ $uos_lc == "G" ]] && FOpt=" -F G"
            [[ $uos_lc == "H" ]] && FOpt=" -F H"
        fi

        if [[ $logical_volume == *([[:space:]]) ]]; then
            print "$0()[$LINENO]($SECONDS): $HASBIN/cl_crlvfs -cspoc \"-n $nodes\"$vOpt$gOpt$FOpt$unitsOpt$mOpt$pOpt$bsOpt$optOpt$ilOpt$lvOpt$lsOpt$eafOpt$quotaOpt$efsOpt$tOpt$fragOpt$nbpiOpt$agOpt$mandatoryOpts" >>$CLMGR_TMPLOG
            $HASBIN/cl_crlvfs -cspoc "-n $nodes"$vOpt$gOpt$FOpt$unitsOpt$mOpt$pOpt$bsOpt$optOpt$ilOpt$lvOpt$lsOpt$eafOpt$quotaOpt$efsOpt$tOpt$fragOpt$nbpiOpt$agOpt$mandatoryOpts
            rc=$?
            print "$0()[$LINENO]($SECONDS): cl_crlvfs RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
        else
            print "$0()[$LINENO]($SECONDS): $HASBIN/cl_crfs -cspoc \"-n $nodes\"$vOpt$gOpt$dOpt$mOpt$pOpt$bsOpt$optOpt$ilOpt$lvOpt$lsOpt$eafOpt$quotaOpt$efsOpt$tOpt$fragOpt$nbpiOpt$agOpt$mandatoryOpts" >>$CLMGR_TMPLOG
            $HASBIN/cl_crfs -cspoc "-n $nodes"$vOpt$gOpt$dOpt$mOpt$pOpt$bsOpt$optOpt$ilOpt$lvOpt$lsOpt$eafOpt$quotaOpt$efsOpt$tOpt$fragOpt$nbpiOpt$agOpt$mandatoryOpts
            rc=$?
            print "$0()[$LINENO]($SECONDS): cl_crfs RC: $rc" >>$CLMGR_TMPLOG  # Always log command result
        fi

        if (( $rc != RC_SUCCESS )); then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 201 "\nERROR: failed to create \"%1\$s\".\n\n" "$file_system" 1>&2
            rc=$RC_ERROR

        #===========================================================
        : If output from this operation was requested, retrieve it
        #===========================================================
        elif (( CLMGR_VERBOSE )) || [[ -n $CLMGR_ATTRS ]]; then
            CL=$LINENO KLIB_HACMP_get_file_system_attributes "$file_system" properties
        fi
    fi

    #=======================================================================
    : If a user input error was detected, provide some helpful suggestions
    #=======================================================================
    if (( $rc == RC_MISSING_INPUT || $rc == RC_INCORRECT_INPUT )) && \
       [[ $CLMGR_GUI == *([[:space:]]) ]]
    then
        CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 104 "For more information about available options and syntax, try\n\"$HAUTILS/clmgr %1\$s\". As an\nalternative, if the PowerHA SystemMirror man pages have been installed, invoke\n\"$HAUTILS/clmgr -hv\" (or \"/usr/bin/man clmgr\"),\nsearching for \"%2\$s\" in the displayed text.\n\n" \
        "add file_system -h" "FILE SYSTEM:" "$CLMGR_PROGNAME" 1>&2
    fi

    log_return_msg "$rc" "$0()" "$LINENO"
    return $?
} # End of "KLIB_HACMP_add_file_system()"
#================================================
# The following, commented line enforces coding
# standards when this file is edited via vim.
#================================================
# vim:tabstop=4:shiftwidth=4:expandtab:smarttab
#================================================
