authfs: support multiple threads

This change adds the -j option to let authfs run in multiple threads.

The bad news is even sequential read is sigificantly slower (2x-ish).

Note that this change does not enable -j anywhere.

Bug: 220386264
Test: ls /proc/`pidof authfs`/tasks  # show multiple threads
Test: Read large file. Time was ~2x-ish with -j2. (bad)
Change-Id: I82ad727d6af6413c2d1aa22a02416b9f38306fb5
diff --git a/authfs/src/fusefs/mount.rs b/authfs/src/fusefs/mount.rs
index 38503df..7f8bac1 100644
--- a/authfs/src/fusefs/mount.rs
+++ b/authfs/src/fusefs/mount.rs
@@ -16,6 +16,7 @@
 
 use fuse::mount::MountOption;
 use std::fs::OpenOptions;
+use std::num::NonZeroU8;
 use std::os::unix::io::AsRawFd;
 use std::path::Path;
 
@@ -35,6 +36,7 @@
     authfs: AuthFs,
     mountpoint: &Path,
     extra_options: &Option<String>,
+    threads: Option<NonZeroU8>,
 ) -> Result<(), fuse::Error> {
     let dev_fuse = OpenOptions::new()
         .read(true)
@@ -64,5 +66,8 @@
 
     let mut config = fuse::FuseConfig::new();
     config.dev_fuse(dev_fuse).max_write(MAX_WRITE_BYTES).max_read(MAX_READ_BYTES);
+    if let Some(num) = threads {
+        config.num_threads(u8::from(num).into());
+    }
     config.enter_message_loop(authfs)
 }
diff --git a/authfs/src/main.rs b/authfs/src/main.rs
index bdca5b4..60318e8 100644
--- a/authfs/src/main.rs
+++ b/authfs/src/main.rs
@@ -37,6 +37,7 @@
 use protobuf::Message;
 use std::convert::TryInto;
 use std::fs::File;
+use std::num::NonZeroU8;
 use std::path::{Path, PathBuf};
 use structopt::StructOpt;
 
@@ -67,6 +68,10 @@
     #[structopt(short = "o")]
     extra_options: Option<String>,
 
+    /// Number of threads to serve FUSE requests.
+    #[structopt(short = "j")]
+    thread_number: Option<NonZeroU8>,
+
     /// A read-only remote file with integrity check. Can be multiple.
     ///
     /// For example, `--remote-ro-file 5:sha256-1234abcd` tells the filesystem to associate the
@@ -312,7 +317,12 @@
     let mut authfs = AuthFs::new(RemoteFsStatsReader::new(service.clone()));
     prepare_root_dir_entries(service, &mut authfs, &args)?;
 
-    fusefs::mount_and_enter_message_loop(authfs, &args.mount_point, &args.extra_options)?;
+    fusefs::mount_and_enter_message_loop(
+        authfs,
+        &args.mount_point,
+        &args.extra_options,
+        args.thread_number,
+    )?;
     bail!("Unexpected exit after the handler loop")
 }