Merge branch 'schemev2plus' into 'master'
Use new positioned IO interface in disk drivers See merge request redox-os/drivers!168
This commit is contained in:
Generated
+150
-128
@@ -14,7 +14,7 @@ dependencies = [
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"spin",
|
||||
]
|
||||
|
||||
@@ -33,7 +33,7 @@ dependencies = [
|
||||
"plain",
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"rustc-hash",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
@@ -52,7 +52,9 @@ dependencies = [
|
||||
"pcid",
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox-scheme",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -64,7 +66,7 @@ dependencies = [
|
||||
"libredox 0.1.3",
|
||||
"redox-daemon",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -115,9 +117,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.81"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
|
||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
@@ -138,9 +140,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
@@ -157,7 +159,7 @@ dependencies = [
|
||||
"fdt 0.1.5",
|
||||
"libredox 0.1.3",
|
||||
"redox-daemon",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -168,7 +170,7 @@ dependencies = [
|
||||
"orbclient",
|
||||
"pcid",
|
||||
"redox-daemon",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -212,9 +214,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.15.4"
|
||||
version = "3.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
@@ -224,9 +226,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.90"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
|
||||
checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@@ -252,9 +254,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.35"
|
||||
version = "0.4.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a"
|
||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
@@ -284,7 +286,7 @@ name = "common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libredox 0.1.3",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -295,9 +297,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||
|
||||
[[package]]
|
||||
name = "crc"
|
||||
version = "3.0.1"
|
||||
version = "3.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
|
||||
checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
|
||||
dependencies = [
|
||||
"crc-catalog",
|
||||
]
|
||||
@@ -324,7 +326,7 @@ version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
|
||||
dependencies = [
|
||||
"crossbeam-utils 0.8.19",
|
||||
"crossbeam-utils 0.8.20",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -340,16 +342,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.19"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "driver-block"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"partitionlib",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -357,7 +359,7 @@ name = "driver-network"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libredox 0.1.3",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -371,7 +373,7 @@ dependencies = [
|
||||
"pcid",
|
||||
"redox-daemon",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -390,7 +392,7 @@ dependencies = [
|
||||
"ransid",
|
||||
"redox-daemon",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -475,7 +477,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -510,9 +512,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.12"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
@@ -533,9 +535,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
@@ -589,7 +591,7 @@ dependencies = [
|
||||
"pcid",
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -604,15 +606,15 @@ dependencies = [
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.5"
|
||||
version = "2.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4"
|
||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
@@ -628,24 +630,24 @@ dependencies = [
|
||||
"orbclient",
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.12"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
||||
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.10"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||
|
||||
[[package]]
|
||||
name = "ixgbed"
|
||||
@@ -658,7 +660,7 @@ dependencies = [
|
||||
"pcid",
|
||||
"redox-daemon",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -678,9 +680,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
@@ -701,7 +703,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"libc",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -711,15 +713,15 @@ dependencies = [
|
||||
"anyhow",
|
||||
"libredox 0.1.3",
|
||||
"redox-daemon",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.11"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
@@ -739,9 +741,9 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.1"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
@@ -756,9 +758,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.18"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
@@ -785,8 +787,10 @@ dependencies = [
|
||||
"pcid",
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox_syscall 0.5.1",
|
||||
"smallvec 1.13.1",
|
||||
"redox-scheme",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.2",
|
||||
"smallvec 1.13.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -798,7 +802,7 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
[[package]]
|
||||
name = "orbclient"
|
||||
version = "0.3.47"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/orbclient.git#8de2b5ac9ff71811cde41e3085fe6722a823a7e2"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/orbclient.git#563f1457890be4a81e9613bc803617482d38aa3b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libredox 0.0.2",
|
||||
@@ -858,7 +862,7 @@ dependencies = [
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall 0.2.16",
|
||||
"smallvec 1.13.1",
|
||||
"smallvec 1.13.2",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
@@ -874,9 +878,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.14"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "paw"
|
||||
@@ -931,7 +935,7 @@ dependencies = [
|
||||
"pci_types",
|
||||
"plain",
|
||||
"redox-log",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"structopt",
|
||||
@@ -945,14 +949,14 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"libredox 0.1.3",
|
||||
"redox-daemon",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.13"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
@@ -992,9 +996,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
|
||||
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -1007,14 +1011,14 @@ dependencies = [
|
||||
"libredox 0.1.3",
|
||||
"orbclient",
|
||||
"redox-daemon",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -1089,10 +1093,19 @@ checksum = "dbd7c67eb2d8e610a74a8f1e67eecd3042f87b1aebfa620de4b40257265a54f2"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"log",
|
||||
"smallvec 1.13.1",
|
||||
"smallvec 1.13.2",
|
||||
"termion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox-scheme"
|
||||
version = "0.2.0"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/redox-scheme.git#62aed6c712cca31bb18078adacd27b400f5ccf93"
|
||||
dependencies = [
|
||||
"libredox 0.1.3",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_event"
|
||||
version = "0.4.1"
|
||||
@@ -1123,9 +1136,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e"
|
||||
checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
]
|
||||
@@ -1139,7 +1152,7 @@ checksum = "20145670ba436b55d91fc92d25e71160fbfbdd57831631c8d7d36377a476f1cb"
|
||||
[[package]]
|
||||
name = "rehid"
|
||||
version = "0.1.0"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/rehid.git#d3c74a8abbdb75d93260883e3378c46b3e875fa9"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/rehid.git#ea48fff4901986903359cb616a9b0d0ff8d0d8b4"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"log",
|
||||
@@ -1159,7 +1172,7 @@ dependencies = [
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1175,7 +1188,7 @@ dependencies = [
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1186,9 +1199,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.17"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||
|
||||
[[package]]
|
||||
name = "sb16d"
|
||||
@@ -1201,7 +1214,7 @@ dependencies = [
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"spin",
|
||||
]
|
||||
|
||||
@@ -1256,29 +1269,29 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.197"
|
||||
version = "1.0.203"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.197"
|
||||
version = "1.0.203"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.114"
|
||||
version = "1.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
|
||||
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@@ -1287,9 +1300,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.5"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
|
||||
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -1314,9 +1327,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.1"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -1395,9 +1408,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.53"
|
||||
version = "2.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
|
||||
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1433,22 +1446,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.58"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
|
||||
checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.58"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
|
||||
checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1474,9 +1487,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.5"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -1508,9 +1521,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
|
||||
|
||||
[[package]]
|
||||
name = "usbctl"
|
||||
@@ -1528,7 +1541,7 @@ dependencies = [
|
||||
"log",
|
||||
"orbclient",
|
||||
"redox-log",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"rehid",
|
||||
"xhcid",
|
||||
]
|
||||
@@ -1539,7 +1552,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"redox-log",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"xhcid",
|
||||
]
|
||||
|
||||
@@ -1551,7 +1564,8 @@ dependencies = [
|
||||
"libredox 0.1.3",
|
||||
"plain",
|
||||
"redox-daemon",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox-scheme",
|
||||
"redox_syscall 0.5.2",
|
||||
"thiserror",
|
||||
"xhcid",
|
||||
]
|
||||
@@ -1573,9 +1587,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ux"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cb3ff47e36907a6267572c1e398ff32ef78ac5131de8aa272e53846592c207e"
|
||||
checksum = "3b59fc5417e036e53226bbebd90196825d358624fd5577432c4e486c95b1b096"
|
||||
|
||||
[[package]]
|
||||
name = "vboxd"
|
||||
@@ -1587,7 +1601,7 @@ dependencies = [
|
||||
"pcid",
|
||||
"redox-daemon",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1618,7 +1632,7 @@ dependencies = [
|
||||
"orbclient",
|
||||
"ransid",
|
||||
"redox-daemon",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1635,7 +1649,8 @@ dependencies = [
|
||||
"pcid",
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox-scheme",
|
||||
"redox_syscall 0.5.2",
|
||||
"spin",
|
||||
"static_assertions",
|
||||
"thiserror",
|
||||
@@ -1655,7 +1670,7 @@ dependencies = [
|
||||
"pcid",
|
||||
"redox-log",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"static_assertions",
|
||||
"thiserror",
|
||||
]
|
||||
@@ -1674,7 +1689,7 @@ dependencies = [
|
||||
"paste",
|
||||
"pcid",
|
||||
"redox-daemon",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"spin",
|
||||
"static_assertions",
|
||||
"virtio-core",
|
||||
@@ -1691,7 +1706,7 @@ dependencies = [
|
||||
"log",
|
||||
"pcid",
|
||||
"redox-daemon",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"static_assertions",
|
||||
"virtio-core",
|
||||
]
|
||||
@@ -1732,7 +1747,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.66",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -1754,7 +1769,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"syn 2.0.66",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -1798,13 +1813,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
@@ -1813,45 +1829,51 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.4"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
@@ -1888,10 +1910,10 @@ dependencies = [
|
||||
"redox-daemon",
|
||||
"redox-log",
|
||||
"redox_event",
|
||||
"redox_syscall 0.5.1",
|
||||
"redox_syscall 0.5.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"smallvec 1.13.1",
|
||||
"smallvec 1.13.2",
|
||||
"thiserror",
|
||||
"toml 0.5.11",
|
||||
]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "ahcid"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.2"
|
||||
@@ -9,9 +9,11 @@ byteorder = "1.2"
|
||||
log = "0.4"
|
||||
redox-daemon = "0.1"
|
||||
redox-log = "0.1"
|
||||
redox_syscall = "0.5"
|
||||
redox_syscall = { version = "0.5", features = ["std"] }
|
||||
|
||||
common = { path = "../../common" }
|
||||
driver-block = { path = "../driver-block" }
|
||||
pcid = { path = "../../pcid" }
|
||||
libredox = "0.1.3"
|
||||
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
|
||||
redox_event = "0.4"
|
||||
|
||||
+35
-52
@@ -4,21 +4,18 @@
|
||||
extern crate syscall;
|
||||
extern crate byteorder;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{ErrorKind, Read, Write};
|
||||
use std::io::{Read, Write};
|
||||
use std::os::fd::AsRawFd;
|
||||
use std::os::unix::io::{FromRawFd, RawFd};
|
||||
use std::usize;
|
||||
|
||||
use libredox::flag;
|
||||
use event::{EventFlags, RawEventQueue};
|
||||
use pcid_interface::PcidServerHandle;
|
||||
use redox_scheme::{RequestKind, Response, SignalBehavior, Socket, V2};
|
||||
use syscall::error::{Error, ENODEV};
|
||||
use syscall::data::{Event, Packet};
|
||||
use syscall::flag::EVENT_READ;
|
||||
use syscall::scheme::SchemeBlockMut;
|
||||
|
||||
use log::{error, info};
|
||||
use redox_log::{OutputBuilder, RedoxLogger};
|
||||
use syscall::{EAGAIN, EWOULDBLOCK};
|
||||
|
||||
use crate::scheme::DiskScheme;
|
||||
|
||||
@@ -94,31 +91,17 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
let address = unsafe { bar.physmap_mem("ahcid") };
|
||||
{
|
||||
let scheme_name = format!("disk.{}", name);
|
||||
let socket_fd = libredox::call::open(
|
||||
&format!(":{}", scheme_name),
|
||||
flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK,
|
||||
0,
|
||||
).expect("ahcid: failed to create disk scheme");
|
||||
let mut socket = unsafe { File::from_raw_fd(socket_fd as RawFd) };
|
||||
let socket = Socket::<V2>::nonblock(&scheme_name).expect("ahcid: failed to create disk scheme");
|
||||
|
||||
let mut irq_file = irq.irq_handle("ahcid");
|
||||
let irq_fd = irq_file.as_raw_fd() as usize;
|
||||
|
||||
let mut event_file = File::open("event:").expect("ahcid: failed to open event file");
|
||||
let mut event_queue = RawEventQueue::new().expect("ahcid: failed to create event queue");
|
||||
|
||||
libredox::call::setrens(0, 0).expect("ahcid: failed to enter null namespace");
|
||||
|
||||
event_file.write(&Event {
|
||||
id: socket_fd,
|
||||
flags: EVENT_READ,
|
||||
data: 0
|
||||
}).expect("ahcid: failed to event disk scheme");
|
||||
|
||||
event_file.write(&Event {
|
||||
id: irq_fd,
|
||||
flags: EVENT_READ,
|
||||
data: 0
|
||||
}).expect("ahcid: failed to event irq scheme");
|
||||
event_queue.subscribe(socket.inner().raw(), 1, EventFlags::READ).expect("ahcid: failed to event scheme socket");
|
||||
event_queue.subscribe(irq_fd, 1, EventFlags::READ).expect("ahcid: failed to event irq scheme");
|
||||
|
||||
daemon.ready().expect("ahcid: failed to notify parent");
|
||||
|
||||
@@ -128,34 +111,37 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
let mut mounted = true;
|
||||
let mut todo = Vec::new();
|
||||
while mounted {
|
||||
let mut event = Event::default();
|
||||
if event_file.read(&mut event).expect("ahcid: failed to read event file") == 0 {
|
||||
let Some(event) = event_queue.next().transpose().expect("ahcid: failed to read event file") else {
|
||||
break;
|
||||
}
|
||||
if event.id == socket_fd {
|
||||
};
|
||||
if event.fd == socket.inner().raw() {
|
||||
loop {
|
||||
let mut packet = Packet::default();
|
||||
match socket.read(&mut packet) {
|
||||
Ok(0) => {
|
||||
let sqe = match socket.next_request(SignalBehavior::Interrupt) {
|
||||
Ok(None) => {
|
||||
mounted = false;
|
||||
break;
|
||||
},
|
||||
Ok(_) => (),
|
||||
Err(err) => if err.kind() == ErrorKind::WouldBlock {
|
||||
Ok(Some(s)) => if let RequestKind::Call(call) = s.kind() {
|
||||
call
|
||||
} else {
|
||||
// TODO: Support e.g. cancellation
|
||||
continue;
|
||||
},
|
||||
Err(err) => if err.errno == EWOULDBLOCK || err.errno == EAGAIN {
|
||||
break;
|
||||
} else {
|
||||
panic!("ahcid: failed to read disk scheme: {}", err);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(a) = scheme.handle(&packet) {
|
||||
packet.a = a;
|
||||
socket.write(&mut packet).expect("ahcid: failed to write disk scheme");
|
||||
if let Some(response) = sqe.handle_scheme_block_mut(&mut scheme) {
|
||||
// TODO: handle full CQE?
|
||||
socket.write_response(response, SignalBehavior::Restart).expect("ahcid: failed to write disk scheme");
|
||||
} else {
|
||||
todo.push(packet);
|
||||
todo.push(sqe);
|
||||
}
|
||||
}
|
||||
} else if event.id == irq_fd {
|
||||
} else if event.fd == irq_fd {
|
||||
let mut irq = [0; 8];
|
||||
if irq_file.read(&mut irq).expect("ahcid: failed to read irq file") >= irq.len() {
|
||||
if scheme.irq() {
|
||||
@@ -164,10 +150,9 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
// Handle todos in order to finish previous packets if possible
|
||||
let mut i = 0;
|
||||
while i < todo.len() {
|
||||
if let Some(a) = scheme.handle(&todo[i]) {
|
||||
let mut packet = todo.remove(i);
|
||||
packet.a = a;
|
||||
socket.write(&mut packet).expect("ahcid: failed to write disk scheme");
|
||||
if let Some(resp) = todo[i].handle_scheme_block_mut(&mut scheme) {
|
||||
let _sqe = todo.remove(i);
|
||||
socket.write_response(resp, SignalBehavior::Restart).expect("ahcid: failed to write disk scheme");
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
@@ -175,25 +160,23 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error!("Unknown event {}", event.id);
|
||||
error!("Unknown event {}", event.fd);
|
||||
}
|
||||
|
||||
// Handle todos to start new packets if possible
|
||||
let mut i = 0;
|
||||
while i < todo.len() {
|
||||
if let Some(a) = scheme.handle(&todo[i]) {
|
||||
let mut packet = todo.remove(i);
|
||||
packet.a = a;
|
||||
socket.write(&packet).expect("ahcid: failed to write disk scheme");
|
||||
if let Some(response) = todo[i].handle_scheme_block_mut(&mut scheme) {
|
||||
let _sqe = todo.remove(i);
|
||||
socket.write_response(response, SignalBehavior::Restart).expect("ahcid: failed to write disk scheme");
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ! mounted {
|
||||
for mut packet in todo.drain(..) {
|
||||
packet.a = Error::mux(Err(Error::new(ENODEV)));
|
||||
socket.write(&packet).expect("ahcid: failed to write disk scheme");
|
||||
for sqe in todo.drain(..) {
|
||||
socket.write_response(Response::new(&sqe, Err(Error::new(ENODEV))), SignalBehavior::Restart).expect("ahcid: failed to write disk scheme");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+97
-150
@@ -1,22 +1,22 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::{cmp, str};
|
||||
use std::convert::{TryFrom};
|
||||
use std::str;
|
||||
use std::fmt::Write;
|
||||
use std::io::prelude::*;
|
||||
|
||||
use driver_block::{Disk, DiskWrapper};
|
||||
use syscall::schemev2::NewFdFlags;
|
||||
use syscall::{
|
||||
Error, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, Result,
|
||||
Io, SchemeBlockMut, Stat, MODE_DIR, MODE_FILE, O_DIRECTORY,
|
||||
O_STAT, SEEK_CUR, SEEK_END, SEEK_SET};
|
||||
Error, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, Result, Io, Stat, MODE_DIR,
|
||||
MODE_FILE, O_DIRECTORY, O_STAT,
|
||||
};
|
||||
use redox_scheme::{CallerCtx, OpenResult, SchemeBlockMut};
|
||||
|
||||
use crate::ahci::hba::HbaMem;
|
||||
|
||||
#[derive(Clone)]
|
||||
enum Handle {
|
||||
List(Vec<u8>, usize), // Dir contents buffer, position
|
||||
Disk(usize, usize), // Disk index, position
|
||||
Partition(usize, u32, usize), // Disk index, partition index, position
|
||||
List(Vec<u8>), // Dir contents buffer
|
||||
Disk(usize), // Disk index
|
||||
Partition(usize, u32), // Disk index, partition index
|
||||
}
|
||||
|
||||
pub struct DiskScheme {
|
||||
@@ -30,8 +30,8 @@ pub struct DiskScheme {
|
||||
impl DiskScheme {
|
||||
pub fn new(scheme_name: String, hba_mem: &'static mut HbaMem, disks: Vec<Box<dyn Disk>>) -> DiskScheme {
|
||||
DiskScheme {
|
||||
scheme_name: scheme_name,
|
||||
hba_mem: hba_mem,
|
||||
scheme_name,
|
||||
hba_mem,
|
||||
disks: disks.into_iter().map(DiskWrapper::new).collect::<Vec<_>>().into_boxed_slice(),
|
||||
handles: BTreeMap::new(),
|
||||
next_id: 0
|
||||
@@ -61,10 +61,10 @@ impl DiskScheme {
|
||||
fn check_locks(&self, disk_i: usize, part_i_opt: Option<u32>) -> Result<()> {
|
||||
for (_, handle) in self.handles.iter() {
|
||||
match handle {
|
||||
Handle::Disk(i, _) => if disk_i == *i {
|
||||
Handle::Disk(i) => if disk_i == *i {
|
||||
return Err(Error::new(ENOLCK));
|
||||
},
|
||||
Handle::Partition(i, p, _) => if disk_i == *i {
|
||||
Handle::Partition(i, p) => if disk_i == *i {
|
||||
match part_i_opt {
|
||||
Some(part_i) => if part_i == *p {
|
||||
return Err(Error::new(ENOLCK));
|
||||
@@ -82,74 +82,64 @@ impl DiskScheme {
|
||||
}
|
||||
|
||||
impl SchemeBlockMut for DiskScheme {
|
||||
fn open(&mut self, path: &str, flags: usize, uid: u32, _gid: u32) -> Result<Option<usize>> {
|
||||
if uid == 0 {
|
||||
let path_str = path.trim_matches('/');
|
||||
if path_str.is_empty() {
|
||||
if flags & O_DIRECTORY == O_DIRECTORY || flags & O_STAT == O_STAT {
|
||||
let mut list = String::new();
|
||||
fn xopen(&mut self, path: &str, flags: usize, ctx: &CallerCtx) -> Result<Option<OpenResult>> {
|
||||
if ctx.uid != 0 {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
let path_str = path.trim_matches('/');
|
||||
|
||||
for (disk_index, disk) in self.disks.iter().enumerate() {
|
||||
write!(list, "{}\n", disk_index).unwrap();
|
||||
let handle = if path_str.is_empty() {
|
||||
if flags & O_DIRECTORY != O_DIRECTORY && flags & O_STAT != O_STAT {
|
||||
return Err(Error::new(EISDIR));
|
||||
}
|
||||
let mut list = String::new();
|
||||
|
||||
if disk.pt.is_none() {
|
||||
continue
|
||||
}
|
||||
for part_index in 0..disk.pt.as_ref().unwrap().partitions.len() {
|
||||
write!(list, "{}p{}\n", disk_index, part_index).unwrap();
|
||||
}
|
||||
}
|
||||
for (disk_index, disk) in self.disks.iter().enumerate() {
|
||||
write!(list, "{}\n", disk_index).unwrap();
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, Handle::List(list.into_bytes(), 0));
|
||||
Ok(Some(id))
|
||||
} else {
|
||||
Err(Error::new(EISDIR))
|
||||
if disk.pt.is_none() {
|
||||
continue
|
||||
}
|
||||
} else if let Some(p_pos) = path_str.chars().position(|c| c == 'p') {
|
||||
let disk_id_str = &path_str[..p_pos];
|
||||
if p_pos + 1 >= path_str.len() {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
let part_id_str = &path_str[p_pos + 1..];
|
||||
let i = disk_id_str.parse::<usize>().or(Err(Error::new(ENOENT)))?;
|
||||
let p = part_id_str.parse::<u32>().or(Err(Error::new(ENOENT)))?;
|
||||
|
||||
if let Some(disk) = self.disks.get(i) {
|
||||
if disk.pt.is_none() || disk.pt.as_ref().unwrap().partitions.get(p as usize).is_none() {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
|
||||
self.check_locks(i, Some(p))?;
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, Handle::Partition(i, p, 0));
|
||||
Ok(Some(id))
|
||||
} else {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
} else {
|
||||
let i = path_str.parse::<usize>().or(Err(Error::new(ENOENT)))?;
|
||||
|
||||
if self.disks.get(i).is_some() {
|
||||
self.check_locks(i, None)?;
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, Handle::Disk(i, 0));
|
||||
Ok(Some(id))
|
||||
} else {
|
||||
Err(Error::new(ENOENT))
|
||||
for part_index in 0..disk.pt.as_ref().unwrap().partitions.len() {
|
||||
write!(list, "{}p{}\n", disk_index, part_index).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Handle::List(list.into_bytes())
|
||||
} else if let Some(p_pos) = path_str.chars().position(|c| c == 'p') {
|
||||
let disk_id_str = &path_str[..p_pos];
|
||||
if p_pos + 1 >= path_str.len() {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
let part_id_str = &path_str[p_pos + 1..];
|
||||
let i = disk_id_str.parse::<usize>().or(Err(Error::new(ENOENT)))?;
|
||||
let p = part_id_str.parse::<u32>().or(Err(Error::new(ENOENT)))?;
|
||||
|
||||
let disk = self.disks.get(i).ok_or(Error::new(ENOENT))?;
|
||||
if disk.pt.is_none() || disk.pt.as_ref().unwrap().partitions.get(p as usize).is_none() {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
|
||||
self.check_locks(i, Some(p))?;
|
||||
|
||||
Handle::Partition(i, p)
|
||||
} else {
|
||||
Err(Error::new(EACCES))
|
||||
}
|
||||
let i = path_str.parse::<usize>().or(Err(Error::new(ENOENT)))?;
|
||||
|
||||
if self.disks.get(i).is_none() {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
self.check_locks(i, None)?;
|
||||
|
||||
Handle::Disk(i)
|
||||
};
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, handle);
|
||||
Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED }))
|
||||
}
|
||||
|
||||
fn dup(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
|
||||
fn xdup(&mut self, id: usize, buf: &[u8], _: &CallerCtx) -> Result<Option<OpenResult>> {
|
||||
if ! buf.is_empty() {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
@@ -162,24 +152,24 @@ impl SchemeBlockMut for DiskScheme {
|
||||
let new_id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(new_id, new_handle);
|
||||
Ok(Some(new_id))
|
||||
Ok(Some(OpenResult::ThisScheme { number: new_id, flags: NewFdFlags::POSITIONED }))
|
||||
}
|
||||
|
||||
fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result<Option<usize>> {
|
||||
match *self.handles.get(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List(ref data, _) => {
|
||||
Handle::List(ref data) => {
|
||||
stat.st_mode = MODE_DIR;
|
||||
stat.st_size = data.len() as u64;
|
||||
Ok(Some(0))
|
||||
},
|
||||
Handle::Disk(number, _) => {
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
stat.st_mode = MODE_FILE;
|
||||
stat.st_size = disk.size();
|
||||
stat.st_blksize = disk.block_length()?;
|
||||
Ok(Some(0))
|
||||
}
|
||||
Handle::Partition(disk_id, part_num, _) => {
|
||||
Handle::Partition(disk_id, part_num) => {
|
||||
let disk = self.disks.get_mut(disk_id).ok_or(Error::new(EBADF))?;
|
||||
let size = {
|
||||
let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?;
|
||||
@@ -215,8 +205,8 @@ impl SchemeBlockMut for DiskScheme {
|
||||
}
|
||||
|
||||
match *handle {
|
||||
Handle::List(_, _) => (),
|
||||
Handle::Disk(number, _) => {
|
||||
Handle::List(_) => (),
|
||||
Handle::Disk(number) => {
|
||||
let number_str = format!("{}", number);
|
||||
let number_bytes = number_str.as_bytes();
|
||||
j = 0;
|
||||
@@ -226,7 +216,7 @@ impl SchemeBlockMut for DiskScheme {
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
Handle::Partition(disk_num, part_num, _) => {
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let path = format!("{}p{}", disk_num, part_num);
|
||||
let path_bytes = path.as_bytes();
|
||||
j = 0;
|
||||
@@ -241,71 +231,60 @@ impl SchemeBlockMut for DiskScheme {
|
||||
Ok(Some(i))
|
||||
}
|
||||
|
||||
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
|
||||
fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result<Option<usize>> {
|
||||
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List(ref handle, ref mut size) => {
|
||||
let count = (&handle[*size..]).read(buf).unwrap();
|
||||
*size += count;
|
||||
Ok(Some(count))
|
||||
Handle::List(ref handle) => {
|
||||
let src = usize::try_from(offset).ok().and_then(|o| handle.get(o..)).unwrap_or(&[]);
|
||||
|
||||
let byte_count = core::cmp::min(src.len(), buf.len());
|
||||
buf[..byte_count].copy_from_slice(&src[..byte_count]);
|
||||
Ok(Some(byte_count))
|
||||
},
|
||||
Handle::Disk(number, ref mut size) => {
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
let blk_len = disk.block_length()?;
|
||||
if let Some(count) = disk.read((*size as u64)/(blk_len as u64), buf)? {
|
||||
*size += count;
|
||||
Ok(Some(count))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
disk.read(offset / u64::from(blk_len), buf)
|
||||
}
|
||||
Handle::Partition(disk_num, part_num, ref mut position) => {
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?;
|
||||
let blksize = disk.block_length()?;
|
||||
|
||||
// validate that we're actually reading within the bounds of the partition
|
||||
let rel_block = *position as u64 / blksize as u64;
|
||||
let rel_block = offset / u64::from(blksize);
|
||||
|
||||
let abs_block = {
|
||||
let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?;
|
||||
let partition = pt.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?;
|
||||
|
||||
let abs_block = partition.start_lba + rel_block;
|
||||
// TODO: This shouldn't return EOVERFLOW?
|
||||
if rel_block >= partition.size {
|
||||
return Err(Error::new(EOVERFLOW));
|
||||
}
|
||||
abs_block
|
||||
};
|
||||
|
||||
if let Some(count) = disk.read(abs_block, buf)? {
|
||||
Ok(Some(count))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
disk.read(abs_block, buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
|
||||
fn write(&mut self, id: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> Result<Option<usize>> {
|
||||
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List(_, _) => {
|
||||
Handle::List(_) => {
|
||||
Err(Error::new(EBADF))
|
||||
},
|
||||
Handle::Disk(number, ref mut size) => {
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
let blk_len = disk.block_length()?;
|
||||
if let Some(count) = disk.write((*size as u64)/(blk_len as u64), buf)? {
|
||||
*size += count;
|
||||
Ok(Some(count))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
disk.write(offset / u64::from(blk_len), buf)
|
||||
}
|
||||
Handle::Partition(disk_num, part_num, ref mut position) => {
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?;
|
||||
let blksize = disk.block_length()?;
|
||||
|
||||
// validate that we're actually reading within the bounds of the partition
|
||||
let rel_block = *position as u64 / blksize as u64;
|
||||
let rel_block = offset / u64::from(blksize);
|
||||
|
||||
let abs_block = {
|
||||
let pt = disk.pt.as_ref().ok_or(Error::new(EBADF))?;
|
||||
@@ -318,56 +297,24 @@ impl SchemeBlockMut for DiskScheme {
|
||||
abs_block
|
||||
};
|
||||
|
||||
if let Some(count) = disk.write(abs_block, buf)? {
|
||||
Ok(Some(count))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
disk.write(abs_block, buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn seek(&mut self, id: usize, pos: isize, whence: usize) -> Result<Option<isize>> {
|
||||
let pos = pos as usize;
|
||||
|
||||
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List(ref mut handle, ref mut size) => {
|
||||
let len = handle.len() as usize;
|
||||
*size = match whence {
|
||||
SEEK_SET => cmp::min(len, pos),
|
||||
SEEK_CUR => cmp::max(0, cmp::min(len as isize, *size as isize + pos as isize)) as usize,
|
||||
SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize,
|
||||
_ => return Err(Error::new(EINVAL))
|
||||
};
|
||||
|
||||
Ok(Some(*size as isize))
|
||||
},
|
||||
Handle::Disk(number, ref mut size) => {
|
||||
fn fsize(&mut self, id: usize) -> Result<Option<u64>> {
|
||||
Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List(ref mut handle) => handle.len() as u64,
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(number).ok_or(Error::new(EBADF))?;
|
||||
let len = disk.size() as usize;
|
||||
*size = match whence {
|
||||
SEEK_SET => cmp::min(len, pos),
|
||||
SEEK_CUR => cmp::max(0, cmp::min(len as isize, *size as isize + pos as isize)) as usize,
|
||||
SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize,
|
||||
_ => return Err(Error::new(EINVAL))
|
||||
};
|
||||
|
||||
Ok(Some(*size as isize))
|
||||
disk.size()
|
||||
}
|
||||
Handle::Partition(disk_num, part_num, ref mut position) => {
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(disk_num).ok_or(Error::new(EBADF))?;
|
||||
let block_count = disk.pt.as_ref().ok_or(Error::new(EBADF))?.partitions.get(part_num as usize).ok_or(Error::new(EBADF))?.size;
|
||||
let len = u64::from(disk.block_length()?) * block_count;
|
||||
|
||||
*position = match whence {
|
||||
SEEK_SET => cmp::min(len as usize, pos) as usize, // Why isn't pos u64?
|
||||
SEEK_CUR => cmp::max(0, cmp::min(len as isize, *position as isize + pos as isize)) as usize,
|
||||
SEEK_END => cmp::max(0, cmp::min(len as isize, len as isize + pos as isize)) as usize,
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
};
|
||||
Ok(Some(*position as isize))
|
||||
u64::from(disk.block_length()?) * block_count
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
fn close(&mut self, id: usize) -> Result<Option<usize>> {
|
||||
|
||||
@@ -11,7 +11,9 @@ futures = "0.3"
|
||||
log = "0.4"
|
||||
redox-daemon = "0.1"
|
||||
redox-log = "0.1"
|
||||
redox_syscall = "0.5"
|
||||
redox_syscall = { version = "0.5", features = ["std"] }
|
||||
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
|
||||
redox_event = "0.4"
|
||||
partitionlib = { git = "https://gitlab.redox-os.org/redox-os/partitionlib.git" }
|
||||
smallvec = "1"
|
||||
|
||||
|
||||
+14
-22
@@ -11,6 +11,7 @@ use std::{slice, usize};
|
||||
|
||||
use libredox::flag;
|
||||
use pcid_interface::{PciFeature, PciFeatureInfo, PciFunction, PcidServerHandle};
|
||||
use redox_scheme::{CallRequest, RequestKind, SignalBehavior, Socket, V2};
|
||||
use syscall::{
|
||||
Event, Mmio, Packet, Result, SchemeBlockMut,
|
||||
PAGE_SIZE,
|
||||
@@ -278,13 +279,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
ptr: NonNull::new(address as *mut u8).expect("Physmapping BAR gave nullptr"),
|
||||
});
|
||||
|
||||
let socket_fd = libredox::call::open(
|
||||
&format!(":{}", scheme_name),
|
||||
flag::O_RDWR | flag::O_CREAT | flag::O_CLOEXEC,
|
||||
0,
|
||||
)
|
||||
.expect("nvmed: failed to create disk scheme");
|
||||
let mut socket_file = unsafe { File::from_raw_fd(socket_fd as RawFd) };
|
||||
let socket = Socket::<V2>::create(&scheme_name).expect("nvmed: failed to create disk scheme");
|
||||
|
||||
daemon.ready().expect("nvmed: failed to signal readiness");
|
||||
|
||||
@@ -306,27 +301,24 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
let mut scheme = DiskScheme::new(scheme_name, nvme, namespaces);
|
||||
let mut todo = Vec::new();
|
||||
loop {
|
||||
let mut packet = Packet::default();
|
||||
match socket_file.read(&mut packet) {
|
||||
Ok(0) => {
|
||||
// TODO: Use a proper event queue once interrupt support is back.
|
||||
match socket.next_request(SignalBehavior::Restart).expect("nvmed: failed to read disk scheme") {
|
||||
None => {
|
||||
break;
|
||||
},
|
||||
Ok(_) => {
|
||||
todo.push(packet);
|
||||
},
|
||||
Err(err) => match err.kind() {
|
||||
ErrorKind::WouldBlock => break,
|
||||
_ => Err(err).expect("nvmed: failed to read disk scheme"),
|
||||
},
|
||||
Some(req) => if let RequestKind::Call(c) = req.kind() {
|
||||
todo.push(c);
|
||||
} else {
|
||||
// TODO: cancellation
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let mut i = 0;
|
||||
while i < todo.len() {
|
||||
if let Some(a) = scheme.handle(&todo[i]) {
|
||||
let mut packet = todo.remove(i);
|
||||
packet.a = a;
|
||||
socket_file
|
||||
.write(&packet)
|
||||
if let Some(resp) = todo[i].handle_scheme_block_mut(&mut scheme) {
|
||||
let _req = todo.remove(i);
|
||||
socket.write_response(resp, SignalBehavior::Restart)
|
||||
.expect("nvmed: failed to write disk scheme");
|
||||
} else {
|
||||
i += 1;
|
||||
|
||||
+99
-163
@@ -6,10 +6,12 @@ use std::io::prelude::*;
|
||||
use std::sync::Arc;
|
||||
use std::{cmp, str};
|
||||
|
||||
use syscall::schemev2::NewFdFlags;
|
||||
use syscall::{
|
||||
Error, Io, Result, SchemeBlockMut, Stat, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK,
|
||||
EOVERFLOW, MODE_DIR, MODE_FILE, O_DIRECTORY, O_STAT, SEEK_CUR, SEEK_END, SEEK_SET,
|
||||
Error, Io, Result, Stat, EACCES, EBADF, EINVAL, EISDIR, ENOENT, ENOLCK, EOVERFLOW, MODE_DIR,
|
||||
MODE_FILE, O_DIRECTORY, O_STAT, SEEK_CUR, SEEK_END, SEEK_SET,
|
||||
};
|
||||
use redox_scheme::{CallerCtx, OpenResult, SchemeBlockMut};
|
||||
|
||||
use crate::nvme::{Nvme, NvmeNamespace};
|
||||
|
||||
@@ -17,9 +19,9 @@ use partitionlib::{LogicalBlockSize, PartitionTable};
|
||||
|
||||
#[derive(Clone)]
|
||||
enum Handle {
|
||||
List(Vec<u8>, usize), // entries, offset
|
||||
Disk(u32, usize), // disk num, offset
|
||||
Partition(u32, u32, usize), // disk num, part num, offset
|
||||
List(Vec<u8>), // entries
|
||||
Disk(u32), // disk num
|
||||
Partition(u32, u32), // disk num, part num
|
||||
}
|
||||
|
||||
pub struct DiskWrapper {
|
||||
@@ -162,10 +164,10 @@ impl DiskScheme {
|
||||
fn check_locks(&self, disk_i: u32, part_i_opt: Option<u32>) -> Result<()> {
|
||||
for (_, handle) in self.handles.iter() {
|
||||
match handle {
|
||||
Handle::Disk(i, _) => if disk_i == *i {
|
||||
Handle::Disk(i) => if disk_i == *i {
|
||||
return Err(Error::new(ENOLCK));
|
||||
},
|
||||
Handle::Partition(i, p, _) => if disk_i == *i {
|
||||
Handle::Partition(i, p) => if disk_i == *i {
|
||||
match part_i_opt {
|
||||
Some(part_i) => if part_i == *p {
|
||||
return Err(Error::new(ENOLCK));
|
||||
@@ -183,82 +185,75 @@ impl DiskScheme {
|
||||
}
|
||||
|
||||
impl SchemeBlockMut for DiskScheme {
|
||||
fn open(&mut self, path_str: &str, flags: usize, uid: u32, _gid: u32) -> Result<Option<usize>> {
|
||||
if uid == 0 {
|
||||
let path_str = path_str
|
||||
.trim_matches('/');
|
||||
if path_str.is_empty() {
|
||||
if flags & O_DIRECTORY == O_DIRECTORY || flags & O_STAT == O_STAT {
|
||||
let mut list = String::new();
|
||||
fn xopen(&mut self, path_str: &str, flags: usize, ctx: &CallerCtx) -> Result<Option<OpenResult>> {
|
||||
if ctx.uid != 0 {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
let path_str = path_str
|
||||
.trim_matches('/');
|
||||
|
||||
for (nsid, disk) in self.disks.iter() {
|
||||
write!(list, "{}\n", nsid).unwrap();
|
||||
let handle = if path_str.is_empty() {
|
||||
if flags & O_DIRECTORY == O_DIRECTORY || flags & O_STAT == O_STAT {
|
||||
let mut list = String::new();
|
||||
|
||||
if disk.pt.is_none() {
|
||||
continue;
|
||||
}
|
||||
for part_num in 0..disk.pt.as_ref().unwrap().partitions.len() {
|
||||
write!(list, "{}p{}\n", nsid, part_num).unwrap();
|
||||
}
|
||||
for (nsid, disk) in self.disks.iter() {
|
||||
write!(list, "{}\n", nsid).unwrap();
|
||||
|
||||
if disk.pt.is_none() {
|
||||
continue;
|
||||
}
|
||||
for part_num in 0..disk.pt.as_ref().unwrap().partitions.len() {
|
||||
write!(list, "{}p{}\n", nsid, part_num).unwrap();
|
||||
}
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, Handle::List(list.into_bytes(), 0));
|
||||
Ok(Some(id))
|
||||
} else {
|
||||
Err(Error::new(EISDIR))
|
||||
}
|
||||
} else if let Some(p_pos) = path_str.chars().position(|c| c == 'p') {
|
||||
let nsid_str = &path_str[..p_pos];
|
||||
|
||||
if p_pos + 1 >= path_str.len() {
|
||||
Handle::List(list.into_bytes())
|
||||
} else {
|
||||
return Err(Error::new(EISDIR));
|
||||
}
|
||||
} else if let Some(p_pos) = path_str.chars().position(|c| c == 'p') {
|
||||
let nsid_str = &path_str[..p_pos];
|
||||
|
||||
if p_pos + 1 >= path_str.len() {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
let part_num_str = &path_str[p_pos + 1..];
|
||||
|
||||
let nsid = nsid_str.parse::<u32>().or(Err(Error::new(ENOENT)))?;
|
||||
let part_num = part_num_str.parse::<u32>().or(Err(Error::new(ENOENT)))?;
|
||||
|
||||
if let Some(disk) = self.disks.get(&nsid) {
|
||||
if disk
|
||||
.pt
|
||||
.as_ref()
|
||||
.ok_or(Error::new(ENOENT))?
|
||||
.partitions
|
||||
.get(part_num as usize)
|
||||
.is_some()
|
||||
{
|
||||
self.check_locks(nsid, Some(part_num))?;
|
||||
|
||||
Handle::Partition(nsid, part_num)
|
||||
} else {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
let part_num_str = &path_str[p_pos + 1..];
|
||||
|
||||
let nsid = nsid_str.parse::<u32>().or(Err(Error::new(ENOENT)))?;
|
||||
let part_num = part_num_str.parse::<u32>().or(Err(Error::new(ENOENT)))?;
|
||||
|
||||
if let Some(disk) = self.disks.get(&nsid) {
|
||||
if disk
|
||||
.pt
|
||||
.as_ref()
|
||||
.ok_or(Error::new(ENOENT))?
|
||||
.partitions
|
||||
.get(part_num as usize)
|
||||
.is_some()
|
||||
{
|
||||
self.check_locks(nsid, Some(part_num))?;
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles
|
||||
.insert(id, Handle::Partition(nsid, part_num, 0));
|
||||
Ok(Some(id))
|
||||
} else {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
} else {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
} else {
|
||||
let nsid = path_str.parse::<u32>().or(Err(Error::new(ENOENT)))?;
|
||||
|
||||
if self.disks.contains_key(&nsid) {
|
||||
self.check_locks(nsid, None)?;
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, Handle::Disk(nsid, 0));
|
||||
Ok(Some(id))
|
||||
} else {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
} else {
|
||||
Err(Error::new(EACCES))
|
||||
}
|
||||
let nsid = path_str.parse::<u32>().or(Err(Error::new(ENOENT)))?;
|
||||
|
||||
if self.disks.contains_key(&nsid) {
|
||||
self.check_locks(nsid, None)?;
|
||||
Handle::Disk(nsid)
|
||||
} else {
|
||||
return Err(Error::new(ENOENT));
|
||||
}
|
||||
};
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, handle);
|
||||
Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED }))
|
||||
}
|
||||
|
||||
fn dup(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
|
||||
@@ -279,12 +274,12 @@ impl SchemeBlockMut for DiskScheme {
|
||||
|
||||
fn fstat(&mut self, id: usize, stat: &mut Stat) -> Result<Option<usize>> {
|
||||
match *self.handles.get(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List(ref data, _) => {
|
||||
Handle::List(ref data) => {
|
||||
stat.st_mode = MODE_DIR;
|
||||
stat.st_size = data.len() as u64;
|
||||
Ok(Some(0))
|
||||
}
|
||||
Handle::Disk(number, _) => {
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?;
|
||||
stat.st_mode = MODE_FILE;
|
||||
stat.st_blocks = disk.as_ref().blocks;
|
||||
@@ -296,7 +291,7 @@ impl SchemeBlockMut for DiskScheme {
|
||||
stat.st_size = disk.as_ref().blocks * disk.as_ref().block_size;
|
||||
Ok(Some(0))
|
||||
}
|
||||
Handle::Partition(disk_num, part_num, _) => {
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(&disk_num).ok_or(Error::new(EBADF))?;
|
||||
let part = disk
|
||||
.pt
|
||||
@@ -337,8 +332,8 @@ impl SchemeBlockMut for DiskScheme {
|
||||
}
|
||||
|
||||
match *handle {
|
||||
Handle::List(_, _) => (),
|
||||
Handle::Disk(number, _) => {
|
||||
Handle::List(_) => (),
|
||||
Handle::Disk(number) => {
|
||||
let number_str = format!("{}", number);
|
||||
let number_bytes = number_str.as_bytes();
|
||||
j = 0;
|
||||
@@ -348,7 +343,7 @@ impl SchemeBlockMut for DiskScheme {
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
Handle::Partition(disk_num, part_num, _) => {
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let number_str = format!("{}p{}", disk_num, part_num);
|
||||
let number_bytes = number_str.as_bytes();
|
||||
j = 0;
|
||||
@@ -363,24 +358,20 @@ impl SchemeBlockMut for DiskScheme {
|
||||
Ok(Some(i))
|
||||
}
|
||||
|
||||
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
|
||||
fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result<Option<usize>> {
|
||||
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List(ref mut handle, ref mut size) => {
|
||||
let count = (&handle[*size..]).read(buf).unwrap();
|
||||
*size += count;
|
||||
Handle::List(ref handle) => {
|
||||
let src = usize::try_from(offset).ok().and_then(|o| handle.get(o..)).unwrap_or(&[]);
|
||||
let count = core::cmp::min(src.len(), buf.len());
|
||||
buf[..count].copy_from_slice(&src[..count]);
|
||||
Ok(Some(count))
|
||||
}
|
||||
Handle::Disk(number, ref mut size) => {
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?;
|
||||
let block_size = disk.as_ref().block_size;
|
||||
if let Some(count) = self.nvme.namespace_read(disk.as_ref(), disk.as_ref().id, (*size as u64) / block_size, buf)? {
|
||||
*size += count;
|
||||
Ok(Some(count))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
self.nvme.namespace_read(disk.as_ref(), disk.as_ref().id, offset / block_size, buf)
|
||||
}
|
||||
Handle::Partition(disk_num, part_num, ref mut offset) => {
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(&disk_num).ok_or(Error::new(EBADF))?;
|
||||
let part = disk
|
||||
.pt
|
||||
@@ -391,38 +382,27 @@ impl SchemeBlockMut for DiskScheme {
|
||||
.ok_or(Error::new(EBADF))?;
|
||||
|
||||
let block_size = disk.as_ref().block_size;
|
||||
let rel_block = (*offset as u64) / block_size;
|
||||
let rel_block = offset / block_size;
|
||||
if rel_block >= part.size {
|
||||
return Err(Error::new(EOVERFLOW));
|
||||
}
|
||||
|
||||
let abs_block = part.start_lba + rel_block;
|
||||
|
||||
if let Some(count) = self.nvme.namespace_read(disk.as_ref(), disk.as_ref().id, abs_block, buf)? {
|
||||
*offset += count;
|
||||
Ok(Some(count))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
self.nvme.namespace_read(disk.as_ref(), disk.as_ref().id, abs_block, buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn write(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
|
||||
fn write(&mut self, id: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> Result<Option<usize>> {
|
||||
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List(_, _) => Err(Error::new(EBADF)),
|
||||
Handle::Disk(number, ref mut size) => {
|
||||
Handle::List(_) => Err(Error::new(EBADF)),
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?;
|
||||
let block_size = disk.as_ref().block_size;
|
||||
if let Some(count) = self.nvme
|
||||
.namespace_write(disk.as_ref(), disk.as_ref().id, (*size as u64) / block_size, buf)? {
|
||||
*size += count;
|
||||
Ok(Some(count))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
self.nvme.namespace_write(disk.as_ref(), disk.as_ref().id, offset / block_size, buf)
|
||||
}
|
||||
Handle::Partition(disk_num, part_num, ref mut offset) => {
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(&disk_num).ok_or(Error::new(EBADF))?;
|
||||
let part = disk
|
||||
.pt
|
||||
@@ -433,57 +413,26 @@ impl SchemeBlockMut for DiskScheme {
|
||||
.ok_or(Error::new(EBADF))?;
|
||||
|
||||
let block_size = disk.as_ref().block_size;
|
||||
let rel_block = (*offset as u64) / block_size;
|
||||
let rel_block = offset / block_size;
|
||||
if rel_block >= part.size {
|
||||
return Err(Error::new(EOVERFLOW));
|
||||
}
|
||||
|
||||
let abs_block = part.start_lba + rel_block;
|
||||
|
||||
if let Some(count) = self.nvme.namespace_write(disk.as_ref(), disk.as_ref().id, abs_block, buf)? {
|
||||
*offset += count;
|
||||
Ok(Some(count))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
self.nvme.namespace_write(disk.as_ref(), disk.as_ref().id, abs_block, buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn seek(&mut self, id: usize, pos: isize, whence: usize) -> Result<Option<isize>> {
|
||||
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List(ref mut handle, ref mut size) => {
|
||||
let len = handle.len() as isize;
|
||||
*size = match whence {
|
||||
SEEK_SET => cmp::min(len, pos),
|
||||
SEEK_CUR => {
|
||||
cmp::max(0, cmp::min(len, *size as isize + pos))
|
||||
}
|
||||
SEEK_END => {
|
||||
cmp::max(0, cmp::min(len, len + pos))
|
||||
}
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
} as usize;
|
||||
|
||||
Ok(Some(*size as isize))
|
||||
}
|
||||
Handle::Disk(number, ref mut size) => {
|
||||
fn fsize(&mut self, id: usize) -> Result<Option<u64>> {
|
||||
Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List(ref handle) => handle.len() as u64,
|
||||
Handle::Disk(number) => {
|
||||
let disk = self.disks.get_mut(&number).ok_or(Error::new(EBADF))?;
|
||||
let len = (disk.as_ref().blocks * disk.as_ref().block_size) as isize;
|
||||
*size = match whence {
|
||||
SEEK_SET => cmp::min(len, pos),
|
||||
SEEK_CUR => {
|
||||
cmp::max(0, cmp::min(len, *size as isize + pos))
|
||||
}
|
||||
SEEK_END => {
|
||||
cmp::max(0, cmp::min(len, len + pos))
|
||||
}
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
} as usize;
|
||||
|
||||
Ok(Some(*size as isize))
|
||||
disk.as_ref().blocks * disk.as_ref().block_size
|
||||
}
|
||||
Handle::Partition(disk_num, part_num, ref mut size) => {
|
||||
Handle::Partition(disk_num, part_num) => {
|
||||
let disk = self.disks.get_mut(&disk_num).ok_or(Error::new(EBADF))?;
|
||||
let part = disk
|
||||
.pt
|
||||
@@ -493,22 +442,9 @@ impl SchemeBlockMut for DiskScheme {
|
||||
.get(part_num as usize)
|
||||
.ok_or(Error::new(EBADF))?;
|
||||
|
||||
let len = (part.size * disk.as_ref().block_size) as isize;
|
||||
|
||||
*size = match whence {
|
||||
SEEK_SET => cmp::min(len, pos),
|
||||
SEEK_CUR => {
|
||||
cmp::max(0, cmp::min(len, *size as isize + pos))
|
||||
}
|
||||
SEEK_END => {
|
||||
cmp::max(0, cmp::min(len, len + pos))
|
||||
}
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
} as usize;
|
||||
|
||||
Ok(Some(*size as isize))
|
||||
part.size * disk.as_ref().block_size
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
fn close(&mut self, id: usize) -> Result<Option<usize>> {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "usbscsid"
|
||||
version = "0.1.0"
|
||||
authors = ["4lDO2 <4lDO2@protonmail.com>"]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
@@ -12,6 +12,7 @@ base64 = "0.11" # Only for debugging
|
||||
libredox = "0.1.3"
|
||||
plain = "0.2"
|
||||
redox-daemon = "0.1"
|
||||
redox_syscall = "0.5"
|
||||
redox_syscall = { version = "0.5", features = ["std"] }
|
||||
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
|
||||
thiserror = "1"
|
||||
xhcid = { path = "../../xhcid" }
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::os::unix::io::{FromRawFd, RawFd};
|
||||
|
||||
use libredox::flag;
|
||||
use syscall::{Packet, SchemeMut};
|
||||
use xhcid_interface::{ConfigureEndpointsReq, DeviceReqData, XhciClientHandle};
|
||||
use redox_scheme::{RequestKind, SignalBehavior, Socket, V2};
|
||||
use xhcid_interface::{ConfigureEndpointsReq, XhciClientHandle};
|
||||
|
||||
pub mod protocol;
|
||||
pub mod scsi;
|
||||
@@ -83,11 +79,10 @@ fn daemon(daemon: redox_daemon::Daemon, scheme: String, port: usize, protocol: u
|
||||
let mut protocol = protocol::setup(&handle, protocol, &desc, &conf_desc, &if_desc)
|
||||
.expect("Failed to setup protocol");
|
||||
|
||||
// TODO: Let all of the USB drivers syscall clone(2), and xhcid won't have to keep track of all
|
||||
// the drivers.
|
||||
let socket_fd = libredox::call::open(disk_scheme_name, flag::O_RDWR | flag::O_CREAT, 0)
|
||||
// TODO: Let all of the USB drivers fork or be managed externally, and xhcid won't have to keep
|
||||
// track of all the drivers.
|
||||
let socket_fd = Socket::<V2>::create(&disk_scheme_name)
|
||||
.expect("usbscsid: failed to create disk scheme");
|
||||
let mut socket_file = unsafe { File::from_raw_fd(socket_fd as RawFd) };
|
||||
|
||||
//libredox::call::setrens(0, 0).expect("scsid: failed to enter null namespace");
|
||||
let mut scsi = Scsi::new(&mut *protocol).expect("usbscsid: failed to setup SCSI");
|
||||
@@ -99,17 +94,19 @@ fn daemon(daemon: redox_daemon::Daemon, scheme: String, port: usize, protocol: u
|
||||
let mut scsi_scheme = ScsiScheme::new(&mut scsi, &mut *protocol);
|
||||
|
||||
// TODO: Use nonblocking and put all pending calls in a todo VecDeque. Use an eventfd as well.
|
||||
'scheme_loop: loop {
|
||||
let mut packet = Packet::default();
|
||||
match socket_file.read(&mut packet) {
|
||||
Ok(0) => break 'scheme_loop,
|
||||
Ok(_) => (),
|
||||
Err(err) => panic!("scsid: failed to read disk scheme: {}", err),
|
||||
}
|
||||
scsi_scheme.handle(&mut packet);
|
||||
socket_file
|
||||
.write(&packet)
|
||||
.expect("scsid: failed to write packet");
|
||||
loop {
|
||||
let req = match socket_fd.next_request(SignalBehavior::Restart).expect("scsid: failed to read disk scheme") {
|
||||
Some(r) => if let RequestKind::Call(c) = r.kind() {
|
||||
c
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
None => break,
|
||||
};
|
||||
let resp = req.handle_scheme_mut(&mut scsi_scheme);
|
||||
socket_fd
|
||||
.write_response(resp, SignalBehavior::Restart)
|
||||
.expect("scsid: failed to write cqe");
|
||||
}
|
||||
|
||||
std::process::exit(0);
|
||||
|
||||
@@ -4,20 +4,21 @@ use std::{cmp, str};
|
||||
use crate::protocol::Protocol;
|
||||
use crate::scsi::Scsi;
|
||||
|
||||
use redox_scheme::{CallerCtx, OpenResult, SchemeMut};
|
||||
use syscall::error::{Error, Result};
|
||||
use syscall::error::{EACCES, EBADF, EINVAL, EIO, ENOENT, ENOSYS};
|
||||
use syscall::flag::{MODE_CHR, MODE_DIR};
|
||||
use syscall::flag::{O_DIRECTORY, O_STAT};
|
||||
use syscall::flag::{SEEK_CUR, SEEK_END, SEEK_SET};
|
||||
use syscall::SchemeMut;
|
||||
use syscall::schemev2::NewFdFlags;
|
||||
|
||||
// TODO: Only one disk, right?
|
||||
const LIST_CONTENTS: &'static [u8] = b"0\n";
|
||||
|
||||
enum Handle {
|
||||
List(usize),
|
||||
Disk(usize),
|
||||
//Partition(usize, u32, usize),
|
||||
List,
|
||||
Disk,
|
||||
//Partition(usize, u32),
|
||||
}
|
||||
|
||||
pub struct ScsiScheme<'a> {
|
||||
@@ -38,9 +39,9 @@ impl<'a> ScsiScheme<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> SchemeMut for ScsiScheme<'a> {
|
||||
fn open(&mut self, path_str: &str, flags: usize, uid: u32, _gid: u32) -> Result<usize> {
|
||||
if uid != 0 {
|
||||
impl SchemeMut for ScsiScheme<'_> {
|
||||
fn xopen(&mut self, path_str: &str, flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
|
||||
if ctx.uid != 0 {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
if flags & O_DIRECTORY != 0 && flags & O_STAT == 0 {
|
||||
@@ -50,26 +51,26 @@ impl<'a> SchemeMut for ScsiScheme<'a> {
|
||||
.trim_start_matches('/');
|
||||
let handle = if path_str.is_empty() {
|
||||
// List
|
||||
Handle::List(0)
|
||||
Handle::List
|
||||
} else if let Some(_p_pos) = path_str.chars().position(|c| c == 'p') {
|
||||
// TODO: Partitions.
|
||||
return Err(Error::new(ENOSYS));
|
||||
} else {
|
||||
Handle::Disk(0)
|
||||
Handle::Disk
|
||||
};
|
||||
self.next_fd += 1;
|
||||
self.handles.insert(self.next_fd, handle);
|
||||
Ok(self.next_fd)
|
||||
Ok(OpenResult::ThisScheme { number: self.next_fd, flags: NewFdFlags::POSITIONED })
|
||||
}
|
||||
fn fstat(&mut self, fd: usize, stat: &mut syscall::Stat) -> Result<usize> {
|
||||
match self.handles.get(&fd).ok_or(Error::new(EBADF))? {
|
||||
Handle::Disk(_) => {
|
||||
Handle::Disk => {
|
||||
stat.st_mode = MODE_CHR;
|
||||
stat.st_size = self.scsi.get_disk_size();
|
||||
stat.st_blksize = self.scsi.block_size;
|
||||
stat.st_blocks = self.scsi.block_count;
|
||||
}
|
||||
Handle::List(_) => {
|
||||
Handle::List => {
|
||||
stat.st_mode = MODE_DIR;
|
||||
stat.st_size = LIST_CONTENTS.len() as u64;
|
||||
}
|
||||
@@ -78,84 +79,64 @@ impl<'a> SchemeMut for ScsiScheme<'a> {
|
||||
}
|
||||
fn fpath(&mut self, fd: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
let path = match self.handles.get_mut(&fd).ok_or(Error::new(EBADF))? {
|
||||
Handle::Disk(_) => "0",
|
||||
Handle::List(_) => "",
|
||||
Handle::Disk => "0",
|
||||
Handle::List => "",
|
||||
}
|
||||
.as_bytes();
|
||||
let min = std::cmp::min(path.len(), buf.len());
|
||||
buf[..min].copy_from_slice(&path[..min]);
|
||||
Ok(min)
|
||||
}
|
||||
fn seek(&mut self, fd: usize, pos: isize, whence: usize) -> Result<isize> {
|
||||
match self.handles.get_mut(&fd).ok_or(Error::new(EBADF))? {
|
||||
Handle::Disk(ref mut offset) => {
|
||||
let len = self.scsi.get_disk_size() as isize;
|
||||
*offset = match whence {
|
||||
SEEK_SET => cmp::max(0, cmp::min(pos, len)),
|
||||
SEEK_CUR => cmp::max(0, cmp::min(*offset as isize + pos, len)),
|
||||
SEEK_END => cmp::max(0, cmp::min(len + pos, len)),
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
} as usize;
|
||||
Ok(*offset as isize)
|
||||
}
|
||||
Handle::List(ref mut offset) => {
|
||||
let len = LIST_CONTENTS.len() as isize;
|
||||
*offset = match whence {
|
||||
SEEK_SET => cmp::max(0, cmp::min(pos, len)),
|
||||
SEEK_CUR => cmp::max(0, cmp::min(*offset as isize + pos, len)),
|
||||
SEEK_END => cmp::max(0, cmp::min(len + pos, len)),
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
} as usize;
|
||||
Ok(*offset as isize)
|
||||
}
|
||||
}
|
||||
fn fsize(&mut self, fd: usize) -> Result<u64> {
|
||||
Ok(match self.handles.get_mut(&fd).ok_or(Error::new(EBADF))? {
|
||||
Handle::Disk => self.scsi.get_disk_size(),
|
||||
Handle::List => LIST_CONTENTS.len() as u64,
|
||||
})
|
||||
}
|
||||
fn read(&mut self, fd: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
fn read(&mut self, fd: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> Result<usize> {
|
||||
match self.handles.get_mut(&fd).ok_or(Error::new(EBADF))? {
|
||||
Handle::Disk(ref mut offset) => {
|
||||
if *offset as u64 % u64::from(self.scsi.block_size) != 0
|
||||
Handle::Disk => {
|
||||
if offset % u64::from(self.scsi.block_size) != 0
|
||||
|| buf.len() as u64 % u64::from(self.scsi.block_size) != 0
|
||||
{
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
let lba = *offset as u64 / u64::from(self.scsi.block_size);
|
||||
let bytes_read = self
|
||||
.scsi
|
||||
.read(self.protocol, lba, buf)
|
||||
.map_err(|err| dbg!(err))
|
||||
.or(Err(Error::new(EIO)))?;
|
||||
*offset += bytes_read as usize;
|
||||
Ok(bytes_read as usize)
|
||||
let lba = offset / u64::from(self.scsi.block_size);
|
||||
match self.scsi.read(self.protocol, lba, buf) {
|
||||
Ok(bytes_read) => Ok(bytes_read as usize),
|
||||
Err(err) => {
|
||||
eprintln!("usbscsid: READ IO ERROR: {err}");
|
||||
Err(Error::new(EIO))
|
||||
}
|
||||
}
|
||||
}
|
||||
Handle::List(ref mut offset) => {
|
||||
let max_bytes_to_read = cmp::min(LIST_CONTENTS.len(), buf.len());
|
||||
let bytes_to_read = cmp::max(max_bytes_to_read, *offset) - *offset;
|
||||
Handle::List => {
|
||||
let src = usize::try_from(offset).ok().and_then(|o| LIST_CONTENTS.get(o..)).unwrap_or(&[]);
|
||||
let min = core::cmp::min(src.len(), buf.len());
|
||||
buf[..min].copy_from_slice(&src[..min]);
|
||||
|
||||
buf[..bytes_to_read].copy_from_slice(&LIST_CONTENTS[..bytes_to_read]);
|
||||
*offset += bytes_to_read;
|
||||
|
||||
Ok(bytes_to_read)
|
||||
Ok(min)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn write(&mut self, fd: usize, buf: &[u8]) -> Result<usize> {
|
||||
fn write(&mut self, fd: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> Result<usize> {
|
||||
match self.handles.get_mut(&fd).ok_or(Error::new(EBADF))? {
|
||||
Handle::Disk(ref mut offset) => {
|
||||
if *offset as u64 % u64::from(self.scsi.block_size) != 0
|
||||
Handle::Disk => {
|
||||
if offset % u64::from(self.scsi.block_size) != 0
|
||||
|| buf.len() as u64 % u64::from(self.scsi.block_size) != 0
|
||||
{
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
let lba = *offset as u64 / u64::from(self.scsi.block_size);
|
||||
let bytes_written = self
|
||||
.scsi
|
||||
.write(self.protocol, lba, buf)
|
||||
.map_err(|err| dbg!(err))
|
||||
.or(Err(Error::new(EIO)))?;
|
||||
*offset += bytes_written as usize;
|
||||
Ok(bytes_written as usize)
|
||||
let lba = offset / u64::from(self.scsi.block_size);
|
||||
match self.scsi.write(self.protocol, lba, buf) {
|
||||
Ok(bytes_written) => Ok(bytes_written as usize),
|
||||
Err(err) => {
|
||||
eprintln!("usbscsid: WRITE IO ERROR: {err}");
|
||||
Err(Error::new(EIO))
|
||||
}
|
||||
}
|
||||
}
|
||||
Handle::List(_) => Err(Error::new(EBADF)),
|
||||
Handle::List => Err(Error::new(EBADF)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ spin = "*"
|
||||
|
||||
redox-daemon = "0.1"
|
||||
redox-log = "0.1"
|
||||
redox_syscall = "0.5"
|
||||
redox_syscall = { version = "0.5", features = ["std"] }
|
||||
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
|
||||
partitionlib = { git = "https://gitlab.redox-os.org/redox-os/partitionlib.git" }
|
||||
|
||||
common = { path = "../../common" }
|
||||
|
||||
@@ -7,6 +7,7 @@ use std::os::fd::{FromRawFd, RawFd};
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
use libredox::flag;
|
||||
use redox_scheme::{RequestKind, SignalBehavior, Socket, V2};
|
||||
use static_assertions::const_assert_eq;
|
||||
|
||||
use pcid_interface::*;
|
||||
@@ -141,30 +142,24 @@ fn deamon(deamon: redox_daemon::Daemon) -> anyhow::Result<()> {
|
||||
|
||||
let scheme_name = format!("disk.{}", name);
|
||||
|
||||
let socket_fd = libredox::call::open(
|
||||
&format!(":{}", scheme_name),
|
||||
flag::O_RDWR | flag::O_CREAT | flag::O_CLOEXEC,
|
||||
0,
|
||||
)
|
||||
.map_err(syscall::Error::from)
|
||||
.map_err(Error::SyscallError)?;
|
||||
let socket_fd = Socket::<V2>::create(&scheme_name).map_err(Error::SyscallError)?;
|
||||
|
||||
let mut socket_file = unsafe { File::from_raw_fd(socket_fd as RawFd) };
|
||||
let mut scheme = scheme::DiskScheme::new(queue, device_space);
|
||||
|
||||
deamon.ready().expect("virtio-blkd: failed to deamonize");
|
||||
|
||||
loop {
|
||||
let mut packet = Packet::default();
|
||||
socket_file
|
||||
.read(&mut packet)
|
||||
.expect("virtio-blkd: failed to read disk scheme");
|
||||
let packey = scheme.handle(&mut packet);
|
||||
packet.a = packey.unwrap();
|
||||
socket_file
|
||||
.write(&mut packet)
|
||||
.expect("virtio-blkd: failed to read disk scheme");
|
||||
let req = match socket_fd.next_request(SignalBehavior::Restart)
|
||||
.expect("virtio-blkd: failed to read disk scheme") {
|
||||
Some(r) => if let RequestKind::Call(c) = r.kind() { c } else { continue },
|
||||
None => break,
|
||||
};
|
||||
let resp = req.handle_scheme_block_mut(&mut scheme).expect("TODO: block?");
|
||||
socket_fd
|
||||
.write_response(resp, SignalBehavior::Restart)
|
||||
.expect("virtio-blkd: failed to write to disk scheme");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn daemon_runner(redox_daemon: redox_daemon::Daemon) -> ! {
|
||||
|
||||
@@ -10,8 +10,13 @@ use std::sync::Arc;
|
||||
use common::dma::Dma;
|
||||
use partitionlib::LogicalBlockSize;
|
||||
use partitionlib::PartitionTable;
|
||||
use syscall::*;
|
||||
|
||||
use redox_scheme::CallerCtx;
|
||||
use redox_scheme::OpenResult;
|
||||
use redox_scheme::SchemeBlockMut;
|
||||
use syscall::flag::*;
|
||||
use syscall::error::*;
|
||||
use syscall::schemev2::NewFdFlags;
|
||||
use virtio_core::spec::{Buffer, ChainBuilder, DescriptorFlags};
|
||||
use virtio_core::transport::Queue;
|
||||
|
||||
@@ -82,18 +87,13 @@ pub enum Handle {
|
||||
Partition {
|
||||
/// Partition Number
|
||||
number: u32,
|
||||
/// Offset in bytes
|
||||
offset: usize,
|
||||
},
|
||||
|
||||
List {
|
||||
entries: Vec<u8>,
|
||||
offset: usize,
|
||||
},
|
||||
|
||||
Disk {
|
||||
offset: usize,
|
||||
},
|
||||
Disk,
|
||||
}
|
||||
|
||||
pub struct DiskScheme<'a> {
|
||||
@@ -193,13 +193,12 @@ impl<'a> DiskScheme<'a> {
|
||||
}
|
||||
|
||||
impl<'a> SchemeBlockMut for DiskScheme<'a> {
|
||||
fn open(
|
||||
fn xopen(
|
||||
&mut self,
|
||||
path: &str,
|
||||
flags: usize,
|
||||
_uid: u32,
|
||||
_gid: u32,
|
||||
) -> syscall::Result<Option<usize>> {
|
||||
_ctx: &CallerCtx,
|
||||
) -> syscall::Result<Option<OpenResult>> {
|
||||
log::info!("virtiod: open: {}", path);
|
||||
|
||||
let path_str = path.trim_matches('/');
|
||||
@@ -222,11 +221,10 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> {
|
||||
id,
|
||||
Handle::List {
|
||||
entries: list.into_bytes(),
|
||||
offset: 0,
|
||||
},
|
||||
);
|
||||
|
||||
Ok(Some(id))
|
||||
Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED }))
|
||||
} else {
|
||||
return Err(syscall::Error::new(EISDIR));
|
||||
}
|
||||
@@ -248,36 +246,34 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> {
|
||||
id,
|
||||
Handle::Partition {
|
||||
number: part_num,
|
||||
offset: 0,
|
||||
},
|
||||
);
|
||||
|
||||
Ok(Some(id))
|
||||
Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED }))
|
||||
} else {
|
||||
let nsid = path_str.parse::<u32>().unwrap();
|
||||
assert_eq!(nsid, 0);
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
self.handles.insert(id, Handle::Disk { offset: 0 });
|
||||
Ok(Some(id))
|
||||
self.handles.insert(id, Handle::Disk);
|
||||
Ok(Some(OpenResult::ThisScheme { number: id, flags: NewFdFlags::POSITIONED }))
|
||||
}
|
||||
}
|
||||
|
||||
fn read(&mut self, id: usize, buf: &mut [u8]) -> syscall::Result<Option<usize>> {
|
||||
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
fn read(&mut self, id: usize, buf: &mut [u8], offset: u64, _fcntl_flags: u32) -> syscall::Result<Option<usize>> {
|
||||
Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List {
|
||||
ref mut entries,
|
||||
ref mut offset,
|
||||
} => {
|
||||
let count = (&entries[*offset..]).read(buf).unwrap();
|
||||
*offset += count;
|
||||
Ok(Some(count))
|
||||
let src = usize::try_from(offset).ok().and_then(|o| entries.get(o..)).unwrap_or(&[]);
|
||||
let count = core::cmp::min(src.len(), buf.len());
|
||||
buf[..count].copy_from_slice(&src[..count]);
|
||||
count
|
||||
}
|
||||
|
||||
Handle::Partition {
|
||||
number,
|
||||
ref mut offset,
|
||||
} => {
|
||||
let part_table = self.part_table.as_ref().unwrap();
|
||||
let part = part_table
|
||||
@@ -286,68 +282,52 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> {
|
||||
.ok_or(Error::new(EBADF))?;
|
||||
|
||||
// Get the offset in sectors.
|
||||
let rel_block = (*offset as u64) / BLK_SIZE;
|
||||
let rel_block = offset / BLK_SIZE;
|
||||
// if rel_block >= part.size {
|
||||
// return Err(Error::new(EOVERFLOW));
|
||||
// }
|
||||
|
||||
let abs_block = part.start_lba + rel_block;
|
||||
|
||||
let count = futures::executor::block_on(self.queue.read(abs_block, buf));
|
||||
*offset += count;
|
||||
Ok(Some(count))
|
||||
futures::executor::block_on(self.queue.read(abs_block, buf))
|
||||
}
|
||||
|
||||
Handle::Disk { ref mut offset } => {
|
||||
Handle::Disk => {
|
||||
let block_size = self.cfg.block_size();
|
||||
|
||||
let count = futures::executor::block_on(
|
||||
self.queue.read((*offset as u64) / block_size as u64, buf),
|
||||
);
|
||||
*offset += count;
|
||||
Ok(Some(count))
|
||||
futures::executor::block_on(
|
||||
self.queue.read(offset / u64::from(block_size), buf),
|
||||
)
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
fn write(&mut self, id: usize, buf: &[u8]) -> syscall::Result<Option<usize>> {
|
||||
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::Disk { ref mut offset } => {
|
||||
fn write(&mut self, id: usize, buf: &[u8], offset: u64, _fcntl_flags: u32) -> syscall::Result<Option<usize>> {
|
||||
Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::Disk => {
|
||||
let block_size = self.cfg.block_size();
|
||||
let count = futures::executor::block_on(
|
||||
self.queue.write((*offset as u64) / block_size as u64, buf),
|
||||
);
|
||||
|
||||
*offset += count;
|
||||
Ok(Some(count))
|
||||
futures::executor::block_on(
|
||||
self.queue.write(offset / u64::from(block_size), buf),
|
||||
)
|
||||
}
|
||||
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
_ => todo!(),
|
||||
}))
|
||||
}
|
||||
|
||||
fn seek(&mut self, id: usize, pos: isize, whence: usize) -> syscall::Result<Option<isize>> {
|
||||
match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
fn fsize(&mut self, id: usize) -> syscall::Result<Option<u64>> {
|
||||
Ok(Some(match *self.handles.get_mut(&id).ok_or(Error::new(EBADF))? {
|
||||
Handle::List {
|
||||
ref entries,
|
||||
ref mut offset,
|
||||
} => {
|
||||
let len = entries.len() as isize;
|
||||
log::debug!("list: whence={whence:?} pos={pos:?} part_len={len:?}");
|
||||
let len = entries.len() as u64;
|
||||
log::debug!("list: part_len={len:?}");
|
||||
|
||||
*offset = match whence {
|
||||
SEEK_SET => cmp::min(len, pos),
|
||||
SEEK_CUR => cmp::max(0, cmp::min(len, *offset as isize + pos)),
|
||||
SEEK_END => cmp::max(0, cmp::min(len, len + pos)),
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
} as usize;
|
||||
|
||||
Ok(Some(*offset as isize))
|
||||
len
|
||||
}
|
||||
|
||||
Handle::Partition {
|
||||
number,
|
||||
ref mut offset,
|
||||
} => {
|
||||
let part_table = self.part_table.as_ref().unwrap();
|
||||
let part = part_table
|
||||
@@ -356,33 +336,15 @@ impl<'a> SchemeBlockMut for DiskScheme<'a> {
|
||||
.ok_or(Error::new(EBADF))?;
|
||||
|
||||
// Partition size in bytes.
|
||||
let len = (part.size * BLK_SIZE) as isize;
|
||||
let len = part.size * BLK_SIZE;
|
||||
|
||||
log::debug!("part: whence={whence:?} pos={pos:?} part_len={len:?}");
|
||||
log::debug!("part: part_len={len:?}");
|
||||
|
||||
*offset = match whence {
|
||||
SEEK_SET => cmp::min(len, pos),
|
||||
SEEK_CUR => cmp::max(0, cmp::min(len, *offset as isize + pos)),
|
||||
SEEK_END => cmp::max(0, cmp::min(len, len + pos)),
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
} as usize;
|
||||
|
||||
Ok(Some(*offset as isize))
|
||||
len
|
||||
}
|
||||
|
||||
Handle::Disk { ref mut offset } => {
|
||||
let len = (self.cfg.capacity() * self.cfg.block_size() as u64) as isize;
|
||||
|
||||
*offset = match whence {
|
||||
SEEK_SET => cmp::min(len, pos),
|
||||
SEEK_CUR => cmp::max(0, cmp::min(len, *offset as isize + pos)),
|
||||
SEEK_END => cmp::max(0, cmp::min(len, len + pos)),
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
} as usize;
|
||||
|
||||
Ok(Some(*offset as isize))
|
||||
}
|
||||
}
|
||||
Handle::Disk => self.cfg.capacity() * u64::from(self.cfg.block_size()),
|
||||
}))
|
||||
}
|
||||
|
||||
fn fpath(&mut self, _id: usize, _buf: &mut [u8]) -> syscall::Result<Option<usize>> {
|
||||
|
||||
Reference in New Issue
Block a user