Tag Archives: ext4 Filesystem

Testing length of Linux ext3/ext4 and ZFS file names with Python 3

Last Update: 2022-04-16 15:22

So, I was working on a project and i wanted to test how long a file can be.

The resources I checked, and also the Kernel and C source I reviewed, were pointing that effectively the limit is 255 characters.

But I had one doubt… given that Python 3 String are UTF-8, and that Linux encode by default is UTF-8, will I be able to use 255 characters length, or this will be reduced as the Strings will be encoded as UTF-8 or Unicode?.

So I did a small Proof of Concept.

For the filenames I grabbed a fragment of the translation to English of the book epic book “Tirant lo Blanc” (The White Knight), one of the first books written in Catalan language and the first chivalry novel known in the world. You can download it for free it in:

https://onlinebooks.library.upenn.edu/webbin/gutbook/lookup?num=378

Python Code:

from carleslibs.fileutils import FileUtils
from colorama import Fore, Back, Style , init


class ColorUtils:

    def __init__(self):
        # For Colorama on Windows
        init()

    def print_error(self, s_text, s_end="\n"):
        """
        Prints errors in Red.
        :param s_text:
        :return:
        """
        print(Fore.RED + s_text)
        print(Style.RESET_ALL, end=s_end)

    def print_success(self, s_text, s_end="\n"):
        """
        Prints errors in Green.
        :param s_text:
        :return:
        """
        print(Fore.GREEN + s_text)
        print(Style.RESET_ALL, end=s_end)

    def print_label(self, s_text, s_end="\n"):
        """
        Prints a label and not the end line
        :param s_text:
        :return:
        """
        print(Fore.BLUE + s_text, end="")
        print(Style.RESET_ALL, end=s_end)

    def return_text_blue(self, s_text):
        """
        Restuns a Text
        :param s_text:
        :return: String
        """
        s_text_return = Fore.BLUE + s_text + Style.RESET_ALL
        return s_text_return


if __name__ == "__main__":

    o_color = ColorUtils()
    o_file = FileUtils()

    s_text = "In the fertile, rich and lovely island of England there lived a most valiant knight, noble by his lineage and much more for his "
    s_text += "courage.  In his great wisdom and ingenuity he had served the profession of chivalry for many years and with a great deal of honor, "
    s_text += "and his fame was widely known throughout the world.  His name was Count William of Warwick.  This was a very strong knight "
    s_text += "who, in his virile youth, had practiced the use of arms, following wars on sea as well as land, and he had brought many "
    s_text += "battles to a successful conclusion."

    o_color.print_label("Erasure Code project by Carles Mateo")
    print()
    print("Task 237 - Proof of Concep of Long File Names, encoded is ASCii, in Linux ext3 and ext4 Filesystems")
    print()
    print("Using as a sample a text based on the translation of Tirant Lo Blanc")
    print("Sample text used:")
    print("-"*30)
    print(s_text)
    print("-" * 30)
    print()
    print("This test uses the OpenSource libraries from Carles Mateo carleslibs")
    print()
    print("Initiating tests")
    print("================")

    s_dir = "task237_tests"

    if o_file.folder_exists(s_dir) is True:
        o_color.print_success("Directory " + s_dir + " already existed, skipping creation")
    else:
        b_success = o_file.create_folder(s_dir)
        if b_success is True:
            o_color.print_success("Directory " + s_dir + " created successfully")
        else:
            o_color.print_error("Directory " + s_dir + " creation failed")
            exit(1)

    for i_length in range(200, 512, 1):
        s_filename = s_dir + "/" + s_text[0:i_length]
        b_success = o_file.write(s_file=s_filename, s_text=s_text)
        s_output = "Writing file length: "
        print(s_output, end="")
        o_color.print_label(str(i_length).rjust(3), s_end="")
        print(" file name: ", end="")
        o_color.print_label(s_filename, s_end="")
        print(": ", end="")
        if b_success is False:
            o_color.print_error("failed", s_end="\n")
            exit(0)
        else:
            o_color.print_success("success", s_end="\n")

    # Note: up to 255 work, 256 fails

I tried this in an Ubuntu Virtual Box VM.

As part of my tests I tried to add a non typical character in English, ASCii >127, like Ç.

When I use ASCii character < 128 (0 to 127) for the filenames in ext3/ext4 and in a ZFS Pool, I can use 255 positions. But when I add characters that are not typical, like the Catalan ç Ç or accents Àí the space available is reduced, suggesting the characters are being encoded:

Ç has value 128 in the ASCii table and ç 135.

I used my Open Source carleslibs and the package colorama.

Install them with:

pip3 install carleslibs colorama