Skip to content

Mounting more than 64 shares with 1 C# process not possible. #364

Description

@JFra-AME

Environment

  • Windows version: Windows 10
  • Processor architecture: x64 Intel(R) Core(TM) i7-6700HQ
  • Dokany version: 2.2.0.1000
  • Library type (Dokany/FUSE): Dokany DotNet wrapper

Check List

  • I checked my issue doesn't exist yet
  • My issue is valid with mirror default sample and not specific to my user-mode driver implementation
  • I can always reproduce the issue with the provided description below.
  • I have updated Dokany to the latest version and have reboot my computer after.
  • I tested one of the last snapshot from appveyor CI

Description

Background

I am using the Dokany .NET wrapper to provide users within my organization with their own virtual drives, each equipped with custom access control. This setup requires the creation of over 64 individual shares, as each user is assigned a unique share.

Problem

When attempting to create multiple shares for users, I encountered a hard limit of 64 shares per C# process. This restriction causes issues when mounting more than 64 shares in a directory such as C:\shares.
Specifically:

  • Shares exceeding the 64-share "limit" become inaccessible. When trying to access shares 65 and beyond, the system displays an error message: "The parameter is incorrect."
    image

  • Discrepancy in displayed size: Successfully mounted shares correctly reflect the size of the C: disk. However, shares beyond the limit (those that are "corrupt") show a default or incorrect size:
    image

This behaviour prevents me from scaling the virtual drive solution to meet the needs of the organization.

Replication

To replicate this I provide an altered code of the Mirror .NET sample.
In the class Program of the sample DokanNetMirror
Once this code is running it will take 64 seconds till it will make the "corrupt" shares.

private static async Task Main(string[] args)
{
    try
    {
        var arguments = args
           .Select(x => x.Split(new char[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries))
           .ToDictionary(x => x[0], x => x.Length > 1 ? x[1] as object : true, StringComparer.OrdinalIgnoreCase);

        var mirrorPath = arguments.ContainsKey(MirrorKey)
           ? arguments[MirrorKey] as string
           : @"C:\productdata";

        var mountPath = arguments.ContainsKey(MountKey)
           ? arguments[MountKey] as string
           : @"C:\Share\";

        var unsafeReadWrite = arguments.ContainsKey(UseUnsafeKey);

        using (var mirrorLogger = new ConsoleLogger("[Mirror] "))
        using (var dokanLogger = new ConsoleLogger("[Dokan] "))
        using (var dokan = new Dokan(dokanLogger))
        {
            var mirror = unsafeReadWrite
                ? new UnsafeMirror(mirrorLogger, mirrorPath)
                : new Mirror(mirrorLogger, mirrorPath);

            // Creation of shares 1 till 128
            for (int i = 1; i <= 128; i++)
            {
                // Delay for a more smooth creation of the shares
                await Task.Delay(1000);

                // Creation of the correct mount path so each share gets its own mount
                var actualMountPath = mountPath + i + @"\";
                dokanLogger.Warn($"Started mounting on path {actualMountPath}");

                // If the mountPath does not exist create it.
                if (!Directory.Exists(actualMountPath))
                    Directory.CreateDirectory(actualMountPath);

                var dokanBuilder = new DokanInstanceBuilder(dokan)
                    .ConfigureLogger(() => dokanLogger)
                    .ConfigureOptions(options =>
                    {
                        options.Options = DokanOptions.DebugMode | DokanOptions.StderrOutput;
                        options.MountPoint = actualMountPath;
                    });

                // Run async so that the loop continues and the share does not close down .
                Task.Run(async () =>
                {
                    using (var dokanInstance = dokanBuilder.Build(mirror))
                    using (var notify = new Notify(mirrorPath, actualMountPath, dokanInstance))
                    {
                        // Debug message
                        dokanLogger.Warn($"Is dokany running for:{actualMountPath}. Answer: {dokanInstance.IsFileSystemRunning()}");

                        await dokanInstance.WaitForFileSystemClosedAsync(uint.MaxValue);
                    }
                });
            }
        }
        Console.WriteLine(@"Success");
    }
    catch (DokanException ex)
    {
        Console.WriteLine(@"Error: " + ex.Message);
    }
}

More details

image

Multible processes

I have also tested running multiple processes, which appears to work, but still remains limited to only 64 shares per process. While this approach offers some benefits, my goal is to enable the creation of more than 64 shares within a single process.

Logs

DebugView kernel logs.
image
DokanyDebugLogs1.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions