Compare commits

...

1141 Commits
page ... 1.4.7

Author SHA1 Message Date
AuxXxilium
eec2393740 tree: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-15 01:46:34 +01:00
AuxXxilium
5147002d0d custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-14 21:11:18 +01:00
AuxXxilium
b23b551d2e arc-functions: add new branch
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-14 18:59:15 +01:00
AuxXxilium
9c654b8661 ramdisk: rework more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-14 18:52:35 +01:00
AuxXxilium
4b07877e50 ramdisk: fix more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-14 18:35:43 +01:00
AuxXxilium
7d2583aa68 ramdisk: remove empty line
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-14 18:25:29 +01:00
AuxXxilium
2133cc94c6 ramdisk: more rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-14 18:20:16 +01:00
AuxXxilium
9cef565971 tree: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-14 18:10:50 +01:00
AuxXxilium
4e40d54f2d tree: update more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-13 20:32:05 +01:00
AuxXxilium
abfabee34a tree: rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-13 18:28:13 +01:00
AuxXxilium
faf340458c grub: update 2025-01-12 18:55:33 2025-01-12 18:55:33 +01:00
AuxXxilium
7c432898f5 boot: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-12 18:51:19 +01:00
AuxXxilium
1923b4774d build: update grub
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-12 18:47:22 +01:00
AuxXxilium
e297f7ccfe arc: update modulelist
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-11 17:30:00 +01:00
AuxXxilium
3cfa988a15 tree: more updates
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-11 16:09:20 +01:00
AuxXxilium
9a66f15f1d tree: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-11 15:17:35 +01:00
AuxXxilium
48b1443974 arc-functions: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-08 21:39:32 +01:00
AuxXxilium
a405764fe9 tree: fix more logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-05 14:59:55 +01:00
AuxXxilium
e552595b99 tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-03 18:04:27 +01:00
AuxXxilium
868443164e arc: remove compatboot
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-03 16:56:34 +01:00
AuxXxilium
9e688e76ce build: modify arc
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-03 16:54:21 +01:00
AuxXxilium
60d71dca4f build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 20:48:27 +01:00
AuxXxilium
090c29d589 build: cleanup files
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 20:44:11 +01:00
AuxXxilium
7f4d124f9c arc-functions: remove empty line in sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 19:24:49 +01:00
AuxXxilium
1d0adb6b61 build: update local
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 18:40:32 +01:00
AuxXxilium
99e9f13ae9 arc: update modelselection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 18:08:49 +01:00
AuxXxilium
5db6c8499d build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 17:56:15 +01:00
AuxXxilium
46bed3f449 arc-functions: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 17:56:08 +01:00
AuxXxilium
3ff54fa893 grub: update 2025-01-01 17:47:49 2025-01-01 17:47:49 +01:00
AuxXxilium
dba6e0c373 grub: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 17:39:27 +01:00
AuxXxilium
c4221d93d8 build: expand image to 2G
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 17:01:17 +01:00
AuxXxilium
78cb49b655 boot/functions: add more checks
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 16:51:02 +01:00
AuxXxilium
10933e8cae boot: rework to match latest changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 16:42:11 +01:00
AuxXxilium
122dc5a874 grub: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 16:41:13 +01:00
AuxXxilium
45e99341eb grub: update for amd
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 16:01:22 +01:00
AuxXxilium
b50dc273cc tree: rename stable -> minimal / next -> extended
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2025-01-01 16:01:10 +01:00
AuxXxilium
b2a31744a9 arc: rework some changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-31 04:22:39 +01:00
AuxXxilium
731ffd710c boot: add empty line
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-31 04:20:01 +01:00
AuxXxilium
276b21d130 arc: modelselection cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-31 04:18:38 +01:00
AuxXxilium
d202bf3565 Revert "tree: rework more"
This reverts commit 6bcf451e77.
2024-12-31 04:14:04 +01:00
AuxXxilium
b107c77d29 arc-functions: rewrite more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-31 04:07:28 +01:00
AuxXxilium
e608b32e3b arc/boot: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-31 03:24:42 +01:00
AuxXxilium
20caa713eb arc: update menu name
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-31 02:47:01 +01:00
AuxXxilium
6bcf451e77 tree: rework more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-30 21:15:49 +01:00
AuxXxilium
cd16e7f011 grub: sync with latest changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-30 18:23:56 +01:00
AuxXxilium
990a6cb03a init: sync with latest changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-30 18:23:44 +01:00
AuxXxilium
971331188b arc: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-30 17:43:20 +01:00
AuxXxilium
8407ed1482 arc: only add i915 if system support it
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-30 17:10:04 +01:00
AuxXxilium
9c15548d34 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-30 16:50:35 +01:00
AuxXxilium
5568b4f0b4 tree: multiple rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-30 16:44:06 +01:00
AuxXxilium
03a48fbd14 build: update more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-29 15:42:55 +01:00
AuxXxilium
0d5107e8cd build: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-29 14:16:28 +01:00
AuxXxilium
e9daed7143 func: fix dual build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-28 19:20:55 +01:00
AuxXxilium
8a1a314eb5 build: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-28 17:06:39 +01:00
AuxXxilium
a800767f0b bootscreen: fix config
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-28 16:48:11 +01:00
AuxXxilium
e8efec928a arc: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-28 14:43:31 +01:00
AuxXxilium
21630d6e33 arc: force reinit system after changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-28 13:41:33 +01:00
AuxXxilium
738a16514d tree: add more checks
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-28 13:33:25 +01:00
AuxXxilium
6debfe73b8 grub: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-28 01:19:50 +01:00
AuxXxilium
7a6197f04d build: update local
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 23:28:07 +01:00
AuxXxilium
491c15ec63 tree: rework more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 23:24:44 +01:00
AuxXxilium
3b94661c90 func: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 23:20:52 +01:00
AuxXxilium
e9463d990e tree: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 23:15:58 +01:00
AuxXxilium
90cc4520d8 func: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 23:01:24 +01:00
AuxXxilium
4cf4efffbe func: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 22:59:38 +01:00
AuxXxilium
071ae09e1b func: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 22:54:46 +01:00
AuxXxilium
21b0f768f1 tree: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 22:34:58 +01:00
AuxXxilium
fe774756c0 tree: revert some changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 22:27:52 +01:00
AuxXxilium
6ab4bf3a5a grub: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 22:01:07 +01:00
AuxXxilium
0a7db3b4bb arc: rewrite logic and cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 15:33:48 +01:00
AuxXxilium
9849dc2ecc arc: fix register hwid
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 15:05:20 +01:00
AuxXxilium
b82c840e04 init: fix shortpath
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 15:03:00 +01:00
AuxXxilium
d762884775 arc: fix message
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 15:01:49 +01:00
AuxXxilium
33e0149dbf grub: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-27 00:58:35 +01:00
AuxXxilium
3a98b86d33 func: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-26 00:27:19 +01:00
AuxXxilium
8354251917 boot: fix styling
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-25 15:26:19 +01:00
AuxXxilium
d9cd6ded90 build: update more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 17:21:40 +01:00
AuxXxilium
9eb611b388 build: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 17:05:51 +01:00
AuxXxilium
712b5a5cb9 build: update logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 17:02:15 +01:00
AuxXxilium
8e10997fd5 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 17:00:04 +01:00
AuxXxilium
ee35d426b3 grub: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 16:57:36 +01:00
AuxXxilium
8676e9e349 func: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 16:46:57 +01:00
AuxXxilium
efbd445a79 func: rewrite more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 16:46:10 +01:00
AuxXxilium
f23935e6c9 task: fix local build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 16:41:01 +01:00
AuxXxilium
edc87953a5 func: rewrite for api
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 16:39:53 +01:00
AuxXxilium
3cfc706a74 arc: fix command shown
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 16:39:42 +01:00
AuxXxilium
231eebd18b taskfile: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 16:12:28 +01:00
AuxXxilium
73d75f1769 tree: fix latest
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 16:07:42 +01:00
AuxXxilium
7bec0cc7f4 build: update grub
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 16:02:39 +01:00
AuxXxilium
1de80457ad build: update local
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 16:00:31 +01:00
AuxXxilium
d53d7ac473 arc: more rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 14:33:18 +01:00
AuxXxilium
60b1579628 arc: fix init
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 14:04:17 +01:00
AuxXxilium
5d344ed6a9 tree: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 13:49:54 +01:00
AuxXxilium
a6be08228b tree: more optimization
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 02:49:17 +01:00
AuxXxilium
d08e73e999 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 01:50:07 +01:00
AuxXxilium
9ba63a0c17 arc: fix more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 01:47:01 +01:00
AuxXxilium
96afe6dd29 tree: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-24 01:37:47 +01:00
AuxXxilium
1c71b690c4 arc: add failsafe for arc config mode
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-23 21:13:27 +01:00
AuxXxilium
dc51577bbb arc-functions: add unmount to mount dsm pool feature
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-23 17:56:55 +01:00
AuxXxilium
d092bf87c8 boot: extend message
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-23 17:23:43 +01:00
AuxXxilium
c1dd12c611 init: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-23 17:00:41 +01:00
AuxXxilium
6b2d4e720a boot: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-23 16:52:32 +01:00
AuxXxilium
2f9031e3fb tree: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-23 16:27:12 +01:00
AuxXxilium
df325c5f5e tree: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-21 16:22:32 +01:00
AuxXxilium
a1055d68be boot: add hwid output to bootscreen options
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-20 16:32:45 +01:00
AuxXxilium
10b0d1c64f tree: fix more logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-20 16:13:57 +01:00
AuxXxilium
2fdb4a5e69 tree: logic fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-20 15:35:02 +01:00
AuxXxilium
3b62345e5a grub: update 2024-12-17 23:21:27 2024-12-18 20:50:57 +01:00
AuxXxilium
f564167e9d tree: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-18 20:50:37 +01:00
AuxXxilium
67e3d5c0f8 tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-16 17:56:28 +01:00
AuxXxilium
39e00baf57 tree: more fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-11 18:17:54 +01:00
AuxXxilium
3378fb5a93 grub: update 2024-12-11 18:10:51 2024-12-11 18:10:51 +01:00
AuxXxilium
7e481182b1 tree: more fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-11 17:55:26 +01:00
AuxXxilium
6b0d2dad68 build: local update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-09 17:03:05 +01:00
AuxXxilium
8b8a7bcc99 storage: silence output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-08 13:49:34 +01:00
AuxXxilium
1ecf4db983 functions: rewrite text
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-07 18:51:40 +01:00
AuxXxilium
c9c320c2ca arc: fix port change
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-07 15:24:52 +01:00
AuxXxilium
04890fecd5 arc: fix SN if automated update and user set his own
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-07 13:45:03 +01:00
AuxXxilium
28c68c9043 network: fix window
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-07 00:31:17 +01:00
AuxXxilium
6f6778f3a3 tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-06 18:28:19 +01:00
AuxXxilium
bedf2d0a6b boot: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-06 16:23:54 +01:00
AuxXxilium
8af23fb3fe boot: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-05 19:37:53 +01:00
AuxXxilium
f124199acc tree: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-05 19:23:10 +01:00
AuxXxilium
831d4c6384 arc-functions: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-05 19:20:37 +01:00
AuxXxilium
48780950bd boot: init: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-05 19:10:45 +01:00
AuxXxilium
e5ad10ab09 grub/boot: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-05 18:57:16 +01:00
AuxXxilium
09f52a444e grub: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-05 18:53:21 +01:00
AuxXxilium
8997d71e0c grub: set gfx back to old
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-03 22:16:36 +01:00
AuxXxilium
7f434f374a grub: update 2024-12-03 21:05:25 2024-12-03 21:05:25 +01:00
AuxXxilium
82c9fc028a arc: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-03 20:48:31 +01:00
AuxXxilium
d55ca84ccd tree: fix more logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-02 23:46:49 +01:00
AuxXxilium
29a028ad89 func: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-02 23:29:57 +01:00
AuxXxilium
915f60710d build: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-02 23:11:35 +01:00
AuxXxilium
567aaf9733 arc: fix keymap
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-02 20:44:06 +01:00
AuxXxilium
49d8a0425c arc: update model table
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-01 20:40:48 +01:00
AuxXxilium
5338b8ecc7 tree: rewrite more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-01 19:09:57 +01:00
AuxXxilium
ad987595bb tree: rework more logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-01 18:09:26 +01:00
AuxXxilium
3049a8cf5d tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-01 17:53:50 +01:00
AuxXxilium
f6f9ed1810 arc: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-01 17:42:45 +01:00
AuxXxilium
b33d1e0013 grub: test
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-01 17:09:48 +01:00
AuxXxilium
931e5c7942 grub: set fixed resolution
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-01 16:37:23 +01:00
AuxXxilium
2c90cfd41b init: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-01 11:23:32 +01:00
AuxXxilium
bf33567af2 arc-functions: fix clone loader
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-12-01 11:12:19 +01:00
AuxXxilium
a239db84ff tree: fix automated
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-30 23:26:20 +01:00
AuxXxilium
ea0c82fd95 tree: fix more logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-30 22:12:52 +01:00
AuxXxilium
c8663b8994 boot: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-30 21:29:31 +01:00
AuxXxilium
65210543b7 tree: fix more logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-30 20:17:44 +01:00
AuxXxilium
13fa3fc771 tree: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-30 02:49:53 +01:00
AuxXxilium
f6f86334ed grub: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-29 22:45:11 +01:00
AuxXxilium
74093f29b1 init/boot: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-29 21:31:13 +01:00
AuxXxilium
466424229d tree: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-28 23:22:57 +01:00
AuxXxilium
6c31c321e6 arc: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-28 20:53:38 +01:00
AuxXxilium
1f46c8860f tree: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-28 18:03:45 +01:00
AuxXxilium
21ffcf4cd5 busybox: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-26 22:07:20 +01:00
AuxXxilium
4a94b7237f boot: fix mac
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-25 00:16:43 +01:00
AuxXxilium
8c0e316993 tree: update more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-25 00:12:14 +01:00
AuxXxilium
582292c5d1 init: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-25 00:00:09 +01:00
AuxXxilium
d87c63b870 arc: fix menu bug
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-24 23:52:35 +01:00
AuxXxilium
4be4774994 boot: add sections
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-24 23:16:09 +01:00
AuxXxilium
5f89c1d61a tree: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-24 22:56:22 +01:00
AuxXxilium
73ad75ed34 update: rewrite messages
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-24 14:00:32 +01:00
AuxXxilium
bc0c10f829 boot/grub: change intel pstate
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-24 12:55:17 +01:00
AuxXxilium
dfe6a3c534 arc: add new addon to preselection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-24 11:39:59 +01:00
AuxXxilium
75fa94aba8 Merge branch 'test' into dev
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-24 11:36:33 +01:00
AuxXxilium
8b4bdf2fc8 tree: fix syntax and logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-24 11:32:03 +01:00
AuxXxilium
16f3590843 update: fix window
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-23 23:32:04 +01:00
AuxXxilium
892c374946 tree: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-23 14:36:09 +01:00
AuxXxilium
c77d646d26 tree: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-20 20:20:45 +01:00
AuxXxilium
9323868f05 grub: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-20 20:15:15 +01:00
AuxXxilium
3555ec84ad build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-20 20:08:59 +01:00
AuxXxilium
32ffa70cb1 tree: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-20 19:54:38 +01:00
AuxXxilium
2d0dd7d7e9 tree: rework 2
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-20 13:39:15 +01:00
AuxXxilium
27493c7f4f tree: rework menu order and fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-20 12:30:57 +01:00
AuxXxilium
1021427900 grub: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-20 12:01:21 +01:00
AuxXxilium
8cb6619ae8 tree: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-20 01:29:20 +01:00
AuxXxilium
d9ebdd95d8 functions: fast fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-17 17:30:55 +01:00
AuxXxilium
902db23960 arc: add warning if arc patch failed
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-17 16:48:17 +01:00
AuxXxilium
2c2286e651 arc: don't show online functions if loader is offline
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-17 16:42:46 +01:00
AuxXxilium
d274d528bb arc: reinit loader after restore config
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-17 16:40:17 +01:00
AuxXxilium
dabbd3ff81 arc: fix restore from online
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-17 16:38:27 +01:00
AuxXxilium
b2538b24ef tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-17 16:22:53 +01:00
AuxXxilium
c4ff1ecf1e arc: remove some warnings
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-17 16:17:59 +01:00
AuxXxilium
e218db8511 arc: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-16 23:17:59 +01:00
AuxXxilium
8c22d11c49 tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-16 22:58:57 +01:00
AuxXxilium
71e7eba6f3 arc: change false message
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-16 22:42:00 +01:00
AuxXxilium
5f030c2349 tree: add some sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-16 21:53:43 +01:00
AuxXxilium
5fa2c3a1c6 arc: cleanup more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-16 20:43:46 +01:00
AuxXxilium
cf2daa9807 networkdiag: add useridapi check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-16 19:01:58 +01:00
AuxXxilium
167d909e13 arc-functions: add message for user without a brain
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-16 18:27:12 +01:00
AuxXxilium
b4ebd305bd functions: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-16 15:45:11 +01:00
AuxXxilium
f4bbb7c5bb tree: rework more logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-16 11:31:31 +01:00
AuxXxilium
390f5b11db tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-16 10:42:03 +01:00
AuxXxilium
8bc3393d55 functions: move to correct file
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-16 00:35:56 +01:00
AuxXxilium
cee2d7d263 tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-15 15:46:33 +01:00
AuxXxilium
ab508a9eb5 arc-functions: rename update function
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-15 15:35:27 +01:00
AuxXxilium
16a73afe9d arc-functions: more logic fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-15 15:25:43 +01:00
AuxXxilium
c4cc0b779a arc-functions: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-15 14:57:03 +01:00
AuxXxilium
601547d9db arc-functions: more work
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-15 14:16:47 +01:00
AuxXxilium
a68b5d446e functions: fix hwid for multiple nic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-15 14:08:09 +01:00
AuxXxilium
3ccb91be9f arc-functions: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-14 20:42:40 +01:00
AuxXxilium
3e010b781a arc: fix copy
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-13 23:53:11 +01:00
AuxXxilium
dcd86a4272 build: fix local
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-13 23:43:24 +01:00
AuxXxilium
c287e33aab arc: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-13 18:55:07 +01:00
AuxXxilium
95c1eb6897 tree: rework more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-13 18:05:58 +01:00
AuxXxilium
fb183e437e build: fix local
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-13 17:23:09 +01:00
AuxXxilium
efca3aaf6d arc-functions: rework id check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-13 01:20:37 +01:00
AuxXxilium
46ec4215d7 arc-functions: fix loop
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-13 00:32:59 +01:00
AuxXxilium
f44a142d01 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-12 17:02:13 +01:00
AuxXxilium
b036a2aef2 build: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-12 16:51:19 +01:00
AuxXxilium
afb22a6321 functions: more...
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-12 16:11:05 +01:00
AuxXxilium
fb938806a2 functions: finalize hwid
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-12 16:02:28 +01:00
AuxXxilium
1bde43ca66 functions: make hwid unique
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-11 21:42:40 +01:00
AuxXxilium
d890c54a1b arc: add more features for online
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-11 21:05:07 +01:00
AuxXxilium
d876d274d4 functions: add new
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-11 18:54:25 +01:00
AuxXxilium
24d9ed7bb3 arc-functions: make hwid unique
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-10 18:44:21 +01:00
AuxXxilium
1d04d3f59f arc: more logic rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-10 18:24:04 +01:00
AuxXxilium
78f5455b69 arc: more ...
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-10 17:39:26 +01:00
AuxXxilium
81d72a0800 arc: next step
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-10 17:16:46 +01:00
AuxXxilium
73ec652bd0 boot: fix boot message
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-10 12:56:32 +01:00
AuxXxilium
bbc9904b3e build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-10 11:09:53 +01:00
AuxXxilium
2bc754c9a1 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-10 00:56:17 +01:00
AuxXxilium
f50bb9cc46 arc-functions: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-10 00:16:03 +01:00
AuxXxilium
8de9970341 ramdisk: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-09 23:58:14 +01:00
AuxXxilium
1245ca4f4a arc-functions: add missing spaces
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-09 23:46:01 +01:00
AuxXxilium
10a5a18abb arc-function: set defaults for latest changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-09 21:59:11 +01:00
AuxXxilium
51eea40ea7 boot: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-09 21:33:18 +01:00
AuxXxilium
2b13648cc4 arc-functions: more work
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-09 21:17:57 +01:00
AuxXxilium
6b315e08ad arc-functions: rework sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-09 21:16:12 +01:00
AuxXxilium
fe642ebec2 build: update 2
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-09 17:59:57 +01:00
AuxXxilium
bc43cdaeb7 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-09 17:43:20 +01:00
AuxXxilium
0966a2b783 boot: logic fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-09 17:30:02 +01:00
AuxXxilium
4c5bfbe695 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-09 13:45:54 +01:00
AuxXxilium
623271fc6c build: include dependencies in release
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-09 12:26:52 +01:00
AuxXxilium
3df2339e63 arc: fix latest
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-08 20:31:40 +01:00
AuxXxilium
323c266812 init/boot: add arc_build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-08 19:57:07 +01:00
AuxXxilium
a5055dbaf4 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-08 19:44:29 +01:00
AuxXxilium
d9c71d453a tree: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-08 19:10:03 +01:00
AuxXxilium
474b8bbe03 arc-functions: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-03 17:19:16 +01:00
AuxXxilium
c45d52459d arc-functions: fix typos
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-03 13:25:13 +01:00
AuxXxilium
1ec1f7ffb9 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-02 18:56:39 +01:00
AuxXxilium
3777d2c952 arc-functions: add back branch switch to update menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-02 14:53:49 +01:00
AuxXxilium
bd868c6142 arc: rewrite more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-02 14:35:39 +01:00
AuxXxilium
62bf4259b9 arc: rework some menu things
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-02 14:20:09 +01:00
AuxXxilium
bcc7a7f6c1 addons: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-02 01:10:01 +01:00
AuxXxilium
8f6a18f6dd functions: remove unused
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-01 15:55:34 +01:00
AuxXxilium
d48a970cd8 arc: rework ui
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-01 14:23:45 +01:00
AuxXxilium
39f119c123 arc: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-11-01 11:44:57 +01:00
AuxXxilium
cc429e4ea5 tree: remove usage of syno api
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 22:03:59 +01:00
AuxXxilium
7da081d887 update: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 12:57:57 +01:00
AuxXxilium
73e9eae212 addons: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 12:43:04 +01:00
AuxXxilium
e72a8586cf arc: optimize changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 12:36:10 +01:00
AuxXxilium
d9650981f7 arc-functions: typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 12:29:03 +01:00
AuxXxilium
4cced72bbb arc: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 12:27:42 +01:00
AuxXxilium
bbc7e9046d arc: try something new
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 11:47:16 +01:00
AuxXxilium
e512310055 functions: add logic check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 11:26:00 +01:00
AuxXxilium
d44f741887 consts: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 11:19:21 +01:00
AuxXxilium
f6e88b135b update: rewrite logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 11:19:10 +01:00
AuxXxilium
8e2794c1bf update: add backup logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 10:56:49 +01:00
AuxXxilium
843fa0aa30 functions: optimize logic for online check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 10:52:53 +01:00
AuxXxilium
99bb6937eb arc: rewrite more api related
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 02:04:12 +01:00
AuxXxilium
7a5932fea5 arc: reduce api calls and rewrite offline mode
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-31 01:48:27 +01:00
AuxXxilium
ccfbd4c15c tree: rework update functions
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-30 20:53:35 +01:00
AuxXxilium
e7994e5cd2 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-30 20:02:17 +01:00
AuxXxilium
3295073c99 tree: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-30 19:56:11 +01:00
AuxXxilium
b6c0b24b70 tree: fix VMM issue on epyc7002
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-29 16:57:50 +01:00
AuxXxilium
998bdceba7 arc: more rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-27 23:04:48 +01:00
AuxXxilium
ae0f6a30fe arc: rewrite more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-27 21:26:45 +01:00
AuxXxilium
465b147960 tree: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-27 21:16:55 +01:00
AuxXxilium
a4da6be93b arc: fix reset loader
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-27 18:58:56 +01:00
AuxXxilium
d6a5443593 addons: remove online addons if arc is offline
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-27 18:39:05 +01:00
AuxXxilium
4ba2e6baa6 tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-27 18:33:41 +01:00
AuxXxilium
962645bb9e arc: add check for cpufreqscaling
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-27 18:33:20 +01:00
AuxXxilium
6dfce5cc1b arc: add offline check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-27 18:30:22 +01:00
AuxXxilium
39b95a840a arc: rework update way
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-26 20:15:57 +02:00
AuxXxilium
e3b850ecb0 arc-functions: changes for upcoming
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-26 13:02:18 +02:00
AuxXxilium
fb9d67881d arc: expand sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-26 12:59:40 +02:00
AuxXxilium
bf8d488eb9 arc: fix config restore
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-26 12:41:02 +02:00
AuxXxilium
877feba5cb arc: remove dependencies for cpufreqscaling
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-26 11:36:56 +02:00
AuxXxilium
bb8c74e9ac arc: fix patch reset while read models
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-26 11:29:06 +02:00
AuxXxilium
25dc3115b6 grub: update 2024-10-25 20:29:10 2024-10-25 22:15:07 +02:00
AuxXxilium
3cdc3c874c tree: fix more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 22:14:52 +02:00
AuxXxilium
bce7d47e4a grub: shrink partition 2
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 20:20:11 +02:00
AuxXxilium
1d13466f83 grub: update 2024-10-25 20:09:50 2024-10-25 20:16:13 +02:00
AuxXxilium
ddd7e2ccef functions: fix sortnetif for arc
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 20:15:58 +02:00
AuxXxilium
5b40850fe0 functions: fix .dev version check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 20:07:08 +02:00
AuxXxilium
8810cd128d grub: shrink loader to 1G
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 20:00:46 +02:00
AuxXxilium
1c0f3a4c06 compat: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 19:56:02 +02:00
AuxXxilium
2594a8a599 tree: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 19:55:21 +02:00
AuxXxilium
138d683318 boot: add option to customize
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 19:43:54 +02:00
AuxXxilium
3f916ce79e tree: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 18:32:23 +02:00
AuxXxilium
96e0679adb tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 18:20:04 +02:00
AuxXxilium
293f266842 tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 16:05:39 +02:00
AuxXxilium
7ea1888c93 arc-functions: rework addons
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 15:16:52 +02:00
AuxXxilium
905131ae8e Revert "init: remove sortnetif for now"
This reverts commit 9e482783f0.
2024-10-25 14:49:37 +02:00
AuxXxilium
4d47d4dfb3 functions: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 14:48:01 +02:00
AuxXxilium
0f64c0ed80 arc: fix sn/mac stuff
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 14:45:13 +02:00
AuxXxilium
56d9c038a4 tree: syntax fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 14:32:32 +02:00
AuxXxilium
91babd9162 functions: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 14:12:48 +02:00
AuxXxilium
a03f4fcada build: update local stable
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 14:12:14 +02:00
AuxXxilium
326c92acc5 build: update local next
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 14:12:14 +02:00
AuxXxilium
4ddaaf7584 build: update build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 14:12:14 +02:00
AuxXxilium
5c45588bf8 build: update autobuild
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 14:12:14 +02:00
AuxXxilium
9e482783f0 init: remove sortnetif for now
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-25 14:11:55 +02:00
AuxXxilium
290ef7e65a build: remove ova from autobuild
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 23:42:39 +02:00
AuxXxilium
1830fa3220 build: fix autobuild
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 23:36:06 +02:00
AuxXxilium
fd7c7508b0 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 20:17:24 +02:00
AuxXxilium
57a8b7ccb5 arc: rewrite message
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 20:12:13 +02:00
AuxXxilium
1fadffe0c7 build: update dev build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 19:33:20 +02:00
AuxXxilium
678cc34e09 update: rewrite version after update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 19:28:44 +02:00
AuxXxilium
db5776871e build: update dev build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 19:23:24 +02:00
AuxXxilium
f0d61394a0 grub: update 2024-10-24 19:21:21 2024-10-24 19:21:42 +02:00
AuxXxilium
2ab92748a1 arc-functions: update credits
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 19:21:22 +02:00
AuxXxilium
65d18c8792 tree: modify more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 19:18:05 +02:00
AuxXxilium
4250b5341b arc-functions: change grub img path
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 19:10:52 +02:00
AuxXxilium
e03df2dbab build: update local build files
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 19:08:56 +02:00
AuxXxilium
064c9fe84b grub: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 19:06:29 +02:00
AuxXxilium
8dcf836a69 tree: merge latest changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 19:05:24 +02:00
AuxXxilium
dc80125b75 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-24 18:59:15 +02:00
AuxXxilium
120e70c3b0 Merge pull request #3892 from AuxXxilium/dev
tree: fix syntax
2024-10-02 22:58:26 +02:00
AuxXxilium
dba67f8d42 tree: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-02 22:57:56 +02:00
AuxXxilium
a5aaa8bf6e Merge pull request #3891 from AuxXxilium/dev
Dev
2024-10-02 22:54:29 +02:00
AuxXxilium
7bc8857fb0 arc: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-02 22:02:59 +02:00
AuxXxilium
103c99d291 arc/update: remove "dev" from update versions
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-02 21:15:20 +02:00
AuxXxilium
d285ed08d0 Merge pull request #3870 from AuxXxilium/dev
Dev
2024-10-01 21:21:33 +02:00
AuxXxilium
f14b7e3308 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-01 21:21:01 +02:00
AuxXxilium
043401f478 modulelist: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-01 21:19:44 +02:00
AuxXxilium
440b84be18 Merge pull request #3869 from AuxXxilium/dev
Dev
2024-10-01 21:15:08 +02:00
AuxXxilium
8fac73a1d7 arc: move ram amount write to build step
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-01 21:02:34 +02:00
AuxXxilium
44316e5083 arc-functions: add sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-01 20:51:44 +02:00
AuxXxilium
cb3611b88a arc-functions: remove advanced update features
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-01 20:49:55 +02:00
AuxXxilium
07112560e4 tree: add sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-10-01 20:25:51 +02:00
AuxXxilium
ff4298c305 Merge pull request #3823 from AuxXxilium/dev
Dev
2024-09-29 18:44:41 +02:00
AuxXxilium
1462a53e6a arc-functions: fix warning
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 18:39:47 +02:00
AuxXxilium
94c1c901c2 tree: rewrite more syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 18:37:19 +02:00
AuxXxilium
2fbfef5178 restore: rewrite logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 18:32:51 +02:00
AuxXxilium
c72a0fd713 restore: check modules tree
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 18:24:38 +02:00
AuxXxilium
d92244ff77 arc: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 18:19:36 +02:00
AuxXxilium
0c7a1a3c75 arc: fix sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 16:41:23 +02:00
AuxXxilium
132245fe80 arc: fix build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 16:31:15 +02:00
AuxXxilium
2395316403 arc: rewrite more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 16:19:17 +02:00
AuxXxilium
6327553181 arc: add sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 16:12:19 +02:00
AuxXxilium
ab9c19968b arc-functions: fix password reset
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 15:59:32 +02:00
AuxXxilium
9448e3f298 tree: cleanup and rewrite logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 15:45:49 +02:00
AuxXxilium
8a1ea9bd53 tree: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 15:15:02 +02:00
AuxXxilium
dee1244b7d arc: add back ipv6 switch 2024-09-29 11:47:35 +02:00
AuxXxilium
2b2ded937c update: more rewrites
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-29 11:37:09 +02:00
AuxXxilium
1cec4f728f build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-28 01:31:55 +02:00
AuxXxilium
04990a0fb8 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-27 22:05:59 +02:00
AuxXxilium
831538f7f9 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-27 21:44:02 +02:00
AuxXxilium
3066ce8cac arc-functions: change addon selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-27 21:40:38 +02:00
AuxXxilium
c701d2e0c6 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-27 21:30:19 +02:00
AuxXxilium
f3f2a0bce5 sysinfo: fix gpu name
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-27 21:04:54 +02:00
AuxXxilium
efc4a116a2 Merge pull request #3791 from AuxXxilium/dev
tree: rework loader update
2024-09-27 20:52:31 +02:00
AuxXxilium
c1bdea0e57 tree: rework loader update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-27 20:52:14 +02:00
AuxXxilium
4c9b3d353c Merge pull request #3725 from AuxXxilium/dev
build: update
2024-09-24 23:42:59 +02:00
AuxXxilium
fd08eef485 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-24 23:24:41 +02:00
AuxXxilium
508d5b2962 Merge pull request #3697 from AuxXxilium/dev
tree: some rewrite
2024-09-23 21:16:19 +02:00
AuxXxilium
0b6a20fda0 tree: some rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-23 20:43:36 +02:00
AuxXxilium
7f666e643e Merge pull request #3669 from AuxXxilium/dev
Dev
2024-09-22 16:19:33 +02:00
AuxXxilium
eab68b37ee arc: add sanity check for latest changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-21 15:27:56 +02:00
AuxXxilium
270ecd019e arc: rework latest changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-21 15:24:54 +02:00
AuxXxilium
34c4adb14d grub: shrink image to 1536MB
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-21 13:01:14 +02:00
AuxXxilium
90df8f1848 update: use cp instead of mv
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-21 13:00:52 +02:00
AuxXxilium
c1299a469d tree: more rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-21 12:52:23 +02:00
AuxXxilium
76730b1063 tree: rewrite more addon related
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-21 11:54:58 +02:00
AuxXxilium
e42305bc48 tree: update addons selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-21 11:22:52 +02:00
AuxXxilium
62f01f4e1b Merge pull request #3641 from AuxXxilium/dev
Dev
2024-09-20 23:35:01 +02:00
AuxXxilium
d9b3367a8a update: fix addons update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-20 19:47:29 +02:00
AuxXxilium
b9860d0adf functions: disable time write to bios
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-20 13:39:23 +02:00
AuxXxilium
7285be06cb Revert "grub: shrink image to 1.5gb"
This reverts commit ee7200e189.
2024-09-20 13:24:05 +02:00
AuxXxilium
def8fa1799 Revert "grub: update 2024-09-19 18:09:28"
This reverts commit 46f2e6d576.
2024-09-20 13:24:05 +02:00
AuxXxilium
41ac923127 grub: add more modules
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-19 23:10:52 +02:00
AuxXxilium
100526b0b0 arc: rewrite function
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-19 22:32:45 +02:00
AuxXxilium
46f2e6d576 grub: update 2024-09-19 18:09:28 2024-09-19 21:09:35 +02:00
AuxXxilium
93c039b7c2 tree: readd something old
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-19 21:09:25 +02:00
AuxXxilium
ee7200e189 grub: shrink image to 1.5gb
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-19 17:54:52 +02:00
AuxXxilium
b4ede7e2c4 arc/arc-functions: add back acpi check for more clearification
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-19 17:06:50 +02:00
AuxXxilium
d299f0b6b6 Merge pull request #3577 from AuxXxilium/dev
build: cleanup
2024-09-17 20:52:25 +02:00
AuxXxilium
16c6e677c2 build: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-17 20:29:06 +02:00
AuxXxilium
802b28587c Merge pull request #3576 from AuxXxilium/dev
build: update
2024-09-17 19:57:24 +02:00
AuxXxilium
786f6fc49b build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-17 19:57:05 +02:00
AuxXxilium
11cbf15da1 Merge pull request #3573 from AuxXxilium/dev
Dev
2024-09-17 19:38:54 +02:00
AuxXxilium
20d65f42e9 tree: fix more syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-17 18:56:39 +02:00
AuxXxilium
430f31edcc tree: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-17 18:48:05 +02:00
AuxXxilium
2729ea0f43 tree: rework static ip
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-15 00:13:25 +02:00
AuxXxilium
acdcd2c63c arc-functions: read correct mac for IP
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-14 20:52:23 +02:00
AuxXxilium
8ccf7d39fd arc-functions: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-14 18:14:36 +02:00
AuxXxilium
3ef298098b arc-functions: rework addon selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-14 17:44:55 +02:00
AuxXxilium
9234501099 arc: rework backup build logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-11 18:55:51 +02:00
AuxXxilium
561482b14a arc: rewrite description
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-10 21:12:39 +02:00
AuxXxilium
686b894e91 tree: rework functions
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-10 21:01:43 +02:00
AuxXxilium
9ee2b6cc23 boot: cleanup (speedup boot - time reading has no sense here, time will be read by dsm at boot)
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-10 20:22:21 +02:00
AuxXxilium
63d3816464 boot: rewrite for non rtc compatible systems
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-10 20:01:15 +02:00
AuxXxilium
7e595e828c arc: move static ip to loader options
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-09 23:29:17 +02:00
AuxXxilium
748eed9e1f boot: change back to reboot to dsm instead of booting dsm directly
(better for hardware initialization)

Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-09 22:55:40 +02:00
AuxXxilium
250e809fe2 compatboot: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-09 19:12:27 +02:00
AuxXxilium
812a5d95f1 arc: enable compatboot
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-08 19:09:36 +02:00
AuxXxilium
73aa58b38b tree: call ntp earlier
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-08 18:50:45 +02:00
AuxXxilium
9d3293f91a tree: fix more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-08 12:44:42 +02:00
AuxXxilium
51ffa84ffb tree: move function
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-08 11:25:29 +02:00
AuxXxilium
f507020948 functions: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-07 21:17:23 +02:00
AuxXxilium
4343d7fd94 sysinfo: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-07 21:15:20 +02:00
AuxXxilium
b436eed058 boot: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-07 17:36:30 +02:00
AuxXxilium
091f0aa722 arc: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-07 12:54:21 +02:00
AuxXxilium
5b917907ca arc: more logic rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-07 12:51:26 +02:00
AuxXxilium
36ecfa5ca2 update: don't clean arc key
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-07 12:47:29 +02:00
AuxXxilium
f6a7c0729e tree: rewrite more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-07 12:38:00 +02:00
AuxXxilium
3429d54d51 tree: fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-06 23:04:26 +02:00
AuxXxilium
d9c9042099 tree: show timezone/region to user
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-06 20:44:01 +02:00
AuxXxilium
54d5ba40dd functions: don't set region/timezone only locally
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-06 20:40:10 +02:00
AuxXxilium
028b30c24e arc: add asking for automated build after model/version
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-06 20:33:50 +02:00
AuxXxilium
29a5a54f7e boot: remove ntp from boot
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-06 17:32:51 +02:00
AuxXxilium
97431a6a3b arc: rewrite more logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-06 17:31:44 +02:00
AuxXxilium
bd0e53bb7f arc: rename backup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 23:48:37 +02:00
AuxXxilium
74d88856f7 arc: rewrite update menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 23:39:54 +02:00
AuxXxilium
747b0fca36 arc: add space to sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 23:29:04 +02:00
AuxXxilium
261fbae2af arc: more rewrite for time
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 23:27:53 +02:00
AuxXxilium
949ab7fe2e arc: rewrite timezone/region check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 22:36:30 +02:00
AuxXxilium
3fba97c0c9 arc/boot: format data output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 21:10:55 +02:00
AuxXxilium
9842d5de61 build: update local build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 21:04:28 +02:00
AuxXxilium
84e63a1ac8 arc: menu change description
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 20:59:04 +02:00
AuxXxilium
5f6b18a216 arc: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 20:50:31 +02:00
AuxXxilium
3911aab34b arc: fix network
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 19:23:58 +02:00
AuxXxilium
e461f25cf7 arc: force copy files while build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 17:54:10 +02:00
AuxXxilium
bf7c53bc4d tree: fix branch system
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 17:36:39 +02:00
AuxXxilium
98c5a6ed95 ramdisk: remove updatenotify from system addons
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 17:24:31 +02:00
AuxXxilium
4193c5e867 tree: some fixes and debug
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-05 16:46:21 +02:00
AuxXxilium
53520f89fd arc: fix logic in update menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-04 19:43:15 +02:00
AuxXxilium
3e659f4745 arc: add more sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-04 18:23:37 +02:00
AuxXxilium
70c198c157 arc: fix more logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-04 18:10:35 +02:00
AuxXxilium
0faa83d778 arc: fix offline (non automated) build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-04 18:00:04 +02:00
AuxXxilium
b7cd95454a custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 09:38:42 -04:00
AuxXxilium
d3bf99a0b3 custom: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 09:28:38 -04:00
AuxXxilium
7f03145d85 custom: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 09:25:49 -04:00
AuxXxilium
dcc9dd73d1 custom: add missing
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 09:19:22 -04:00
AuxXxilium
52c499866c custom: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 09:16:35 -04:00
AuxXxilium
2b30628d4c custom: add missing
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 09:16:18 -04:00
AuxXxilium
5d1801cfcd custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 09:10:52 -04:00
AuxXxilium
65f5ebc371 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 08:56:25 -04:00
AuxXxilium
f9911d15fc build: update custom
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 08:45:56 -04:00
AuxXxilium
ca8e8eba0e update: add more sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 05:59:25 -04:00
AuxXxilium
5f6fe509b7 build: set min version to 24.09.01
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 05:49:02 -04:00
AuxXxilium
9fbf06d4eb boot: add space between version and build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 05:37:48 -04:00
AuxXxilium
a8e3728088 arc: rewrite text
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 05:28:29 -04:00
AuxXxilium
f6926e686c arc: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 05:20:51 -04:00
AuxXxilium
19a6d05786 arc: remove warning
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 04:27:01 -04:00
AuxXxilium
4cf514f97d build: fix local versions
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 04:25:11 -04:00
AuxXxilium
ac38020ce7 arc: move primary nic to loader options
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 04:23:37 -04:00
AuxXxilium
5d9022e916 update: add update inside development mode
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-09-01 04:18:07 -04:00
AuxXxilium
eb48f87f3a ramdisk: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-31 14:13:28 -04:00
AuxXxilium
45f5b80850 arc: update logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-31 13:39:45 -04:00
AuxXxilium
e9819fee80 arc: cleanup old files
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-31 09:41:11 +02:00
AuxXxilium
8d3479a524 arc: fix more logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-31 09:35:40 +02:00
AuxXxilium
0526fc732a arc: add url sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-30 22:20:31 +02:00
AuxXxilium
60f9bcf768 tree: rework more logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-30 19:58:32 +02:00
AuxXxilium
e339aad9e2 arc: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-30 19:34:10 +02:00
AuxXxilium
b953d57c54 arc: fix latest
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-30 15:38:12 +02:00
AuxXxilium
fcddafcdf7 arc: fix logix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-29 20:22:07 +02:00
AuxXxilium
c5967c3646 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-29 20:20:00 +02:00
AuxXxilium
d0e85c0202 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-29 20:17:30 +02:00
AuxXxilium
a7cb8a4a5f custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-29 20:13:10 +02:00
AuxXxilium
874d14b948 arc: more rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-29 19:38:14 +02:00
AuxXxilium
87e9682a1e build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-29 18:01:21 +02:00
AuxXxilium
567dca7f8d arc-functions: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-29 17:40:31 +02:00
AuxXxilium
3c38310164 functions: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-29 17:40:20 +02:00
AuxXxilium
0775acd417 arc: rewrite build code
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-29 00:18:06 +02:00
AuxXxilium
7ca13eaf89 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-28 23:02:48 +02:00
AuxXxilium
d0cbc386af arc: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-28 22:15:33 +02:00
AuxXxilium
d6e7da9af8 tree: rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-28 22:06:56 +02:00
AuxXxilium
e085595bf6 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 22:43:34 +02:00
AuxXxilium
a759b65cb5 tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 22:40:00 +02:00
AuxXxilium
bf2c728c6d arc: if system has only nvme disks, show only SA6400
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 22:26:38 +02:00
AuxXxilium
bf792503b6 custom: remove modules from selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 15:41:56 -04:00
AuxXxilium
f530b22232 arc: change menu ordering
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 15:21:25 -04:00
AuxXxilium
862b812a7d arc: force confdone true if builddone is true
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 15:10:20 -04:00
AuxXxilium
a0fb758acb arc: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 14:52:23 -04:00
AuxXxilium
4c81cfdedd arc: simplify code
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 14:47:40 -04:00
AuxXxilium
8608b0695c arc: rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 14:45:37 -04:00
AuxXxilium
7684075e86 arc: fix build logic if model is changed
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 14:19:43 -04:00
AuxXxilium
863ca11c16 tree: simplify code and add sanity check for paturl
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 14:15:50 -04:00
AuxXxilium
f77a3b851c arc-functions: format decrypt menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 12:49:58 -04:00
AuxXxilium
9425e0773f boot: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 12:41:21 -04:00
AuxXxilium
8c8a282dc4 arc/arc-functions: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 12:23:02 -04:00
AuxXxilium
814fda8991 update: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-27 11:35:13 -04:00
AuxXxilium
ac792bedba boot: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-26 16:42:36 -04:00
AuxXxilium
ff2b282a09 boot: add correct version output to boot screen
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-26 15:27:47 -04:00
AuxXxilium
ffe51043d4 tree: rewrite more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-26 15:12:51 -04:00
AuxXxilium
9e34bc70f3 arc: remove custom kernel if 7.2.2 is selected
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-26 14:29:26 -04:00
AuxXxilium
9f2485ad00 arc: rework more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-26 14:22:24 -04:00
AuxXxilium
d6609e191c tree: more formatting
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-26 12:54:51 -04:00
AuxXxilium
7d7d719e2d tree: rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-26 12:47:54 -04:00
AuxXxilium
0595c78aa2 tree: fix offline file
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-26 12:31:52 -04:00
AuxXxilium
1a81e2d204 functions: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-26 12:25:59 -04:00
AuxXxilium
9a15f8208d tree: workaround
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-26 12:14:23 -04:00
AuxXxilium
b612c541ab arc: format warnings
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-26 11:44:50 -04:00
AuxXxilium
4542fd4ff9 arc: temp workaround part 1
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-26 11:27:53 -04:00
AuxXxilium
82e403e69c arc: check for cpufreqscaling addon
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 18:39:41 +02:00
AuxXxilium
5e7e62b9d5 arc: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 17:10:17 +02:00
AuxXxilium
b524a95ea6 tree: rewrite more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 17:06:49 +02:00
AuxXxilium
cc5ecd61c5 tree: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 16:46:10 +02:00
AuxXxilium
23187955dc tree: more fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 16:17:32 +02:00
AuxXxilium
37bef42f65 arc: rewrite build logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 14:38:02 +02:00
AuxXxilium
0b337ad600 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 13:58:48 +02:00
AuxXxilium
3a455c57ff arc-functions: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 10:58:56 +02:00
AuxXxilium
f6abf4d9c0 arc-functions: a bit more styling
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 10:57:17 +02:00
AuxXxilium
ed37720151 arc-functions: update menu rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 10:50:13 +02:00
AuxXxilium
271fb2e6e8 arc-functions: ask for reboot after loader update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 10:30:08 +02:00
AuxXxilium
3d67eea1b2 arc-functions: fix rebootMenu message style
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 10:27:10 +02:00
AuxXxilium
96326a3272 arc-functions: updateMenu fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-25 10:25:18 +02:00
AuxXxilium
ce386c049c init: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-24 21:28:48 +02:00
AuxXxilium
0423c1611e custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-24 21:19:48 +02:00
AuxXxilium
d58d1f5b0c tree: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-24 21:03:24 +02:00
AuxXxilium
daec6b60fd build: fix local build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-24 20:42:10 +02:00
AuxXxilium
18f42509ae arc: reorder menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-24 20:26:30 +02:00
AuxXxilium
1e1b41b1d9 arc: fix menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-24 20:17:30 +02:00
AuxXxilium
38558d4452 arc-functions: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-24 19:56:06 +02:00
AuxXxilium
646d7cef38 arc-functions: add something new
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-24 19:46:22 +02:00
AuxXxilium
8949e723d3 arc-functions: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-24 14:26:13 +02:00
AuxXxilium
5d05cdff10 arc: rework branch system
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-24 00:25:41 +02:00
AuxXxilium
8f4a9b698e arc: fix arckey value
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-23 00:34:04 +02:00
AuxXxilium
5daa656d46 arc-functions: add synoinfo for ssd cache
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-23 00:29:53 +02:00
AuxXxilium
7d9f7817af tree: fix arc patch after update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-23 00:21:08 +02:00
AuxXxilium
934b9e8fba ramdisk: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-21 23:28:24 +02:00
AuxXxilium
0c27c8d5a8 build: update 2024-08-21 18:55:20 +02:00
AuxXxilium
09148a05d3 functions: fix syntax 2024-08-21 18:55:16 +02:00
AuxXxilium
0b229c3fe9 init: fix nic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-21 18:54:56 +02:00
AuxXxilium
b46767e423 ramdisk: syntaxfix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-19 23:41:26 +02:00
AuxXxilium
f568b62685 tree: some more rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-19 21:18:23 +02:00
AuxXxilium
668c38f833 modulelist: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-19 20:51:30 +02:00
AuxXxilium
9c52d811ed arc: fix false inputed user SN
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-19 20:47:35 +02:00
AuxXxilium
84f33ed659 init: rework blacklist
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-19 18:39:18 +02:00
AuxXxilium
f8f8950799 arc: remove geoblocking for now <- until the next ... comes around
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-19 18:26:23 +02:00
AuxXxilium
b991c9d7f7 tree: try something
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-18 23:24:34 +02:00
AuxXxilium
d053c824e2 arc: fix branch selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-18 18:07:46 +02:00
AuxXxilium
91e895ac9f arc: fix module selection for custom builds
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-18 16:04:26 +02:00
AuxXxilium
a8834e0c1c functions: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-18 12:06:42 +02:00
AuxXxilium
c0a28c3efe custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-18 03:05:54 +02:00
AuxXxilium
19e5d34378 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-18 02:01:13 +02:00
AuxXxilium
f10ceade71 build: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-18 01:48:11 +02:00
AuxXxilium
06f4e05de4 tree: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-18 01:40:13 +02:00
AuxXxilium
eb74f7bfed arc: update make code
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-17 21:44:50 +02:00
AuxXxilium
345fc9a106 Revert "arc-functions: do some more work"
This reverts commit 9b99315c02.
2024-08-17 19:27:14 +02:00
AuxXxilium
9b99315c02 arc-functions: do some more work
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-17 19:10:05 +02:00
AuxXxilium
2bd5354f75 block: remove es from geoblocking
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-17 18:40:04 +02:00
AuxXxilium
0f3c6c4092 arc: decrypt rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-17 17:38:23 +02:00
AuxXxilium
2b4f06496e block: spain also from usage
(spainish user can say thanks to apriliars3 / Miguel Angel)

Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-17 17:20:56 +02:00
AuxXxilium
40cb99762c boot: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-17 16:22:22 +02:00
AuxXxilium
6124e562c5 boot: more fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-17 15:55:04 +02:00
AuxXxilium
149db87a0c boot: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-17 15:47:14 +02:00
AuxXxilium
6640aa1f52 functions: add region block
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-17 00:21:04 +02:00
AuxXxilium
8e0eebf817 boot: fix pvscsi
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-16 23:57:41 +02:00
AuxXxilium
4dd6a0b6bc functions: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-16 23:57:26 +02:00
AuxXxilium
b36aafd7e4 ramdisk: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-16 23:57:09 +02:00
AuxXxilium
b30456aa91 compat: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-16 23:56:55 +02:00
AuxXxilium
bfae54a8b5 build: fix branch
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-16 15:47:38 +02:00
AuxXxilium
3d9c6043bf build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-15 21:12:07 +02:00
AuxXxilium
519026cf2d functions: update 2024-08-15 12:56:18 +02:00
AuxXxilium
68a996c776 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-14 21:30:23 +02:00
AuxXxilium
7eff59a8cf build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-14 20:14:47 +02:00
AuxXxilium
03f5ce953e tree: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-14 20:05:37 +02:00
AuxXxilium
14925c2cf5 arc: remove arc patch from image
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-14 19:15:01 +02:00
AuxXxilium
41d9b805bf build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-14 19:14:23 +02:00
AuxXxilium
c7d29e79ba update: fix output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-14 19:14:14 +02:00
AuxXxilium
4f981aea94 ramdisk: fix 2024-08-14 12:25:47 +02:00
AuxXxilium
8f5a1042a9 build: fix clean
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-14 10:45:50 +02:00
AuxXxilium
d2f4bcf7d7 tree: some fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-13 19:47:32 +02:00
AuxXxilium
e8b7e4ca28 tree: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-11 17:02:06 +02:00
AuxXxilium
72ac648ad2 arc: remove force addons
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-10 23:51:12 +02:00
AuxXxilium
26fba39441 tree: fix boot and other functions
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-09 16:00:41 +02:00
AuxXxilium
e9dc78b35d build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-08 15:17:01 +02:00
AuxXxilium
77806ea713 update: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-08 15:14:44 +02:00
AuxXxilium
bdf28ff2a8 arc-functions: fix branch selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-08 14:47:40 +02:00
AuxXxilium
cce41aa9d4 readme: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-08 13:52:58 +02:00
AuxXxilium
1cb8bf76f1 tree: fix proxmox/unraid boot issue
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-08 13:48:38 +02:00
AuxXxilium
abac77944a build: add all function
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-08 13:41:22 +02:00
AuxXxilium
2947e57497 build: fix local
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-08 13:37:44 +02:00
AuxXxilium
23d56ece85 build: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-07 20:34:00 +02:00
AuxXxilium
f0de26f9b0 arc-functions: fix format/clone
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-07 19:49:29 +02:00
AuxXxilium
fa1f8e8420 tree: fix typos
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-07 17:08:13 +02:00
AuxXxilium
0fecccf852 build: fix local
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-06 23:37:35 +02:00
AuxXxilium
5d35673184 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-06 22:58:23 +02:00
AuxXxilium
63d2573f2c tree: fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-06 21:01:04 +02:00
AuxXxilium
498da3d502 grub: disable aspm again
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-06 14:15:48 +02:00
AuxXxilium
147acc3f57 arc-functions: change sysinfo ordering
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-06 13:53:13 +02:00
AuxXxilium
1ddad28dea arc-functions: remove sysinfo line if empty
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-06 13:51:02 +02:00
AuxXxilium
2bfced0ca8 tree: rewrite versions and build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-06 13:03:04 +02:00
AuxXxilium
b04c40c23c arc: if nondt and portmap user selected, check for config values
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-04 14:32:18 +02:00
AuxXxilium
90065f509f update: fix fullupgrade for "s" version
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 21:42:49 +02:00
AuxXxilium
cbb55ac160 grub: back to old cmdline (need more checks)
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 15:52:47 +02:00
AuxXxilium
b09f30f399 boot: add warning if connection IP isn't found
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 15:39:01 +02:00
AuxXxilium
e07b053226 boot: enable latest kexec related changes only if kexec is enabled
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 15:36:36 +02:00
AuxXxilium
3d2874b2be arc: expand dynamic mode
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 14:16:55 +02:00
AuxXxilium
8a9c7d44b7 arc-functions: rewrite power menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 14:07:38 +02:00
AuxXxilium
45001d77c3 arc-functions: silent efibootmgr
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 14:06:04 +02:00
AuxXxilium
f4bc5be100 tree: more fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 14:03:10 +02:00
AuxXxilium
8c81d06b7c functions: call exec
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 13:36:30 +02:00
AuxXxilium
a8e0a80349 boot: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 13:34:27 +02:00
AuxXxilium
50ec2de0b6 arc: rewrite message
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 13:31:42 +02:00
AuxXxilium
374c165ee1 arc: rework dynamic mode to dev branch
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 13:30:04 +02:00
AuxXxilium
4f0f912de7 functions: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 13:17:50 +02:00
AuxXxilium
afcd73a659 tree: more rewrite for dynamic mode
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 13:05:27 +02:00
AuxXxilium
f1ee8042dd arc: fix dynmic path
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 12:58:53 +02:00
AuxXxilium
88e4a250db arc-functions: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 12:57:45 +02:00
AuxXxilium
145adabcaf arc: show warning in red
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 12:56:11 +02:00
AuxXxilium
d605e58e74 init: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 12:55:32 +02:00
AuxXxilium
138148ddb4 arc: cleanup files after dynamic loading
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 12:50:20 +02:00
AuxXxilium
0f83e1b786 arc: more work for dynamic mode
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 12:48:54 +02:00
AuxXxilium
14a2c97d84 arc-functions: extend update menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 12:29:02 +02:00
AuxXxilium
ca78453816 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 12:17:13 +02:00
AuxXxilium
7c9811229e build: fix local build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-03 12:12:46 +02:00
AuxXxilium
0b7baa07de build: remove vhdx from s version
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 21:52:19 +02:00
AuxXxilium
0b74f57dab build: fix autobuild
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 21:48:59 +02:00
AuxXxilium
6dc5823706 build: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 21:43:04 +02:00
AuxXxilium
72bb5133e6 grub: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 21:42:57 +02:00
AuxXxilium
b0d370ee30 build: modify
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 21:05:34 +02:00
AuxXxilium
5e10296de9 boot: remove duplicated exit
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 20:31:56 +02:00
AuxXxilium
ca1c372d43 arc: add dynamic mode
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 20:10:43 +02:00
AuxXxilium
4c64123cc2 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 19:52:10 +02:00
AuxXxilium
3a29084e6e tree: add back branches x/s
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 19:48:35 +02:00
AuxXxilium
74e7294491 update: add custom to update section
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 19:12:14 +02:00
AuxXxilium
48c66303af arc-functions: fix missing
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 19:08:11 +02:00
AuxXxilium
7dddfe463c build: load custom from it's own repo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 18:28:15 +02:00
AuxXxilium
4162d718ae custom: move to new location
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 18:23:15 +02:00
AuxXxilium
a9452afe2c readme: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-08-02 18:22:30 +02:00
AuxXxilium
2242c9d8d2 grub: enhance loader disk to 2GB
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-31 20:45:28 +02:00
AuxXxilium
19528cb453 grub: match synoboot partition size
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-31 20:29:50 +02:00
AuxXxilium
a20a00e420 arc-functions: rewrite greplogs
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-31 20:29:40 +02:00
AuxXxilium
94c1174771 tree: remove arc branches (s/x)
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-31 20:29:35 +02:00
AuxXxilium
987f499ad7 grub: rework and add todo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-31 20:29:31 +02:00
AuxXxilium
71ed24972a boot: rewrite order
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-31 20:29:13 +02:00
AuxXxilium
5c309ee4f0 arc/boot: add exit code
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-31 20:29:11 +02:00
AuxXxilium
9f6ec3e219 scripts: add back grub
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-31 20:29:06 +02:00
AuxXxilium
ed099257e7 arc: cleanup cmdline after model switch
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-31 20:29:01 +02:00
AuxXxilium
bb89a21b17 ramdisk: fix 2024-07-30 20:32:35 +02:00
AuxXxilium
f27324c152 arc-functions: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-30 20:30:56 +02:00
AuxXxilium
a12d7726bb ramdisk: fix SA6400
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-30 17:22:30 +02:00
AuxXxilium
6180f1a933 tree: bugfix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-30 17:13:12 +02:00
AuxXxilium
73a72774cd update: fix fullupgrade for "s" version
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-29 23:09:50 +02:00
AuxXxilium
1d582d8e0c tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-29 23:04:28 +02:00
AuxXxilium
e4307368f4 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-28 20:05:42 +02:00
AuxXxilium
019fb71253 tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-26 23:48:55 +02:00
AuxXxilium
e883a0b43f tree: changes for compatibility
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-26 23:26:52 +02:00
AuxXxilium
c288e229fb build: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-26 23:18:48 +02:00
AuxXxilium
248aafbd11 build: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-26 21:04:53 +02:00
AuxXxilium
ae7318a883 build: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-26 20:12:56 +02:00
AuxXxilium
89746196ee init: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-26 19:00:55 +02:00
AuxXxilium
5aadfd792b build: rework build system
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-26 18:50:05 +02:00
AuxXxilium
68ca715f7a tree: full rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-26 16:57:14 +02:00
AuxXxilium
3a28bf0ee9 arc: fix spaces
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-25 21:17:55 +02:00
AuxXxilium
9574727c71 arc: remove ipv6 switch and enable it globally
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-25 17:18:54 +02:00
AuxXxilium
6dc044aec0 tree: multiple fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-25 17:17:14 +02:00
AuxXxilium
03bc810fa0 arc-functions: add more informations to sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-23 19:41:03 +02:00
AuxXxilium
7015dbe2e1 tree: activate latest changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 22:12:38 +02:00
AuxXxilium
afa15a1615 grub: add memtest
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 20:47:04 +02:00
AuxXxilium
326c6d0985 configFile: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 20:46:50 +02:00
AuxXxilium
542c5a1017 boot: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 20:46:40 +02:00
AuxXxilium
58a46bf753 grub: rename
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 16:02:52 +02:00
AuxXxilium
c3592c3756 build: cleanup local
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 15:48:31 +02:00
AuxXxilium
61dd7f0d7c network: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 15:47:45 +02:00
AuxXxilium
935f77255f arc: add warning
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 15:40:42 +02:00
AuxXxilium
0855c5b218 boot: rewrite nic logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 15:32:35 +02:00
AuxXxilium
0524f92c73 boot: fix NIC amount
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 15:16:07 +02:00
AuxXxilium
bd8e23f125 arc: remove amepatch if arc patch is false
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 14:20:57 +02:00
AuxXxilium
d513e63c59 update: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 12:45:05 +02:00
AuxXxilium
2049102139 menu: simplify
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 11:40:18 +02:00
AuxXxilium
6faa0a6632 arc: fix update loader
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-21 11:30:49 +02:00
AuxXxilium
b58cfa5ae1 arc: fix model table
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-20 12:28:38 +02:00
AuxXxilium
1ab6d16be3 arc: change info window size in model selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-20 11:34:42 +02:00
AuxXxilium
544f14589f ramdisk: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-18 18:47:19 +02:00
AuxXxilium
c2ce4b4677 build: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-18 18:46:48 +02:00
AuxXxilium
9cbd12a7dc arc: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-18 18:46:33 +02:00
AuxXxilium
928fc825aa custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-18 18:17:17 +02:00
AuxXxilium
8de7f55b28 tree: finalize changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-18 18:15:01 +02:00
AuxXxilium
e523a66522 arc: reduce code
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-17 18:43:50 +02:00
AuxXxilium
a5a55b6269 arc: fix igpu text in modellist
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-17 18:36:45 +02:00
AuxXxilium
9193cd7c40 arc: SA6400 remove from list if raid controller is found
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-17 17:38:34 +02:00
AuxXxilium
cd20c3bba0 information: rewrite i915 text
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-17 17:37:08 +02:00
AuxXxilium
9467bd1431 information: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-17 17:21:35 +02:00
AuxXxilium
f385460425 build: more changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-17 17:11:48 +02:00
AuxXxilium
91b26d3556 build: set stable br
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-17 16:31:12 +02:00
AuxXxilium
7fc268188f build: more changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-17 16:20:14 +02:00
AuxXxilium
4978a1727d build: new version format
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-17 16:17:22 +02:00
AuxXxilium
ce8148ab3e update: add version check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-17 16:16:50 +02:00
AuxXxilium
0171dcd9ee boot: x2apic - global disable
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-17 16:16:29 +02:00
AuxXxilium
63d8125895 grub: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-14 16:08:19 +02:00
AuxXxilium
0529e65181 grub: remove update mode if loader isn't build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-14 16:03:40 +02:00
AuxXxilium
2f0f429dfa grub: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-14 15:57:19 +02:00
AuxXxilium
354f92dd91 grub: fix rebuild
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-14 13:41:15 +02:00
AuxXxilium
04369acb50 arc/arc-functions: rewrite text
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-14 10:21:08 +02:00
AuxXxilium
2f49981d01 arc: begin work for next changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-13 19:48:44 +02:00
AuxXxilium
4695813e50 tree: rework automated
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-13 18:07:43 +02:00
AuxXxilium
aa714f49c4 grub: test
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-13 16:51:10 +02:00
AuxXxilium
41dd869f0c arc-functions: key transform lower upper
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-13 15:36:46 +02:00
AuxXxilium
1626103849 custom: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-12 21:13:50 +02:00
AuxXxilium
4d7512c53f custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-12 21:11:49 +02:00
AuxXxilium
fd0a9810f3 arc-functions: sysinfo cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-12 21:09:17 +02:00
AuxXxilium
128c3e7ec2 modulelist: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-12 20:56:25 +02:00
AuxXxilium
045352d5f7 arc: rewrite arc patch message
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-12 20:41:47 +02:00
AuxXxilium
38f1318b8f tree: full rework for config compatibility
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-12 18:02:47 +02:00
AuxXxilium
bd75ecab30 arc: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-11 00:36:15 +02:00
AuxXxilium
48169de420 arc: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-11 00:34:51 +02:00
AuxXxilium
462bf9396c arc: update make steps
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-08 21:27:29 +02:00
AuxXxilium
3957bfeb13 arc: remove modules write to dsm, can be used from inside modules submenu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-08 21:17:46 +02:00
AuxXxilium
39764a5ccf arc-functions: rename external controller
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-08 21:08:59 +02:00
AuxXxilium
de69d60290 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-08 21:08:43 +02:00
AuxXxilium
0a2ddad16a Revert "Auxiliary commit to revert individual files from 56d2fba4dd6f8baa8d813f49bac540681af90c46"
This reverts commit f41e5e635e6fc9c411399bf60243f2b27a677e5f.

Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 21:46:07 +02:00
AuxXxilium
5ba0d0d673 arc-functions: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 20:35:19 +02:00
AuxXxilium
56d2fba4dd tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 20:27:17 +02:00
AuxXxilium
e8bd33d383 boot: rewrite logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 19:49:57 +02:00
AuxXxilium
a87d70e3d8 arc-functions: more logic rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 19:48:15 +02:00
AuxXxilium
d663e00df7 arc-functions: cmdline menu optimize logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 19:41:29 +02:00
AuxXxilium
b3e5e16f5b arc-functions: rework StoragePanel Options
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 19:39:04 +02:00
AuxXxilium
8f991cec67 arc-functions: fix cmdline menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 19:33:46 +02:00
AuxXxilium
f422a83c08 arc-functions: fix synoinfo menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 19:25:52 +02:00
AuxXxilium
82b787c223 arc: reorder menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 16:40:29 +02:00
AuxXxilium
5f301893ea update: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 11:32:53 +02:00
AuxXxilium
536d18a946 arc: fix initial offlinecheck
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 11:07:30 +02:00
AuxXxilium
e802789da8 arc: show status for screeen off
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 10:52:14 +02:00
AuxXxilium
ea9c7526d2 arc: offlinemode rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 10:45:36 +02:00
AuxXxilium
4ad6f52ed9 functions: rework offline check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 10:23:55 +02:00
AuxXxilium
27d82d58cf arc: only show addon options if addon is selected
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-06 00:39:56 +02:00
AuxXxilium
91a94b2824 arc: notify while switching to custom kernel
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-05 23:54:24 +02:00
AuxXxilium
9bfe65de07 tree: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-05 23:27:09 +02:00
AuxXxilium
fd7a433d10 init/functions: fix loader disk bus
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 22:08:50 +02:00
AuxXxilium
c799f465a9 arc/arc-functions: rewrite power menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 21:58:23 +02:00
AuxXxilium
8f0cab1764 arc-functions: add bootdisk and bus to sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 21:45:13 +02:00
AuxXxilium
bee4a5d24b arc: fix automated build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 21:34:12 +02:00
AuxXxilium
baf76f4fc8 arc: remove functions need online connection while offline mode is true
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 20:53:56 +02:00
AuxXxilium
7c1118cf1b arc: ipv6 switch rewrite logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 20:50:34 +02:00
AuxXxilium
1cd953b82f arc: fix ipv6 switch
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 20:49:19 +02:00
AuxXxilium
bf5ed142bc functions: more logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 20:43:21 +02:00
AuxXxilium
575cc9e40f functions: rework logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 20:40:25 +02:00
AuxXxilium
4d4a5fd980 tree: rework IV
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 20:37:50 +02:00
AuxXxilium
db6e493a2d tree: bugfix III
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 20:12:29 +02:00
AuxXxilium
e186af796d tree: bugfix II
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 20:05:05 +02:00
AuxXxilium
f01316934f tree: bugfix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-04 20:00:05 +02:00
AuxXxilium
1469146291 boot: recheck bus
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-03 21:03:13 +02:00
AuxXxilium
8be8973f16 functions: reset getbus
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-03 20:51:07 +02:00
AuxXxilium
ccafa47ad7 ramdisk: remove dot from output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-03 18:54:15 +02:00
AuxXxilium
356b470690 arc-functions: remove additional space in sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-03 17:45:03 +02:00
AuxXxilium
79a5e46306 boot: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-03 17:39:59 +02:00
AuxXxilium
fedd090fd4 init/boot: wait a second more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-03 17:00:58 +02:00
AuxXxilium
834abaf73f boot: rework nic logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-03 16:59:22 +02:00
AuxXxilium
1d0dae281b arc: a bit more work
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-02 21:38:30 +02:00
AuxXxilium
359d0ae806 boot: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-02 20:33:23 +02:00
AuxXxilium
6209273d10 arc: fix model selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-02 20:26:13 +02:00
AuxXxilium
17ac74309e arc: add reboot message to ipv6 switch
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-02 20:15:38 +02:00
AuxXxilium
306c7f8c41 init: revert force restart dhcp
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-02 20:12:24 +02:00
AuxXxilium
9f3928ecfd tree: some fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-02 19:49:09 +02:00
AuxXxilium
4bbbebd3c9 arc: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-02 19:08:08 +02:00
AuxXxilium
351b75eceb functions: finalize changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-02 18:57:34 +02:00
AuxXxilium
c1aa1b23b2 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-02 18:55:31 +02:00
AuxXxilium
491531f19c init: force dhcp restart
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-02 18:53:48 +02:00
AuxXxilium
01dbfe92dc arc: rework III
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-02 16:33:11 +02:00
AuxXxilium
82066f3267 arc: rework II
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-02 16:03:22 +02:00
AuxXxilium
e1fa72058e storage: update description
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-01 21:10:18 +02:00
AuxXxilium
52a409a846 arc: fix cpu governor
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-01 20:53:55 +02:00
AuxXxilium
8d8454ebd4 arc: fix model selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-01 20:34:41 +02:00
AuxXxilium
9980ac3f6c arc: syntax fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-01 20:26:07 +02:00
AuxXxilium
b76ee77ad0 arc: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-01 20:12:52 +02:00
AuxXxilium
cbb9df360e arc: error if user exit
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-01 20:11:26 +02:00
AuxXxilium
f936e463c9 arc: rewrite model selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-01 20:07:10 +02:00
AuxXxilium
c0fe877adc ramdisk: predefine values
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-01 19:58:02 +02:00
AuxXxilium
60c38fa781 arc-functions: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-01 19:44:57 +02:00
AuxXxilium
50bee6f3c7 arc: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-01 19:26:51 +02:00
AuxXxilium
d97b820cd6 arc: sync menu to wiki
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-01 18:13:14 +02:00
AuxXxilium
42d9d6be5f boot: reactivate sdcard in dsm
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-07-01 17:47:37 +02:00
AuxXxilium
79391ac86c ramdisk: add cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-30 20:04:49 +02:00
FulcrumCode
3f9e351132 readme: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-30 12:47:35 +02:00
AuxXxilium
4e31dda1de arc: menu update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-30 11:44:04 +02:00
AuxXxilium
f519c386a1 tree: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-30 10:31:51 +02:00
AuxXxilium
9a14abbab6 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-30 10:10:22 +02:00
AuxXxilium
875376902e custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 20:25:08 +02:00
AuxXxilium
a47bdc1ba7 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 20:21:41 +02:00
AuxXxilium
948ca437c0 arc-functions: update format disks
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 20:07:43 +02:00
AuxXxilium
cab97f130f init: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 16:04:36 +02:00
AuxXxilium
eb6336e49c arc: do more work
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 15:39:23 +02:00
AuxXxilium
878dc47783 arc: change memory syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 14:25:15 +02:00
AuxXxilium
67a4046d8f tree: remove usbale from memory showing
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 14:22:27 +02:00
AuxXxilium
bb4dfec3fa boot: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 14:21:04 +02:00
AuxXxilium
e5a9516f73 boot: change more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 14:18:45 +02:00
AuxXxilium
e2fca9a2f3 tree: rewrite more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 14:15:09 +02:00
AuxXxilium
233f7cc1d7 arc: force decrypt if old config has arc patch true
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 14:08:35 +02:00
AuxXxilium
a326a3b733 tree: try something new
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 14:05:20 +02:00
AuxXxilium
4939ea332a arc: fix model window
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 12:34:04 +02:00
AuxXxilium
bd9a33056f arc: move more checks to functions
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 10:58:05 +02:00
AuxXxilium
10ccbfb342 build: add br_version to output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 10:30:18 +02:00
AuxXxilium
07a8376ffa arc: add keymap to update output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 10:26:21 +02:00
AuxXxilium
401d46d923 arc: move checks to functions
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 10:21:41 +02:00
AuxXxilium
b424d25fe1 arc: fix keymap automation
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-29 10:11:12 +02:00
AuxXxilium
b116610e48 arc: readd module write dsm
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 22:37:15 +02:00
AuxXxilium
1bd2c75265 arc: rename "update" to "update loader"
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 22:27:40 +02:00
AuxXxilium
bd2540d740 arc-functions: add secure boot to sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 22:27:22 +02:00
AuxXxilium
477a3d335b arc: reset conf/build if key is entered
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 21:22:56 +02:00
AuxXxilium
243dbac376 arc: remove cpu brand from selection (causing irritation my some user)
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 20:43:57 +02:00
AuxXxilium
fd2d2ca939 arc: more fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 20:41:44 +02:00
AuxXxilium
8f0943fb82 arc: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 20:23:40 +02:00
AuxXxilium
edd58ac378 arc: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 20:02:43 +02:00
AuxXxilium
609248c519 arc: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 20:00:08 +02:00
AuxXxilium
35ade9f672 arc-functions: clean function
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 19:54:28 +02:00
AuxXxilium
3480529b39 tree: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 19:51:45 +02:00
AuxXxilium
46f750bab2 init: add compatmode
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 17:38:22 +02:00
AuxXxilium
a3bf814b26 build: rewrite message
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 15:15:03 +02:00
AuxXxilium
2c5c8e4684 consts: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 15:08:01 +02:00
AuxXxilium
b1cecfc19c update: fix dependecies
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 15:01:00 +02:00
AuxXxilium
462ba91d4f init/boot: ip fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-28 14:28:39 +02:00
AuxXxilium
ecf9bc8f74 init: add dhcp restart (only for testing)
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 22:11:14 +02:00
AuxXxilium
5377eb0e72 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 21:18:44 +02:00
AuxXxilium
2d8a1ba006 arc-functions: add modulelist options
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 21:18:39 +02:00
AuxXxilium
76be9c05fb arc: rename menu entry
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 20:23:16 +02:00
AuxXxilium
2adcef7e40 boot: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 20:19:38 +02:00
AuxXxilium
6adb83f253 arc: remove loaded module write
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 19:51:45 +02:00
AuxXxilium
2c1bab8602 boot: rewrite mac related
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 19:48:05 +02:00
AuxXxilium
7f5ca9ac43 arc: rewrite more texts
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 19:16:25 +02:00
AuxXxilium
74939772bb arc: fix edit user config
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 19:10:46 +02:00
AuxXxilium
b0405f5030 tree: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 19:05:46 +02:00
AuxXxilium
88ce78bbde arc: remove empty line from sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 18:57:43 +02:00
AuxXxilium
e1f8c285a7 tree: rewrite mac
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 18:46:03 +02:00
AuxXxilium
cedbc1393e custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 18:25:24 +02:00
AuxXxilium
b36b2880ba tree: rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-27 18:11:29 +02:00
AuxXxilium
db0c69520e arc/network: fix user mac setting
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-26 20:55:02 +02:00
AuxXxilium
f2117fe5bb tree: do some rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-26 20:07:31 +02:00
AuxXxilium
1aedb8eaae boot: add intel pstate fix for acpi
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-26 19:41:09 +02:00
AuxXxilium
f4ee86857a arc: rework menu and network related
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-25 21:50:40 +02:00
AuxXxilium
8c21ad284d network: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-25 21:20:23 +02:00
AuxXxilium
72e3f0ab63 tree: more config rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-25 21:10:06 +02:00
AuxXxilium
7d8c17c09d arc: update model selection and reduce code
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-25 20:24:26 +02:00
AuxXxilium
f604c2ded5 init: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-25 19:12:17 +02:00
AuxXxilium
2162990007 boot: rewrite for some users they don't understand what is shown
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-25 18:45:20 +02:00
AuxXxilium
13db1340f2 arc: extend sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-25 18:29:54 +02:00
AuxXxilium
3f14098ac3 tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-25 17:03:38 +02:00
AuxXxilium
89c895c868 arc-functions: edit credits
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-25 16:34:41 +02:00
AuxXxilium
15eea1e4e6 tree: fix missing
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-25 16:29:55 +02:00
AuxXxilium
caa6007555 init/boot: final output fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-24 21:39:46 +02:00
AuxXxilium
362ad1b8f7 custom: update build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-24 21:29:52 +02:00
AuxXxilium
25500dfbc5 tree: fix typos
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-24 21:14:42 +02:00
AuxXxilium
b8e6648ea9 arc: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-24 21:05:22 +02:00
AuxXxilium
b4f45592e0 boot: fix output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-24 20:51:23 +02:00
AuxXxilium
bd4737eb6a arc: fix cpufreq for non acpi systems
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-24 20:24:12 +02:00
AuxXxilium
aa2ffbd249 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-24 20:18:09 +02:00
AuxXxilium
62ff3b402e boot: fix mem shown
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-24 20:14:04 +02:00
AuxXxilium
5b6d06a850 arc: add staticip for dsm and loader
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-24 20:12:00 +02:00
AuxXxilium
e07005de67 tree: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-24 18:36:22 +02:00
AuxXxilium
3453046c67 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 23:46:09 +02:00
AuxXxilium
81152b4a79 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 23:43:17 +02:00
AuxXxilium
023280fb64 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 16:28:05 +02:00
AuxXxilium
0cf81cb232 arc-functions: add reinit to menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 16:18:56 +02:00
AuxXxilium
c764bb7d3d ramdisk: change acpi check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 14:00:45 +02:00
AuxXxilium
f2c808891c arc: don't override keymap
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 12:30:57 +02:00
AuxXxilium
cc0dc3ad8b ramdisk: add mountloader
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 12:24:18 +02:00
AuxXxilium
ccbdf7e243 tree: rework functions
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 12:23:10 +02:00
AuxXxilium
8adeb6cc30 init: disable dhcp restart
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 12:14:04 +02:00
AuxXxilium
a3fe5a7b41 build: remove changelog
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 11:27:53 +02:00
AuxXxilium
32fe78d1ab build: add time to output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 11:24:22 +02:00
AuxXxilium
b247348f3c arc/arc-functions: add restart network trigger
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 10:51:40 +02:00
AuxXxilium
330a555147 build: add buildroot version
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-23 10:31:13 +02:00
AuxXxilium
97bfea622a update: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-22 21:50:41 +02:00
AuxXxilium
a050a3703c arc-functions: add format to cmdline/synoinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-22 21:47:04 +02:00
AuxXxilium
647b627dc0 arc: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-22 21:37:24 +02:00
AuxXxilium
a91fc93154 arc: reduce and fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-22 21:31:34 +02:00
AuxXxilium
1591b1c681 arc: rewrite primary nic function
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-22 17:15:10 +02:00
AuxXxilium
9ecf811587 arc: add arcnic "auto" selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-22 16:33:43 +02:00
AuxXxilium
3e6a7c5070 arc: change beta to source
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-22 15:58:39 +02:00
AuxXxilium
5a0d6bb3f9 arc: update model selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-22 15:40:06 +02:00
AuxXxilium
7afdc5a752 init: restart dhcp to get ip
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-22 13:14:44 +02:00
AuxXxilium
57af810bcc arc: add recommended option
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 23:34:02 +02:00
AuxXxilium
067c2d4f71 arc: fix ntp
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 22:04:06 +02:00
AuxXxilium
a666cffcfd arc-functions: fix exit to shell
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 21:12:10 +02:00
AuxXxilium
fa106cca9a grub: set resolution to auto
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 21:06:54 +02:00
AuxXxilium
5b4e7079c4 ramdisk: revert more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 20:21:07 +02:00
AuxXxilium
de61794a07 tree: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 20:11:22 +02:00
AuxXxilium
da227b258d build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 19:58:15 +02:00
AuxXxilium
ba06df22ea ramdisk: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 19:42:15 +02:00
AuxXxilium
f9b0d8c29d ramdisk: revert
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 19:37:07 +02:00
AuxXxilium
3d3509e023 grub: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 19:23:33 +02:00
AuxXxilium
464bee51e0 tree: more work
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 16:11:53 +02:00
AuxXxilium
550a966b6b custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 15:37:11 +02:00
AuxXxilium
f81a84106c arc: syntax fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 15:34:27 +02:00
AuxXxilium
e507b66033 arc: add new functions
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 15:32:43 +02:00
AuxXxilium
0eaeae5b20 arc: add powersave governor
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-21 15:12:07 +02:00
AuxXxilium
18c7782477 arc: reorder build steps
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-20 20:52:41 +02:00
AuxXxilium
50c34f4d20 arc: add conservative
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-20 20:45:13 +02:00
AuxXxilium
811746c927 build: back to 1G (will readd version with more space later)
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-20 20:44:51 +02:00
AuxXxilium
7c0305aa37 arc: rework cpu frequency scaling support
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-20 18:46:49 +02:00
AuxXxilium
bbc667f3a6 arc: rewrite updatecheck
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-19 19:56:23 +02:00
AuxXxilium
292b319730 build: change order to get files
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-19 17:55:57 +02:00
AuxXxilium
f999ad2821 tree: rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-19 17:45:46 +02:00
AuxXxilium
430a2bd00c build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-18 22:29:56 +02:00
AuxXxilium
de12fa6282 build: update local
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-18 18:47:27 +02:00
AuxXxilium
03b85b2474 init/boot: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-18 17:58:12 +02:00
AuxXxilium
0ca5c7cdc1 init/boot: remove wol from arc boot
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-18 17:44:19 +02:00
AuxXxilium
3614986677 boot: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-18 17:42:35 +02:00
AuxXxilium
4dece9d9b0 arc: syntax fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-17 21:38:48 +02:00
AuxXxilium
686a5d225d arc: fix msgbox
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-17 20:52:06 +02:00
AuxXxilium
43f536a3f9 arc-functions: more sysinfo informations
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-17 20:37:34 +02:00
AuxXxilium
e89d87086a arc-functions: reduce sysinfo lines
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-17 19:53:49 +02:00
AuxXxilium
d3843f2b31 arc-functions: add more synoinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-17 18:37:22 +02:00
AuxXxilium
1a1afb9abf arc: add copy for modules loaded in arc
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-17 18:02:32 +02:00
AuxXxilium
02877c7793 arc/storage: rename StorageMap to Sata Portmap
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-15 14:03:19 +02:00
AuxXxilium
684f23d72f storage: fix warning
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-15 13:56:57 +02:00
AuxXxilium
f01a38f003 arc-functions: more changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-15 13:45:38 +02:00
AuxXxilium
75e70c9fbb arc: reorder menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-15 13:36:54 +02:00
AuxXxilium
2751771b75 arc/arc-functions: more rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-15 13:31:11 +02:00
AuxXxilium
784bd4f181 arc-functions: add sequentialio menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-15 13:15:37 +02:00
AuxXxilium
acf242b3a9 arc: rework menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-15 13:15:21 +02:00
AuxXxilium
0fe9e2a405 update: reset arc key
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-14 20:23:39 +02:00
AuxXxilium
2921bee62c arc-functions: fix decrypt
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-14 20:19:13 +02:00
AuxXxilium
4613992098 init: remove sleep
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-14 19:56:21 +02:00
AuxXxilium
7f0efa4b6d init/boot: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-14 19:45:04 +02:00
AuxXxilium
a8241128df custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-14 19:44:43 +02:00
AuxXxilium
db81cb490b tree: rework more features
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-14 17:34:49 +02:00
AuxXxilium
ad1b0d2d1f arc-functions: rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-14 17:20:25 +02:00
AuxXxilium
286acb6821 arc: fix false bus read
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-14 16:14:13 +02:00
AuxXxilium
3e826561ae init: stop dhcp if static ip is set
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-14 15:41:51 +02:00
AuxXxilium
95df71ad10 init: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-13 23:01:04 +02:00
AuxXxilium
b9e478292a tree: more cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-13 21:24:14 +02:00
AuxXxilium
db85294724 init/boot: more cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-13 20:49:09 +02:00
AuxXxilium
055b37d2e3 tree: cleanup more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-13 20:33:42 +02:00
AuxXxilium
76e248f02d tree: rewrite lkm path
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-13 20:19:28 +02:00
AuxXxilium
b7bc607e0e functions: more rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-13 20:13:20 +02:00
AuxXxilium
9bf7e375ee boot/functions: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-13 20:07:48 +02:00
AuxXxilium
cd762d8d0f tree: rewrite grub related
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-13 19:57:28 +02:00
AuxXxilium
f8cbc01cb9 init: test
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-13 19:49:55 +02:00
AuxXxilium
0aa31b59ad init: fix paths
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-13 19:46:12 +02:00
AuxXxilium
71391e3b8d arc: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-12 18:48:41 +02:00
AuxXxilium
d340f3eeaf arc-functions: fix grep logs
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-12 17:35:40 +02:00
AuxXxilium
f086ec46ab arc: remove SA6400 from list if SCSI controller are found
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-12 17:34:45 +02:00
AuxXxilium
8f32bb70df tree: rewrite features
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-12 17:23:32 +02:00
Christian
54f59c71f4 arc: fix ram showing 2024-06-12 07:18:08 +02:00
AuxXxilium
552dce6431 arc: fix summary
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-11 21:05:18 +02:00
AuxXxilium
5c99aa2215 build: resize local builds
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-11 20:38:27 +02:00
AuxXxilium
d745df0978 arc: extend data partition to 2G (need to replace bootimage at all)
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-11 19:17:41 +02:00
AuxXxilium
a2b34bd3cd build: update to latest features
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-11 18:55:28 +02:00
AuxXxilium
113cd2c92e build: add new features
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-11 18:53:47 +02:00
AuxXxilium
53caba0c78 init: add missing
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-11 18:23:46 +02:00
AuxXxilium
e2c90b8481 tree: bugfix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-11 17:50:42 +02:00
AuxXxilium
dca32f571f custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-11 17:49:25 +02:00
AuxXxilium
0e39205b4f ramdisk-patch: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-09 14:13:15 +02:00
AuxXxilium
f4fae21a81 arc-functions: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-09 14:12:03 +02:00
AuxXxilium
f1887e2fc8 sxtorage: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 20:49:48 +02:00
AuxXxilium
b3c806bcd8 build: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 19:51:07 +02:00
AuxXxilium
e51d914a54 arc: move pat data write
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 19:06:45 +02:00
AuxXxilium
1084cee1c5 arc-functions: do not show amepatch if loader is offline
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 18:10:42 +02:00
AuxXxilium
e31cb6f5c2 boot: set boottimer to 5
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 18:05:13 +02:00
AuxXxilium
6a11610cc8 arc: rework online detection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 17:59:08 +02:00
Christian
ae5b44048b arc: set eth0 to default is offline
Signed-off-by: Christian <info@auxxxilium.tech>
2024-06-08 17:49:38 +02:00
AuxXxilium
cda52a9037 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 16:28:28 +02:00
AuxXxilium
3b01bb3f9d arc-functions: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 16:27:03 +02:00
AuxXxilium
74aa8b93a5 readme: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 15:57:12 +02:00
AuxXxilium
ba36dc36a1 arc: add keymap to headline
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 15:08:39 +02:00
AuxXxilium
7db988dccc arc: automate more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 14:40:41 +02:00
AuxXxilium
1e973001db storage: silence output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 14:28:55 +02:00
AuxXxilium
4ad9eb98bf arc-functions: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 11:33:27 +02:00
AuxXxilium
24a7deb0b9 arc: logic fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-08 11:27:44 +02:00
AuxXxilium
ff53f97758 arc: silence ntp
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-07 22:09:46 +02:00
AuxXxilium
2ebf53c908 init/boot: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-07 21:56:38 +02:00
AuxXxilium
6d0295a1cf tree: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-07 21:50:40 +02:00
AuxXxilium
d344504a93 tree: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-07 21:43:01 +02:00
AuxXxilium
18a64e56e2 tree: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-07 19:30:23 +02:00
AuxXxilium
97737d4d61 arc: rewrite online check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-07 19:17:41 +02:00
AuxXxilium
20830376c4 arc: add back max_mem_mb setting
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 21:27:44 +02:00
AuxXxilium
25aa24cd6f init: fix primary nic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 21:15:06 +02:00
AuxXxilium
6aad4217f4 grub: rename
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 19:56:11 +02:00
AuxXxilium
dfec5ba547 arc: rework custom logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 19:51:46 +02:00
AuxXxilium
b45a0415af tree: more rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 17:13:32 +02:00
AuxXxilium
5417b7d548 arc: rework menu
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 16:45:59 +02:00
AuxXxilium
3512512e28 tree: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 16:29:26 +02:00
AuxXxilium
eca0296c36 arc: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 16:09:10 +02:00
AuxXxilium
12cc832a9d arc: cleanup code
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 16:04:53 +02:00
AuxXxilium
77cd61685e arc: fix empty syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 15:59:10 +02:00
AuxXxilium
6eaff7eb36 arc: don't reset custom
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 15:58:04 +02:00
AuxXxilium
219948858b arc: reread config after reset
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 15:56:01 +02:00
AuxXxilium
aae3eaba2c arc: force cleanup old files
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 15:47:54 +02:00
AuxXxilium
9e6a45d579 arc: full reset config if model is changed
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-05 15:45:04 +02:00
AuxXxilium
a80655a76b arc-functions: use module name as description for primary nic setting
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-04 17:25:49 +02:00
AuxXxilium
fc45cc84cb arc: rewrite more messages
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-02 11:18:09 +02:00
AuxXxilium
51239adb22 arc: rework some dialog
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-02 11:12:19 +02:00
AuxXxilium
0491b9e9c9 arc: some more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-02 10:54:45 +02:00
AuxXxilium
34c78ce3c3 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-02 10:35:26 +02:00
AuxXxilium
374282b7b5 arc: silence output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-01 23:46:28 +02:00
AuxXxilium
08c1100be5 tree: more fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-01 23:40:35 +02:00
AuxXxilium
21bbfb5ff2 functions: silent output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-01 11:09:01 +02:00
AuxXxilium
7a7d2b2f22 arc-functions: show time/date in sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-01 09:52:26 +02:00
AuxXxilium
f660cf6131 functions: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-01 09:50:32 +02:00
AuxXxilium
f5ebbf9704 tree: add ntp timeserver
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-01 09:45:45 +02:00
AuxXxilium
808c081325 functions: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-01 09:25:36 +02:00
AuxXxilium
48bd9bd482 tree: fix latest changes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-01 00:27:40 +02:00
AuxXxilium
5c4b8a8bc5 arc: rewrite build dialog
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-01 00:25:08 +02:00
AuxXxilium
b6b47184c1 tree: rework some messages
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-01 00:14:40 +02:00
AuxXxilium
b1338e33b6 tree: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-06-01 00:00:41 +02:00
AuxXxilium
371859f58d tree: rewrite more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-31 23:25:54 +02:00
AuxXxilium
ea6e6fcb08 tree: fix more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-31 20:49:11 +02:00
AuxXxilium
ab7b9f4bcf arc: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-31 20:37:17 +02:00
AuxXxilium
5bd85c8b75 arc: use modelid for getting pat/hash
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-31 20:31:55 +02:00
AuxXxilium
73b63dd007 ramdisk: test
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-31 20:14:50 +02:00
AuxXxilium
b25b88a9ae arc: add time/date function
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-31 19:50:54 +02:00
AuxXxilium
0de2efedfa tree: rewrite more curl
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-31 19:48:16 +02:00
AuxXxilium
15949d773f tree: only use connected interface for curl
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-31 19:42:50 +02:00
AuxXxilium
cdabe50e0c arc: fix custom
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-30 23:13:54 +02:00
AuxXxilium
53f2568481 tree: more fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-30 22:52:28 +02:00
AuxXxilium
a191f1e2c1 update: fix more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 22:50:14 +02:00
AuxXxilium
3a55ac1e3a update: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 21:37:49 +02:00
AuxXxilium
75d064cc3f update: fix more
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 20:57:24 +02:00
AuxXxilium
5cde4b31e8 arc-functions: fix update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 20:26:21 +02:00
AuxXxilium
92bd4a0e97 tree: more fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 20:25:10 +02:00
AuxXxilium
9171f0fa24 update: rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 20:13:49 +02:00
AuxXxilium
92d687342a update: force reboot if autoupdate fails
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 20:11:15 +02:00
AuxXxilium
78320aae48 arc: fix some messages
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 19:59:57 +02:00
AuxXxilium
5f7a1c266e functions: add some output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 19:49:57 +02:00
AuxXxilium
e34e609fcb functions: more rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 19:42:50 +02:00
AuxXxilium
8daeb9109d functions: add more output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 19:36:08 +02:00
AuxXxilium
938dcd6d79 functions: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 19:34:23 +02:00
AuxXxilium
92f78fa136 tree: syntax fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 19:30:01 +02:00
AuxXxilium
4a994f12c7 arc: remove some messages
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 19:08:48 +02:00
AuxXxilium
16927d976c tree: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 19:03:35 +02:00
AuxXxilium
edb3d3b914 tree: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 18:39:16 +02:00
AuxXxilium
5ac955e180 arc: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 01:53:53 +02:00
AuxXxilium
db1fb53315 arc: chmod +x for extractor
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 01:46:06 +02:00
AuxXxilium
11e2d6963a arc/storage: rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-29 01:43:08 +02:00
AuxXxilium
8dde6a899a arc: rewrite validation logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-27 23:09:26 +02:00
AuxXxilium
89ef80dfbe arc: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-27 22:41:00 +02:00
AuxXxilium
e7efdfe7af arc: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-27 22:37:54 +02:00
AuxXxilium
6dd8903f56 consts: revert
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-27 22:33:25 +02:00
AuxXxilium
ed52265c7b arc: add validation check to build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-27 22:24:19 +02:00
AuxXxilium
ead8c64845 arc: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-27 21:50:42 +02:00
AuxXxilium
b42ac77a0a arc: rewrite formate function
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-27 21:02:05 +02:00
AuxXxilium
6201d138a7 build: remove extractor
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-27 20:18:12 +02:00
AuxXxilium
1d5b9b96ba tree: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-27 20:09:27 +02:00
AuxXxilium
47d6ffbbd1 arc: add more sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-26 22:24:15 +02:00
AuxXxilium
ecb7ff0a9e arc/network: rewrite dns setting
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-26 22:04:04 +02:00
AuxXxilium
b987551571 arc: add more sanity check for build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-26 21:52:29 +02:00
AuxXxilium
18b9dd6344 build: remove extractor from build
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-24 10:17:24 +02:00
AuxXxilium
e55c0be066 arc: fix typo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-24 10:14:47 +02:00
AuxXxilium
0886ba597d storage: exclude native from remap port 0
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-24 10:09:37 +02:00
AuxXxilium
838621dc59 init/boot/arc-functions: rewrite some ip functions
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-23 18:20:20 +02:00
AuxXxilium
d51add1678 functions: cleanup code
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 20:40:37 +02:00
AuxXxilium
c2beb03142 tree: more fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 20:35:05 +02:00
AuxXxilium
2fc01c19df tree: rewrite filelinks
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 20:08:22 +02:00
AuxXxilium
d50c968a95 tree: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 19:57:48 +02:00
AuxXxilium
185381aff6 tree: cleanup and rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 19:37:04 +02:00
AuxXxilium
93aaf3a7a0 update: fix reboot message
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 19:20:13 +02:00
AuxXxilium
b19060ca06 update: fix output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 19:09:19 +02:00
AuxXxilium
06d2fd2028 update: syntax fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 18:35:06 +02:00
AuxXxilium
94a5d42b75 update: rewrite code
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 18:32:25 +02:00
AuxXxilium
b5dedb25f7 update: fix loop
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 18:29:36 +02:00
AuxXxilium
5c3e6c0aec update: full rewrite update function
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 17:40:34 +02:00
AuxXxilium
fb128a3670 arc-functions: rewrite full-upgrade
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 15:31:21 +02:00
AuxXxilium
09b774e747 arc: rename hotplug to hotplug/sortdrives
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-22 15:23:26 +02:00
AuxXxilium
d70893a39d arc: fix pat sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-21 22:22:30 +02:00
AuxXxilium
da1cad5b1e arc: rewrite url sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-21 21:07:47 +02:00
AuxXxilium
50cab8772c arc-functions: rework external modules function
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-21 19:05:01 +02:00
AuxXxilium
9f4ffae0bc arc: rewrite automated and add sanity check for url
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-21 18:16:19 +02:00
AuxXxilium
c775348c94 arc: add force rewrite to lower case
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-21 17:53:21 +02:00
AuxXxilium
468214ec1c arc: rewrite arc patch question
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-21 10:19:57 +02:00
AuxXxilium
5af45debaa build: update release notice
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-21 10:06:31 +02:00
AuxXxilium
befc733604 arc-functions: show the version for decryptioncode
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-20 21:57:05 +02:00
AuxXxilium
a4180c932b arc-functions: fix output if key is wrong
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-20 21:51:23 +02:00
AuxXxilium
68b50d0976 storage: remove warning from storagemap
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-20 15:48:36 +02:00
AuxXxilium
01dc990d1d arc-functions: fix reboot warning after full-upgrade
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-20 15:11:58 +02:00
AuxXxilium
612c57c398 arc-functions: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-20 14:56:41 +02:00
AuxXxilium
ef2eca888b arc-functions: reread arc_key
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-19 23:26:29 +02:00
AuxXxilium
ecca04e370 arc-functions: remove netbus from sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-19 20:57:58 +02:00
AuxXxilium
1f08170527 arc: set rammin to ram installed
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-19 20:25:46 +02:00
AuxXxilium
7074702d90 init: add upgrade fix for old configs
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-19 17:20:00 +02:00
AuxXxilium
e6e500a808 custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-19 16:28:36 +02:00
AuxXxilium
49e33844f3 arc/network/functions: rework
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-19 12:51:33 +02:00
AuxXxilium
1982fbe303 arc: rewrite message
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-18 19:31:43 +02:00
AuxXxilium
afabf12c4f tree: some fixes around
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-18 19:19:24 +02:00
AuxXxilium
d943b622f8 arc: fix offline mode
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-18 19:19:00 +02:00
AuxXxilium
dfc2455a57 network: sanity check color output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-18 16:32:24 +02:00
AuxXxilium
948531e59c network: add sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-18 16:30:16 +02:00
AuxXxilium
cdefd4a21f arc: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-18 14:04:35 +02:00
AuxXxilium
961a4c305a arc: modify decryption
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-18 13:43:33 +02:00
AuxXxilium
8d8b7d9c71 arc: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-18 12:37:06 +02:00
AuxXxilium
5371a94ce1 tree: cleanup and add decryption
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-18 12:33:37 +02:00
AuxXxilium
3eab707174 build: update custom
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-17 20:58:37 +02:00
AuxXxilium
9ebc67f6a4 arc: ping github silent
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-17 20:54:30 +02:00
AuxXxilium
d4afc257d5 arc: remove forced module loading while boot
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-16 20:49:06 +02:00
AuxXxilium
7b7410bcc1 arc: update logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-16 19:52:04 +02:00
AuxXxilium
32d31a0b6a arc-functions: add more cmdline options to table
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-16 18:51:49 +02:00
AuxXxilium
2bee3621b9 arc: rewrite online check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-16 18:51:25 +02:00
AuxXxilium
73386cd78f modulelist: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-14 16:59:20 +02:00
AuxXxilium
43cd830acd custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-14 16:53:27 +02:00
AuxXxilium
bf946f3fdd tree: remove usbmount from config
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-13 23:17:57 +02:00
AuxXxilium
ecb0657a6c arc: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 21:16:08 +02:00
AuxXxilium
49ef96ad24 ramdisk: call disks with usbmount
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 20:12:17 +02:00
AuxXxilium
ec875616c0 tree: some style fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 20:11:46 +02:00
AuxXxilium
e60572326e functions: add sanity check
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 16:30:30 +02:00
AuxXxilium
a28a1a80a2 arc: fix syntax
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 16:24:59 +02:00
AuxXxilium
e4b10cd719 arc: only force copy if old dsm files are not found
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 16:23:28 +02:00
AuxXxilium
0dfb6fcfa6 functions: rewrite copyDSMFiles
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 16:17:10 +02:00
AuxXxilium
bc257b20f5 arc-functions: add more options in Portmap section
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 15:39:31 +02:00
AuxXxilium
df566e5d17 arc-functions: rewrite network in sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 15:06:35 +02:00
AuxXxilium
c3e88061d1 arc-functions: fix full sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 14:58:49 +02:00
AuxXxilium
67368b670f init: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 14:54:34 +02:00
AuxXxilium
e02dc20084 arc: fix offline mode logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 14:53:17 +02:00
AuxXxilium
7ac41b5e57 arc: fix logic
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 14:46:01 +02:00
AuxXxilium
bd25dc6704 arc: fix usbmount
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 14:32:27 +02:00
AuxXxilium
210a48cbfd arc-functions: correct sysinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 14:04:41 +02:00
AuxXxilium
fdec4b606d arc: reduce code
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 14:01:25 +02:00
AuxXxilium
2b93eb8ff2 arc: add feature to add user to DSM
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 12:35:35 +02:00
AuxXxilium
f7db7cfb27 arc: ui fixes
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-12 12:06:40 +02:00
AuxXxilium
cc9d6fa074 Revert "ramdisk: try to remove faulty patch"
This reverts commit fae50da982.
2024-05-11 21:58:32 +02:00
AuxXxilium
93341702cd boot: fix mac sequence
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 21:29:46 +02:00
AuxXxilium
a7703ff9e3 init: remove empty space
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 21:28:15 +02:00
AuxXxilium
57691cc035 arc: formate dialogs
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 21:26:35 +02:00
AuxXxilium
f16e8d7078 arc: menu (use platform, not model)
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 21:21:02 +02:00
AuxXxilium
de18c41bf2 arc: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 21:19:49 +02:00
AuxXxilium
fae50da982 ramdisk: try to remove faulty patch
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 21:06:42 +02:00
AuxXxilium
a982084f63 arc: more rewrite
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 16:48:45 +02:00
AuxXxilium
39174a0304 arc: fix generated values
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 16:30:30 +02:00
AuxXxilium
7bd80d8e47 functions: fix random serial
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 16:25:53 +02:00
AuxXxilium
0331738af9 arc: fix some styling
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 16:16:25 +02:00
AuxXxilium
3b93527d9b arc: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 15:42:34 +02:00
AuxXxilium
ab40ee4e8e arc: fix links
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 15:02:29 +02:00
AuxXxilium
e72d424103 arc: silent output
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 14:47:30 +02:00
AuxXxilium
7809449e8d arc: cleanup
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 14:28:49 +02:00
AuxXxilium
78c8f6c0fd custom: update
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 14:26:43 +02:00
AuxXxilium
dd985dd069 arc: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 02:00:42 +02:00
AuxXxilium
e7b8c8f25a tree: reformate Part 8 (fix)
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 01:51:22 +02:00
AuxXxilium
ecf2a4fa81 tree: reformate Part 7
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 01:48:15 +02:00
AuxXxilium
ac6c3f8503 arc: reduce code
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 01:09:14 +02:00
AuxXxilium
13a03925cc arc: rewrite model selection exclusion
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 01:06:18 +02:00
AuxXxilium
7d64765ced arc: fix model selection
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-11 01:04:12 +02:00
AuxXxilium
504c4821a8 tree: reformate Part 6
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-10 16:48:42 +02:00
AuxXxilium
8ad6496cfa tree: reformate Part 5
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-10 16:39:13 +02:00
AuxXxilium
df739d364b tree: fix
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-09 22:00:40 +02:00
AuxXxilium
a3c4b480e7 tree: reformate Part 4
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-09 20:39:43 +02:00
AuxXxilium
6711f2a202 build: update to latest
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-09 16:55:14 +02:00
AuxXxilium
9698a8757c tree: reformate part 3
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-09 16:52:47 +02:00
AuxXxilium
828d1c2ad7 tree: reformate part 2
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-09 13:56:59 +02:00
AuxXxilium
8cafe04730 tree: reformate part 1
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-07 22:50:47 +02:00
AuxXxilium
ecd82e1c04 arc: usbpatch remove force
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-07 21:44:15 +02:00
AuxXxilium
c39316ef5e Revert "storage: try something new"
This reverts commit 31293a6fc8.
2024-05-06 22:28:04 +02:00
AuxXxilium
31293a6fc8 storage: try something new
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-06 22:18:43 +02:00
AuxXxilium
38c2f24a87 arc-functions: set new lkm link
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-06 21:05:57 +02:00
AuxXxilium
ad7c736afc build: update custom
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-06 21:05:53 +02:00
AuxXxilium
408959e974 arc: reduce code part 1
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-06 21:05:36 +02:00
AuxXxilium
b55ed1f888 arc-functions: move some config to synoinfo
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-06 17:58:42 +02:00
AuxXxilium
f1c342df85 init: sort things
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-05 13:04:54 +02:00
AuxXxilium
3dcc744dcd init: arc
Signed-off-by: AuxXxilium <info@auxxxilium.tech>
2024-05-05 01:13:00 +02:00
1145 changed files with 11153 additions and 341373 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
*.sh eol=lf

4
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,4 @@
# These are supported funding model platforms
github: AuxXxilium
buy_me_a_coffee: auxxxilium

17
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,17 @@
---
name: Bug report
about: Create a Bug Report
title: ''
labels: bug
assignees: ''
---
**Describe the Bug**
First read Wiki to find a Solution. If you can't find a Solution, provide a clear and concise description of what the bug is.
**Screenshots**
Actual Screenshot from Systeminfo (Config Mode - Sysinfo) or use new "Full Sysinfo - Upload" Function provide the Code!!! <- IMPORTANT
**Hardware**
Add your Hardware Informations here. CPU / Board / Networkcontroller / Storagecontroller / ...

View File

@@ -0,0 +1,8 @@
---
name: Custom Build
about: Create a Customized Build
title: ''
labels: 'custom'
assignees: ''
---

View File

@@ -0,0 +1,14 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your Feature request related to a Problem? Please describe.**
A clear and concise Description of what the Problem is. Ex. I'm always frustrated when [...]
**Additional Context**
Add any other Context or Screenshots about the Feature request here.

395
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,395 @@
#
# Copyright (C) 2025 AuxXxilium <https://github.com/AuxXxilium>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
name: Build Arc Image
on:
workflow_dispatch:
inputs:
runs:
description: "runs-on"
type: choice
options:
- ubuntu-latest
- self-hosted
version:
description: "version (1.0.0)"
required: true
type: string
notice:
description: "Notice here"
required: false
type: string
latest:
description: "latest"
default: true
type: boolean
prerelease:
description: "pre release"
default: false
type: boolean
minimal:
description: "minimal"
default: true
type: boolean
microcode:
description: "microcode"
default: false
type: boolean
extended:
description: "extended"
default: false
type: boolean
clean:
description: "clean"
default: false
type: boolean
jobs:
build:
runs-on: ${{ inputs.runs }}
steps:
- name: Checkout
uses: actions/checkout@main
- name: Delete releases and workflows runs
if: ${{ inputs.clean }}
uses: ophub/delete-releases-workflows@main
with:
delete_releases: true
releases_keep_latest: 1
delete_workflows: false
delete_tags: true
gh_token: ${{ secrets.GITHUB_TOKEN }}
# Install Dependencies
- name: Install Dependencies
if: ${{ inputs.runs == 'ubuntu-latest' }}
run: |
git config --global user.email "info@auxxxilium.tech"
git config --global user.name "AuxXxilium"
sudo timedatectl set-timezone "Europe/Berlin"
sudo apt update
sudo apt install -y locales busybox dialog gettext sed gawk jq curl
sudo apt install -y python-is-python3 python3-pip libelf-dev qemu-utils cpio xz-utils lz4 lzma bzip2 gzip zstd
# sudo snap install yq
if ! command -v yq &>/dev/null || ! yq --version 2>/dev/null | grep -q "v4."; then
sudo curl -kL https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -o /usr/bin/yq && sudo chmod a+x /usr/bin/yq
fi
df -h
# Get extractor, LKM, Addons, Modules, Theme and Configs
- name: Get Dependencies for all Image
run: |
. scripts/func.sh "${{ secrets.BUILD_TOKEN }}"
echo "Get Dependencies"
getAddons "files/p3/addons"
getModules "files/p3/modules"
getConfigs "files/p3/configs"
getPatches "files/p3/patches"
getCustom "files/p3/custom"
getOffline "files/p3/configs"
getLKMs "files/p3/lkms"
getTheme "files/p1/boot/grub"
getBuildrootx "brx"
getBuildroots "brs"
getBuildrootm "brm"
# Export Dependencies Version to env
echo "ADDONTAG=${ADDONTAG}" >> $GITHUB_ENV
echo "MODULETAG=${MODULETAG}" >> $GITHUB_ENV
echo "CONFIGTAG=${CONFIGTAG}" >> $GITHUB_ENV
echo "PATCHTAG=${PATCHTAG}" >> $GITHUB_ENV
echo "CUSTOMTAG=${CUSTOMTAG}" >> $GITHUB_ENV
echo "LKMTAG=${LKMTAG}" >> $GITHUB_ENV
echo "THEMETAG=${THEMETAG}" >> $GITHUB_ENV
echo "BRXTAG=${BRXTAG}" >> $GITHUB_ENV
echo "BRSTAG=${BRSTAG}" >> $GITHUB_ENV
echo "BRMTAG=${BRMTAG}" >> $GITHUB_ENV
echo "BUILD_TIME=$(date +'%Y-%m-%d %H:%M')" >> $GITHUB_ENV
echo "OK"
# Build incremental
- name: Build extended Image
if: ${{ inputs.extended }}
run: |
. scripts/func.sh
# Modify Source File
ARC_BUILD="`date +'%y%m%d'`"
ARC_VERSION="${{ inputs.version }}"
ARC_BRANCH="extended"
echo "${ARC_BUILD}" >files/p1/ARC-BUILD
echo "${ARC_VERSION}" >files/p1/ARC-VERSION
echo "${ARC_BRANCH}" >files/p1/ARC-BRANCH
echo "ARC_BUILD=${ARC_BUILD}" >> $GITHUB_ENV
echo "ARC_VERSION=${ARC_VERSION}" >> $GITHUB_ENV
echo "ARC_BRANCH=${ARC_BRANCH}" >> $GITHUB_ENV
echo "Create Arc Image"
IMAGE_FILE="arc.img"
gzip -dc "files/initrd/opt/arc/grub.img.gz" >"${IMAGE_FILE}"
fdisk -l "${IMAGE_FILE}"
LOOPX=$(sudo losetup -f)
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
echo "Mounting Image File"
mkdir -p "/tmp/p1"
mkdir -p "/tmp/p3"
sudo mount ${LOOPX}p1 "/tmp/p1"
sudo mount ${LOOPX}p3 "/tmp/p3"
[ ! -f "brx/bzImage-arc" ] || [ ! -f "brx/initrd-arc" ] && return 1
echo "Repack initrd"
cp -f "brx/bzImage-arc" "files/p3/bzImage-arc"
repackInitrd "brx/initrd-arc" "files/initrd" "files/p3/initrd-arc"
echo "Copying files"
sudo cp -rf "files/p1/"* "/tmp/p1"
sudo cp -rf "files/p3/"* "/tmp/p3"
sudo sync
echo "Unmount image file"
sudo umount "/tmp/p1"
sudo umount "/tmp/p3"
rmdir "/tmp/p1"
rmdir "/tmp/p3"
sudo losetup --detach ${LOOPX}
echo "Image Converter"
qemu-img convert -p -f raw -O vmdk ${IMAGE_FILE} arc-dyn.vmdk
qemu-img convert -p -f raw -o subformat=monolithicFlat -O vmdk ${IMAGE_FILE} arc.vmdk
echo "Create Arc vhd"
createvmc "arc.vmc"
qemu-img convert -p -f raw -O vpc ${IMAGE_FILE} arc.vhd
echo "Create Arc ova"
convertova "${IMAGE_FILE}" "arc.ova"
# Zip image and generate checksum
- name: Pack extended Image
if: ${{ inputs.extended }}
run: |
if [ -n "${{ env.ARC_VERSION }}" ]; then
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.img.zip" arc.img
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-dyn.zip" arc-dyn.vmdk
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-flat.zip" arc.vmdk arc-flat.vmdk
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vhd.zip" arc.vhd arc.vmc
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.ova.zip" arc.ova
(cd files && zip -r ../update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.zip ./p1 ./p3)
sha256sum update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.zip >"update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.hash"
fi
# Cleanup
- name: Cleanup
if: ${{ inputs.extended }}
run: |
rm -rf "arc.img" "arc.vmdk" "arc-dyn.vmdk" "arc-flat.vmdk" "arc.vhd" "arc.ova" "arc.vmc" 2>/dev/null
# Build incremental
- name: Build minimal Image
if: ${{ inputs.minimal }}
run: |
. scripts/func.sh
# Modify Source File
ARC_BUILD="`date +'%y%m%d'`"
ARC_VERSION="${{ inputs.version }}"
ARC_BRANCH="minimal"
echo "${ARC_BUILD}" >files/p1/ARC-BUILD
echo "${ARC_VERSION}" >files/p1/ARC-VERSION
echo "${ARC_BRANCH}" >files/p1/ARC-BRANCH
echo "ARC_BUILD=${ARC_BUILD}" >> $GITHUB_ENV
echo "ARC_VERSION=${ARC_VERSION}" >> $GITHUB_ENV
echo "ARC_BRANCH=${ARC_BRANCH}" >> $GITHUB_ENV
echo "Create Arc Image"
IMAGE_FILE="arc.img"
gzip -dc "files/initrd/opt/arc/grub.img.gz" >"${IMAGE_FILE}"
fdisk -l "${IMAGE_FILE}"
LOOPX=$(sudo losetup -f)
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
echo "Mounting Image File"
mkdir -p "/tmp/p1"
mkdir -p "/tmp/p3"
sudo mount ${LOOPX}p1 "/tmp/p1"
sudo mount ${LOOPX}p3 "/tmp/p3"
[ ! -f "brs/bzImage-arc" ] || [ ! -f "brs/initrd-arc" ] && return 1
echo "Repack initrd"
cp -f "brs/bzImage-arc" "files/p3/bzImage-arc"
repackInitrd "brs/initrd-arc" "files/initrd" "files/p3/initrd-arc"
echo "Copying files"
sudo cp -rf "files/p1/"* "/tmp/p1"
sudo cp -rf "files/p3/"* "/tmp/p3"
sudo sync
echo "Unmount image file"
sudo umount "/tmp/p1"
sudo umount "/tmp/p3"
rmdir "/tmp/p1"
rmdir "/tmp/p3"
sudo losetup --detach ${LOOPX}
echo "Image Converter"
qemu-img convert -p -f raw -O vmdk ${IMAGE_FILE} arc-dyn.vmdk
qemu-img convert -p -f raw -o subformat=monolithicFlat -O vmdk ${IMAGE_FILE} arc.vmdk
echo "Create Arc vhd"
createvmc "arc.vmc"
qemu-img convert -p -f raw -O vpc ${IMAGE_FILE} arc.vhd
echo "Create Arc ova"
convertova "${IMAGE_FILE}" "arc.ova"
# Zip image and generate checksum
- name: Pack minimal Image
if: ${{ inputs.minimal }}
run: |
if [ -n "${{ env.ARC_VERSION }}" ]; then
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.img.zip" arc.img
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-dyn.zip" arc-dyn.vmdk
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-flat.zip" arc.vmdk arc-flat.vmdk
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vhd.zip" arc.vhd arc.vmc
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.ova.zip" arc.ova
(cd files && zip -r ../update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.zip ./p1 ./p3)
sha256sum update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.zip >"update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.hash"
fi
# Cleanup
- name: Cleanup
if: ${{ inputs.minimal }}
run: |
rm -rf "arc.img" "arc.vmdk" "arc-dyn.vmdk" "arc-flat.vmdk" "arc.vhd" "arc.ova" "arc.vmc" 2>/dev/null
# Build incremental
- name: Build microcode Image
if: ${{ inputs.microcode }}
run: |
. scripts/func.sh
# Modify Source File
ARC_BUILD="`date +'%y%m%d'`"
ARC_VERSION="${{ inputs.version }}"
ARC_BRANCH="microcode"
echo "${ARC_BUILD}" >files/p1/ARC-BUILD
echo "${ARC_VERSION}" >files/p1/ARC-VERSION
echo "${ARC_BRANCH}" >files/p1/ARC-BRANCH
echo "ARC_BUILD=${ARC_BUILD}" >> $GITHUB_ENV
echo "ARC_VERSION=${ARC_VERSION}" >> $GITHUB_ENV
echo "ARC_BRANCH=${ARC_BRANCH}" >> $GITHUB_ENV
echo "Create Arc Image"
IMAGE_FILE="arc.img"
gzip -dc "files/initrd/opt/arc/grub.img.gz" >"${IMAGE_FILE}"
fdisk -l "${IMAGE_FILE}"
LOOPX=$(sudo losetup -f)
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
echo "Mounting Image File"
mkdir -p "/tmp/p1"
mkdir -p "/tmp/p3"
sudo mount ${LOOPX}p1 "/tmp/p1"
sudo mount ${LOOPX}p3 "/tmp/p3"
[ ! -f "brm/bzImage-arc" ] || [ ! -f "brm/initrd-arc" ] && return 1
echo "Repack initrd"
cp -f "brm/bzImage-arc" "files/p3/bzImage-arc"
repackInitrd "brm/initrd-arc" "files/initrd" "files/p3/initrd-arc"
echo "Copying files"
sudo cp -rf "files/p1/"* "/tmp/p1"
sudo cp -rf "files/p3/"* "/tmp/p3"
sudo sync
echo "Unmount image file"
sudo umount "/tmp/p1"
sudo umount "/tmp/p3"
rmdir "/tmp/p1"
rmdir "/tmp/p3"
sudo losetup --detach ${LOOPX}
echo "Image Converter"
qemu-img convert -p -f raw -O vmdk ${IMAGE_FILE} arc-dyn.vmdk
qemu-img convert -p -f raw -o subformat=monolithicFlat -O vmdk ${IMAGE_FILE} arc.vmdk
echo "Create Arc vhd"
createvmc "arc.vmc"
qemu-img convert -p -f raw -O vpc ${IMAGE_FILE} arc.vhd
echo "Create Arc ova"
convertova "${IMAGE_FILE}" "arc.ova"
# Zip image and generate checksum
- name: Pack minimal Image
if: ${{ inputs.minimal }}
run: |
if [ -n "${{ env.ARC_VERSION }}" ]; then
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.img.zip" arc.img
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-dyn.zip" arc-dyn.vmdk
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vmdk-flat.zip" arc.vmdk arc-flat.vmdk
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.vhd.zip" arc.vhd arc.vmc
zip -9 "arc-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.ova.zip" arc.ova
(cd files && zip -r ../update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.zip ./p1 ./p3)
sha256sum update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.zip >"update-${{ env.ARC_VERSION }}-${{ env.ARC_BRANCH }}.hash"
fi
# Publish a release if is a tag
- name: Release
if: success() && env.ARC_VERSION != ''
uses: ncipollo/release-action@v1
with:
tag: ${{ env.ARC_VERSION }}
prerelease: ${{ inputs.prerelease }}
makeLatest: ${{ inputs.latest }}
allowUpdates: true
body: |
### Note:
- ${{ inputs.notice }}
### Information:
- Changelog is available in my Discord
- Discord Account for Arc Patch needed
### Versions:
${{ inputs.minimal && '- minimal: full image, all dependencies included (reduced size, faster boot)' || '' }}
${{ inputs.microcode && '- microcode: minimal + additional microcode updates' || '' }}
${{ inputs.extended && '- extended: full image, all dependencies included (new features to test)' || '' }}
### Dependencies:
- Addons: ${{ env.ADDONTAG }}
- Modules: ${{ env.MODULETAG }}
- Configs: ${{ env.CONFIGTAG }}
- Patches: ${{ env.PATCHTAG }}
- Custom: ${{ env.CUSTOMTAG }}
- LKMs: ${{ env.LKMTAG }}
${{ inputs.minimal && format('- Buildroot minimal: {0}', env.BRSTAG) || '' }}
${{ inputs.microcode && format('- Buildroot microcode: {0}', env.BRMTAG) || '' }}
${{ inputs.extended && format('- Buildroot extended: {0}', env.BRXTAG) || '' }}
### Release
- ${{ env.BUILD_TIME }}
artifacts: |
arc-*.zip
update-*.zip
update-*.hash

316
.github/workflows/custom.yml vendored Normal file
View File

@@ -0,0 +1,316 @@
#
# Copyright (C) 2023 AuxXxilium <https://github.com/AuxXxilium>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
name: Custom Build
on:
issues:
types:
- labeled
jobs:
build:
if: github.event.label.name == 'custom'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@main
- name: Init Env
run: |
git config --global user.email "info@auxxxilium.tech"
git config --global user.name "AuxXxilium"
sudo timedatectl set-timezone "Europe/Berlin"
- name: Check Custom
shell: python
run: |
# -*- coding: utf-8 -*-
import json, subprocess
def set_output(name, value):
subprocess.call(["echo '{}={}' >> $GITHUB_ENV".format(name, value)], shell=True)
issuetitle = ${{ toJSON(github.event.issue.title) }};
issuebody = ${{ toJSON(github.event.issue.body) }};
MODEL = ''
PRODUCTVER = ''
ADDONS = ''
KERNEL = ''
FORMAT = ''
BRANCH = ''
try:
jsonbody = json.loads(issuebody)
MODEL = jsonbody.get('model', '')
PRODUCTVER = jsonbody.get('version', '')
ADDONS = jsonbody.get('addons', '')
KERNEL = jsonbody.get('kernel', '')
FORMAT = jsonbody.get('format', '')
BRANCH = jsonbody.get('branch', '')
except ValueError as e:
pass
set_output("MODEL", MODEL)
set_output("PRODUCTVER", PRODUCTVER)
set_output("ADDONS", ADDONS)
set_output("KERNEL", KERNEL)
set_output("FORMAT", FORMAT)
set_output("BRANCH", BRANCH)
# calculates the version number and push
- name: Calculate Version
run: |
# Calculate Version
VERSION="`date +'%y.%-m.%-d'`-custom"
echo "Version: ${VERSION}"
echo "VERSION=${VERSION}" >> $GITHUB_ENV
- name: Update Comment Building
id: comment
uses: actions-cool/issues-helper@v3
with:
actions: 'create-comment'
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
body: |
Hi @${{ github.event.issue.user.login }}.
building arc-${{ env.MODEL }}-${{ env.VERSION }}, it will be uploaded here and sent to your email later..
> ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
----
# Install dependencies
- name: Install Dependencies
run: |
sudo apt update
sudo apt install -y jq gawk cpio gettext libelf-dev qemu-utils busybox dialog curl sed
sudo pip install -r scripts/requirements.txt
sudo snap install yq
# Build incremental
- name: Build image
run: |
. scripts/func.sh
function writeConfigKey() {
[ "${2}" = "{}" ] && sudo yq eval '.'${1}' = {}' --inplace "${3}" 2>/dev/null || sudo yq eval '.'${1}' = "'"${2}"'"' --inplace "${3}" 2>/dev/null
}
TAG="$(curl -m 5 -kL https://api.github.com/repos/AuxXxilium/arc/releases/latest | grep "tag_name" | awk '{print substr($2, 2, length($2)-3)}')"
curl -kL "https://github.com/AuxXxilium/arc/releases/download/${TAG}/arc-${TAG}-${{ env.BRANCH }}.img.zip" -o "/tmp/arc.img.zip"
unzip -o "/tmp/arc.img.zip" -d "/tmp"
echo "Modify Arc Image"
IMAGE_FILE="/tmp/arc.img"
fdisk -l "${IMAGE_FILE}"
LOOPX=$(sudo losetup -f)
sudo losetup -P "${LOOPX}" "${IMAGE_FILE}"
echo "Mounting image file"
mkdir -p "/tmp/p1"
mkdir -p "/tmp/p3"
sudo mount ${LOOPX}p1 "/tmp/p1"
sudo mount ${LOOPX}p3 "/tmp/p3"
echo "Set Custom Config"
PRESET_CONFIG_FILE="/tmp/p1/user-config.yml"
sudo touch "${PRESET_CONFIG_FILE}"
MODEL="${{ env.MODEL }}"
writeConfigKey "model" "${MODEL}" "${PRESET_CONFIG_FILE}"
PRODUCTVER="${{ env.PRODUCTVER }}"
PJ="$(python scripts/functions.py getpats4mv -m "${MODEL}" -v "${PRODUCTVER:0:3}")"
PAT_URL=$(echo "${PJ}" | jq -r ".\"${PRODUCTVER}\".url")
PAT_HASH=$(echo "${PJ}" | jq -r ".\"${PRODUCTVER}\".sum")
writeConfigKey "productver" "${PRODUCTVER:0:3}" "${PRESET_CONFIG_FILE}"
writeConfigKey "paturl" "${PAT_URL}" "${PRESET_CONFIG_FILE}"
writeConfigKey "pathash" "${PAT_HASH}" "${PRESET_CONFIG_FILE}"
if [ "${{ env.MODEL }}" = "SA6400" ]; then
writeConfigKey "kernel" "${{ env.KERNEL }}" "${PRESET_CONFIG_FILE}"
fi
writeConfigKey "addons" "{}" "${PRESET_CONFIG_FILE}"
if [ -n "${{ env.ADDONS }}" ]; then
for A in $(echo "${{ env.ADDONS }}" | tr ',' ' ' | sed 's/\[//g' | sed 's/\]//g'); do
VALUE=""
writeConfigKey "addons.\"${A}\"" "${VALUE}" "${PRESET_CONFIG_FILE}"
done
fi
writeConfigKey "automated" "true" "${PRESET_CONFIG_FILE}"
echo "$(cat "${PRESET_CONFIG_FILE}")"
sudo echo "arc-${MODEL}-${PRODUCTVER:0:3}-${TAG}" >"/tmp/automated"
sudo mv -f "/tmp/automated" "/tmp/p3/automated"
DSM_FILE="${PAT_HASH}.tar"
DSM_URL="https://raw.githubusercontent.com/AuxXxilium/arc-dsm/main/files/${MODEL/+/%2B}/${PRODUCTVER:0:3}/${PAT_HASH}.tar"
sudo curl -skL "${DSM_URL}" -o "/tmp/${DSM_FILE}"
[ -f "/tmp/${DSM_FILE}" ] && echo "dsm: download successful" || exit 1
sudo mkdir -p "/tmp/p3/users"
sudo mv -f "/tmp/${DSM_FILE}" "/tmp/p3/users/${DSM_FILE}"
echo "Syncing files"
sync
echo "Unmount image file"
sudo umount "/tmp/p1"
sudo umount "/tmp/p3"
rmdir "/tmp/p1"
rmdir "/tmp/p3"
sudo losetup --detach ${LOOPX}
cp -f "${IMAGE_FILE}" "arc.img"
if [ "${{ env.FORMAT }}" = "dyn" ]; then
echo "Image Converter -> dyn"
qemu-img convert arc.img -O vmdk -o adapter_type=lsilogic,compat6 arc-dyn.vmdk
elif [ "${{ env.FORMAT }}" = "flat" ]; then
echo "Image Converter -> flat"
qemu-img convert arc.img -O vmdk -o adapter_type=lsilogic,subformat=monolithicFlat,compat6 arc.vmdk
elif [ "${{ env.FORMAT }}" = "vhdx" ]; then
echo "Image Converter -> vhdx"
qemu-img convert arc.img -O vhdx -o subformat=dynamic arc.vhdx
elif [ "${{ env.FORMAT }}" = "ova" ]; then
echo "Image Converter -> ova"
convertova "arc.img" "arc.ova"
fi
# Zip image and generate checksum
- name: Pack
run: |
if [ "${{ env.FORMAT }}" = "img" ]; then
zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.img.zip" arc.img
UPLOAD="$(curl -k -F "file=@arc-${{ env.MODEL }}-${{ env.VERSION }}.img.zip" "https://file.io")"
if ! echo "${UPLOAD}" | grep -oP '"link":\s*"\K[^"]+'; then
echo "Upload failed"
exit 1
fi
elif [ "${{ env.FORMAT }}" = "dyn" ]; then
zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.vmdk-dyn.zip" arc-dyn.vmdk
UPLOAD="$(curl -k -F "file=@arc-${{ env.MODEL }}-${{ env.VERSION }}.vmdk-dyn.zip" "https://file.io")"
if ! echo "${UPLOAD}" | grep -oP '"link":\s*"\K[^"]+'; then
echo "Upload failed"
exit 1
fi
elif [ "${{ env.FORMAT }}" = "flat" ]; then
zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.vmdk-flat.zip" arc.vmdk arc-flat.vmdk
UPLOAD="$(curl -k -F "file=@arc-${{ env.MODEL }}-${{ env.VERSION }}.vmdk-flat.zip" "https://file.io")"
if ! echo "${UPLOAD}" | grep -oP '"link":\s*"\K[^"]+'; then
echo "Upload failed"
exit 1
fi
elif [ "${{ env.FORMAT }}" = "vhdx" ]; then
zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.vhdx.zip" arc.vhdx
UPLOAD="$(curl -k -F "file=@arc-${{ env.MODEL }}-${{ env.VERSION }}.vhdx.zip" "https://file.io")"
if ! echo "${UPLOAD}" | grep -oP '"link":\s*"\K[^"]+'; then
echo "Upload failed"
exit 1
fi
elif [ "${{ env.FORMAT }}" = "ova" ]; then
zip -9 "arc-${{ env.MODEL }}-${{ env.VERSION }}.ova.zip" arc.ova
UPLOAD="$(curl -k -F "file=@arc-${{ env.MODEL }}-${{ env.VERSION }}.ova.zip" "https://file.io")"
if ! echo "${UPLOAD}" | grep -oP '"link":\s*"\K[^"]+'; then
echo "Upload failed"
exit 1
fi
fi
EMAIL=$(curl -s -H "Authorization: token ${{ secrets.ACTION }}" "https://api.github.com/users/${{ github.event.issue.user.login }}" | jq -r '.email')
FIOURL="$(echo "${UPLOAD}" | grep -oP '"link":\s*"\K[^"]+')"
echo "EMAIL=${EMAIL}" >> $GITHUB_ENV
echo "FIOURL=${FIOURL}" >> $GITHUB_ENV
- name: Send mail
if: success() && env.EMAIL != 'null'
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.gmail.com
server_port: 587
username: ${{ secrets.MAIL_USERNAME }}
password: ${{ secrets.MAIL_PASSWORD }}
subject: arc-${{ env.model }}-${{ env.VERSION }}
to: ${{ env.EMAIL }}
from: ${{ secrets.MAIL_USERNAME }}
body: |
${{ env.FIOURL }}
- name: Update Comment Success
if: success()
uses: actions-cool/issues-helper@v3
with:
actions: 'update-comment'
token: ${{ secrets.GITHUB_TOKEN }}
comment-id: ${{ steps.comment.outputs.comment-id }}
update-mode: replace
body: |
Hi @${{ github.event.issue.user.login }}.
arc-${{ env.MODEL }}-${{ env.VERSION }} is ready to download: ${{ env.FIOURL }}
> ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
If this isn't working, do not use customized Versions!
----
- name: Update Comment Fail
if: failure()
uses: actions-cool/issues-helper@v3
with:
actions: 'update-comment'
token: ${{ secrets.GITHUB_TOKEN }}
comment-id: ${{ steps.comment.outputs.comment-id }}
update-mode: replace
body: |
Hi @${{ github.event.issue.user.login }}.
arc-${{ env.MODEL }}-${{ env.PRODUCTVER }}-${{ env.VERSION }} failed to build and package, please try again later.
> ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
----
- name: Close Issues
if: success()
uses: actions-cool/issues-helper@v3
with:
actions: 'close-issue'
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
comment:
if: github.event.label.name == 'bug'
runs-on: ubuntu-latest
steps:
- name: Init Env
run: |
git config --global user.email "info@auxxxilium.tech"
git config --global user.name "AuxXxilium"
sudo timedatectl set-timezone "Europe/Berlin"
- name: Check Issues
run: |
if echo "${{ github.event.issue.body }}" | grep -q "Screenshots"; then
echo "FALG=true" >> $GITHUB_ENV
else
echo "FALG=false" >> $GITHUB_ENV
fi
- name: Create Issues comment
if: env.FALG == 'false'
uses: actions-cool/issues-helper@v3
with:
actions: "create-comment"
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}
body: |
**Describe the Bug**
A clear and concise description of what the bug is.
**Screenshots**
Screenshot the Systeminfo (Arc - Sysinfo) or use new "Full Sysinfo - Upload" Function provide the Code!!! <- IMPORTANT
**Hardware**
Add your Hardware Informations here. CPU / Board / Networkcontroller / Storagecontroller / ...
- name: Close Issues
if: env.FALG == 'false'
uses: actions-cool/issues-helper@v3
with:
actions: 'close-issue'
token: ${{ secrets.GITHUB_TOKEN }}
issue-number: ${{ github.event.issue.number }}

95
.github/workflows/data.yml vendored Normal file
View File

@@ -0,0 +1,95 @@
#
# Copyright (C) 2023 AuxXxilium <https://github.com/AuxXxilium> and Ing <https://github.com/wjz304>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
name: Data
on:
release:
types:
- created
workflow_dispatch:
inputs:
push:
description: "push"
default: false
type: boolean
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@main
with:
ref: page
- name: Init Env
run: |
git config --global user.email "info@auxxxilium.tech"
git config --global user.name "AuxXxilium"
sudo timedatectl set-timezone "Europe/Berlin"
sudo apt update
sudo apt install -y build-essential libtool pkgconf libzstd-dev liblzma-dev libssl-dev # kmodule dependencies
- name: Get Release Data for Arc
run: |
REPO="${{ github.server_url }}/${{ github.repository }}"
PRERELEASE="true"
TAG=""
if [ "${PRERELEASE}" = "true" ]; then
TAG="$(curl -skL --connect-timeout 10 "${REPO}/tags" | grep /refs/tags/.*\.zip | sed -E 's/.*\/refs\/tags\/(.*)\.zip.*$/\1/' | sort -rV | head -1)"
else
LATESTURL="$(curl -skL --connect-timeout 10 -w %{url_effective} -o /dev/null "${REPO}/releases/latest")"
TAG="${LATESTURL##*/}"
fi
[ "${TAG:0:1}" = "v" ] && TAG="${TAG:1}"
rm -f arc-${TAG}.img.zip
STATUS=$(curl -kL --connect-timeout 10 -w "%{http_code}" "${REPO}/releases/download/${TAG}/arc-${TAG}.img.zip" -o "arc-${TAG}.img.zip")
if [ $? -ne 0 -o ${STATUS:-0} -ne 200 ]; then
echo "Download failed"
exit 1
fi
unzip arc-${TAG}.img.zip -d "arc"
sudo ./localbuild.sh create arc/ws arc/arc.img
if [ $? -ne 0 ]; then
echo "create failed"
exit 1
fi
- name: Get data
run: |
pip install -r scripts/requirements.txt
python scripts/func.py getmodels -w "arc/ws" -j "docs/models.json"
python scripts/func.py getaddons -w "arc/ws" -j "docs/addons.json"
python scripts/func.py getmodules -w "arc/ws" -j "docs/modules.json"
python scripts/func.py getpats -w "arc/ws" -j "docs/pats.json"
- name: Upload to Artifacts
if: success()
uses: actions/upload-artifact@v4
with:
name: docs
path: |
docs/*.json
retention-days: 5
- name: Check and Push
if: success() && (inputs.push == true || github.event.action == 'created')
run: |
echo "Git push ..."
# git checkout main
git pull
status=$(git status -s | grep -E "docs" | awk '{printf " %s", $2}')
if [ -n "${status}" ]; then
git add ${status}
git commit -m "data: update $(date +%Y-%m-%d" "%H:%M:%S)"
git push -f
fi

53
.github/workflows/grub.yml vendored Normal file
View File

@@ -0,0 +1,53 @@
#
# Copyright (C) 2023 AuxXxilium <https://github.com/AuxXxilium>
#
# This is free software, licensed under the MIT License.
# See /LICENSE for more information.
#
name: Grub
on:
workflow_dispatch:
inputs:
push:
description: "push"
default: false
type: boolean
jobs:
grub:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@main
- name: Initialization environment
run : |
git config --global user.email "info@auxxxilium.tech"
git config --global user.name "AuxXxilium"
sudo timedatectl set-timezone "Europe/Berlin"
sudo apt update
sudo apt install -y autoconf automake autopoint build-essential pkg-config bison flex gettext gawk libtool dosfstools e2fsprogs
sudo apt install -y libfreetype6-dev unifont fonts-dejavu libfuse-dev libzfslinux-dev liblzma-dev libdevmapper-dev
- name: Make Grub
run: |
rm -f grub.img.gz
. scripts/grub.sh "grub-2.12" "i386-pc i386-efi x86_64-efi" "ARC"
- name: Check and Push
if: success() && inputs.push == true
run: |
if [ -f "grub.img.gz" ]; then
echo "Git push ..."
git pull
status=$(git status -s | grep -E 'grub.img.gz' | awk '{printf " %s", $2}')
if [ -n "${status}" ]; then
git add ${status}
git commit -m "grub: update $(date +%Y-%m-%d" "%H:%M:%S)"
git push -f
fi
else
echo "No change ..."
fi

20
.gitignore vendored
View File

@@ -1,7 +1,17 @@
!.gitkeep
.vscode
arpl.img*
/buildroot-2022.02.2
test.sh
docker/Dockerfile
docker/cache
arc.img
arc*.vmdk
*.zip
.buildroot
test*.sh
docker/syno-compiler/Dockerfile
cache
*.bak
*.o
/files/board/arc/p3/addons
/files/board/arc/p3/lkms
/files/board/arc/p3/modules
/files/board/arc/p3/configs
/files/board/arc/p3/extensions
/tests

674
LICENSE Normal file
View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View File

@@ -1,8 +0,0 @@
bromolow 3.10.108
apollolake 4.4.180
broadwell 4.4.180
broadwellnk 4.4.180
denverton 4.4.180
geminilake 4.4.180
v1000 4.4.180
purley 4.4.180

View File

@@ -1 +1,27 @@
# arpl
<center><img width="845" alt="arc_loader" src="https://github.com/AuxXxilium/AuxXxilium/assets/67025065/ef975a36-9f3e-4cfb-813c-402db69611e7"></center>
The Arc Loader is a customized Redpill Loader for DSM 7.x (Xpenology) with enhanced Hardwaresupport, Addons, guided(semi-automated) Installation and more. Multiple customization options are built-in. It is modified to run on different Hardware (see Wiki for more Informations).
- Commercial use is not permitted and strictly forbidden!!!
- DSM and all Parts are under Copyright / Ownership or Registered Trademark by Synology Inc.
### Bugreport
- Before you report an issue or bug please read the <a href="https://auxxxilium.tech/wiki">FAQ & Wiki</a> and make sure your setting are correct.
- If you have to report an issue or bug:
- Hardware you use (Networkchip, Sata/HBA/Raid Controller)
- Screenshot the Systeminfo (Arc - Sysinfo) or use new "Full Sysinfo - Upload" Function and provide the Code!!! <- IMPORTANT
### Links
- <a href="https://github.com/AuxXxilium">Overview</a>
- <a href="https://auxxxilium.tech/wiki">FAQ & Wiki</a>
- <a href="https://github.com/AuxXxilium/arc/releases?q=prerelease%3Afalse&expanded=true">Download latest Build</a>
### Developer
- <a href="https://github.com/AuxXxilium">AuxXxilium</a>
- <a href="https://github.com/FulcrumCode">Fulcrum</a>
### Thanks
Code is based on the work of TTG, pocopico, jumkey, fbelavenuto, wjz304 and others involved in continuing TTG's original redpill-load project.

23
TODO
View File

@@ -1,23 +0,0 @@
A fazer
- Implementar update do bzimage e ramdisk online
Concluidos:
- Generalizar código dos addons
- Implementar checagem de conflito entre addons *** Usado alternativa de ter listagem de módulos não necessários ***
- Tirar MAXDISKS dos arquivos dos modelos e adicionar menu no synoinfo para configurar máximo de HDs
- mudar na configs dos modelos os módulos builtin para módulos não necessários
- Mudar palavra "extra" para "cmdline"
- Implementar exibição de cmdline e synoinfo dos modelos
- Adicionar checagem no grub para exibir ou não menu de boot
- Bug no boot.sh, se usuário mudar a variável netif_num o script repassa os macX sem considerar o novo número de interfaces
*** TIRADO obrigatoriedade no LKM de passar esses parâmetros ***
- bug com macs, com 2 placas os MACs podem se inverter, checar isso
*** Resolvido com solução anterior ***
- Verifica se plataforma vai rodar na máquina checando as flags da CPU
- Implementar seleção da versão do LKM (dev ou prod)
- Usando TTYD para acesso via web
- Verificar se fica legal colocar na config dos modelos os addons obrigatórios como o qjs-dtb *** Usado outra maneira ***
- Implementar escolha de maxdisks
https://kb.synology.com/en-me/DSM/tutorial/What_kind_of_CPU_does_my_NAS_have

View File

@@ -1,22 +1,22 @@
# https://taskfile.dev
version: '3'
version: "3"
tasks:
build-img:
build-ext:
cmds:
- ./img-gen.sh
- git reset --hard
- git pull
- ./img-ext.sh
build-docker-img:
dir: docker
build-min:
cmds:
- ./build.sh
- git reset --hard
- git pull
- ./img-min.sh
compile-lkms:
compile-kpatch:
dir: kpatch
cmds:
- ./compile-lkm.sh
compile-addons:
dir: addons
cmds:
- ./compile-addons.sh {{.CLI_ARGS}}
- make clean all
- mv kpatch ../files/p3/system/

View File

@@ -1,6 +0,0 @@
if [ "${1}" = "rd" ]; then
echo "Installing module for Plan 9 Resource Sharing Support (9P2000)"
${INSMOD} "/modules/9pnet.ko"
${INSMOD} "/modules/9pnet_virtio.ko"
${INSMOD} "/modules/9p.ko" ${PARAMS}
fi

View File

@@ -1,28 +0,0 @@
version: 1
name: 9p
description: "Driver for Plan 9 Resource Sharing Support (9P2000)"
available-for:
bromolow-3.10.108:
install-script: &script "install.sh"
modules: true
apollolake-4.4.180:
install-script: *script
modules: true
broadwell-4.4.180:
install-script: *script
modules: true
broadwellnk-4.4.180:
install-script: *script
modules: true
denverton-4.4.180:
install-script: *script
modules: true
geminilake-4.4.180:
install-script: *script
modules: true
v1000-4.4.180:
install-script: *script
modules: true
purley-4.4.180:
install-script: *script
modules: true

View File

@@ -1,36 +0,0 @@
obj-m := 9p.o
9p-objs := \
vfs_super.o \
vfs_inode.o \
vfs_inode_dotl.o \
vfs_addr.o \
vfs_file.o \
vfs_dir.o \
vfs_dentry.o \
v9fs.o \
fid.o \
xattr.o \
xattr_user.o
9p-y += cache.o
9p-n += acl.o
obj-m := 9pnet.o
obj-m += 9pnet_virtio.o
obj-n += 9pnet_rdma.o
9pnet-objs := \
mod.o \
client.o \
error.o \
util.o \
protocol.o \
trans_fd.o \
trans_common.o \
9pnet_virtio-objs := \
trans_virtio.o
9pnet_rdma-objs := \
trans_rdma.o

View File

@@ -1,375 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <linux/module.h>
#include <linux/fs.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/posix_acl_xattr.h>
#include "xattr.h"
#include "acl.h"
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name)
{
ssize_t size;
void *value = NULL;
struct posix_acl *acl = NULL;
size = v9fs_fid_xattr_get(fid, name, NULL, 0);
if (size > 0) {
value = kzalloc(size, GFP_NOFS);
if (!value)
return ERR_PTR(-ENOMEM);
size = v9fs_fid_xattr_get(fid, name, value, size);
if (size > 0) {
acl = posix_acl_from_xattr(&init_user_ns, value, size);
if (IS_ERR(acl))
goto err_out;
}
} else if (size == -ENODATA || size == 0 ||
size == -ENOSYS || size == -EOPNOTSUPP) {
acl = NULL;
} else
acl = ERR_PTR(-EIO);
err_out:
kfree(value);
return acl;
}
int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
{
int retval = 0;
struct posix_acl *pacl, *dacl;
struct v9fs_session_info *v9ses;
v9ses = v9fs_inode2v9ses(inode);
if (((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) ||
((v9ses->flags & V9FS_ACL_MASK) != V9FS_POSIX_ACL)) {
set_cached_acl(inode, ACL_TYPE_DEFAULT, NULL);
set_cached_acl(inode, ACL_TYPE_ACCESS, NULL);
return 0;
}
/* get the default/access acl values and cache them */
dacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_DEFAULT);
pacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_ACCESS);
if (!IS_ERR(dacl) && !IS_ERR(pacl)) {
set_cached_acl(inode, ACL_TYPE_DEFAULT, dacl);
set_cached_acl(inode, ACL_TYPE_ACCESS, pacl);
} else
retval = -EIO;
if (!IS_ERR(dacl))
posix_acl_release(dacl);
if (!IS_ERR(pacl))
posix_acl_release(pacl);
return retval;
}
static struct posix_acl *v9fs_get_cached_acl(struct inode *inode, int type)
{
struct posix_acl *acl;
/*
* 9p Always cache the acl value when
* instantiating the inode (v9fs_inode_from_fid)
*/
acl = get_cached_acl(inode, type);
BUG_ON(acl == ACL_NOT_CACHED);
return acl;
}
struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type)
{
struct v9fs_session_info *v9ses;
v9ses = v9fs_inode2v9ses(inode);
if (((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) ||
((v9ses->flags & V9FS_ACL_MASK) != V9FS_POSIX_ACL)) {
/*
* On access = client and acl = on mode get the acl
* values from the server
*/
return NULL;
}
return v9fs_get_cached_acl(inode, type);
}
static int v9fs_set_acl(struct p9_fid *fid, int type, struct posix_acl *acl)
{
int retval;
char *name;
size_t size;
void *buffer;
if (!acl)
return 0;
/* Set a setxattr request to server */
size = posix_acl_xattr_size(acl->a_count);
buffer = kmalloc(size, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
retval = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
if (retval < 0)
goto err_free_out;
switch (type) {
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
break;
case ACL_TYPE_DEFAULT:
name = POSIX_ACL_XATTR_DEFAULT;
break;
default:
BUG();
}
retval = v9fs_fid_xattr_set(fid, name, buffer, size, 0);
err_free_out:
kfree(buffer);
return retval;
}
int v9fs_acl_chmod(struct inode *inode, struct p9_fid *fid)
{
int retval = 0;
struct posix_acl *acl;
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS);
if (acl) {
retval = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
if (retval)
return retval;
set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
retval = v9fs_set_acl(fid, ACL_TYPE_ACCESS, acl);
posix_acl_release(acl);
}
return retval;
}
int v9fs_set_create_acl(struct inode *inode, struct p9_fid *fid,
struct posix_acl *dacl, struct posix_acl *acl)
{
set_cached_acl(inode, ACL_TYPE_DEFAULT, dacl);
set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
v9fs_set_acl(fid, ACL_TYPE_DEFAULT, dacl);
v9fs_set_acl(fid, ACL_TYPE_ACCESS, acl);
return 0;
}
void v9fs_put_acl(struct posix_acl *dacl,
struct posix_acl *acl)
{
posix_acl_release(dacl);
posix_acl_release(acl);
}
int v9fs_acl_mode(struct inode *dir, umode_t *modep,
struct posix_acl **dpacl, struct posix_acl **pacl)
{
int retval = 0;
umode_t mode = *modep;
struct posix_acl *acl = NULL;
if (!S_ISLNK(mode)) {
acl = v9fs_get_cached_acl(dir, ACL_TYPE_DEFAULT);
if (IS_ERR(acl))
return PTR_ERR(acl);
if (!acl)
mode &= ~current_umask();
}
if (acl) {
if (S_ISDIR(mode))
*dpacl = posix_acl_dup(acl);
retval = posix_acl_create(&acl, GFP_NOFS, &mode);
if (retval < 0)
return retval;
if (retval > 0)
*pacl = acl;
else
posix_acl_release(acl);
}
*modep = mode;
return 0;
}
static int v9fs_remote_get_acl(struct dentry *dentry, const char *name,
void *buffer, size_t size, int type)
{
char *full_name;
switch (type) {
case ACL_TYPE_ACCESS:
full_name = POSIX_ACL_XATTR_ACCESS;
break;
case ACL_TYPE_DEFAULT:
full_name = POSIX_ACL_XATTR_DEFAULT;
break;
default:
BUG();
}
return v9fs_xattr_get(dentry, full_name, buffer, size);
}
static int v9fs_xattr_get_acl(struct dentry *dentry, const char *name,
void *buffer, size_t size, int type)
{
struct v9fs_session_info *v9ses;
struct posix_acl *acl;
int error;
if (strcmp(name, "") != 0)
return -EINVAL;
v9ses = v9fs_dentry2v9ses(dentry);
/*
* We allow set/get/list of acl when access=client is not specified
*/
if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
return v9fs_remote_get_acl(dentry, name, buffer, size, type);
acl = v9fs_get_cached_acl(dentry->d_inode, type);
if (IS_ERR(acl))
return PTR_ERR(acl);
if (acl == NULL)
return -ENODATA;
error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
posix_acl_release(acl);
return error;
}
static int v9fs_remote_set_acl(struct dentry *dentry, const char *name,
const void *value, size_t size,
int flags, int type)
{
char *full_name;
switch (type) {
case ACL_TYPE_ACCESS:
full_name = POSIX_ACL_XATTR_ACCESS;
break;
case ACL_TYPE_DEFAULT:
full_name = POSIX_ACL_XATTR_DEFAULT;
break;
default:
BUG();
}
return v9fs_xattr_set(dentry, full_name, value, size, flags);
}
static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
const void *value, size_t size,
int flags, int type)
{
int retval;
struct posix_acl *acl;
struct v9fs_session_info *v9ses;
struct inode *inode = dentry->d_inode;
if (strcmp(name, "") != 0)
return -EINVAL;
v9ses = v9fs_dentry2v9ses(dentry);
/*
* set the attribute on the remote. Without even looking at the
* xattr value. We leave it to the server to validate
*/
if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
return v9fs_remote_set_acl(dentry, name,
value, size, flags, type);
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
if (!inode_owner_or_capable(inode))
return -EPERM;
if (value) {
/* update the cached acl value */
acl = posix_acl_from_xattr(&init_user_ns, value, size);
if (IS_ERR(acl))
return PTR_ERR(acl);
else if (acl) {
retval = posix_acl_valid(acl);
if (retval)
goto err_out;
}
} else
acl = NULL;
switch (type) {
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
if (acl) {
struct iattr iattr;
retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
if (retval)
goto err_out;
if (!acl) {
/*
* ACL can be represented
* by the mode bits. So don't
* update ACL.
*/
value = NULL;
size = 0;
}
iattr.ia_valid = ATTR_MODE;
/* FIXME should we update ctime ?
* What is the following setxattr update the
* mode ?
*/
v9fs_vfs_setattr_dotl(dentry, &iattr);
}
break;
case ACL_TYPE_DEFAULT:
name = POSIX_ACL_XATTR_DEFAULT;
if (!S_ISDIR(inode->i_mode)) {
retval = acl ? -EINVAL : 0;
goto err_out;
}
break;
default:
BUG();
}
retval = v9fs_xattr_set(dentry, name, value, size, flags);
if (!retval)
set_cached_acl(inode, type, acl);
err_out:
posix_acl_release(acl);
return retval;
}
const struct xattr_handler v9fs_xattr_acl_access_handler = {
.prefix = POSIX_ACL_XATTR_ACCESS,
.flags = ACL_TYPE_ACCESS,
.get = v9fs_xattr_get_acl,
.set = v9fs_xattr_set_acl,
};
const struct xattr_handler v9fs_xattr_acl_default_handler = {
.prefix = POSIX_ACL_XATTR_DEFAULT,
.flags = ACL_TYPE_DEFAULT,
.get = v9fs_xattr_get_acl,
.set = v9fs_xattr_set_acl,
};

View File

@@ -1,55 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef FS_9P_ACL_H
#define FS_9P_ACL_H
#ifdef CONFIG_9P_FS_POSIX_ACL
extern int v9fs_get_acl(struct inode *, struct p9_fid *);
extern struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type);
extern int v9fs_acl_chmod(struct inode *, struct p9_fid *);
extern int v9fs_set_create_acl(struct inode *, struct p9_fid *,
struct posix_acl *, struct posix_acl *);
extern int v9fs_acl_mode(struct inode *dir, umode_t *modep,
struct posix_acl **dpacl, struct posix_acl **pacl);
extern void v9fs_put_acl(struct posix_acl *dacl, struct posix_acl *acl);
#else
#define v9fs_iop_get_acl NULL
static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
{
return 0;
}
static inline int v9fs_acl_chmod(struct inode *inode, struct p9_fid *fid)
{
return 0;
}
static inline int v9fs_set_create_acl(struct inode *inode,
struct p9_fid *fid,
struct posix_acl *dacl,
struct posix_acl *acl)
{
return 0;
}
static inline void v9fs_put_acl(struct posix_acl *dacl,
struct posix_acl *acl)
{
}
static inline int v9fs_acl_mode(struct inode *dir, umode_t *modep,
struct posix_acl **dpacl,
struct posix_acl **pacl)
{
return 0;
}
#endif
#endif /* FS_9P_XATTR_H */

View File

@@ -1,415 +0,0 @@
/*
* V9FS cache definitions.
*
* Copyright (C) 2009 by Abhishek Kulkarni <adkulkar@umail.iu.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/jiffies.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <net/9p/9p.h>
#include "v9fs.h"
#include "cache.h"
#define CACHETAG_LEN 11
struct fscache_netfs v9fs_cache_netfs = {
.name = "9p",
.version = 0,
};
/**
* v9fs_random_cachetag - Generate a random tag to be associated
* with a new cache session.
*
* The value of jiffies is used for a fairly randomly cache tag.
*/
static
int v9fs_random_cachetag(struct v9fs_session_info *v9ses)
{
v9ses->cachetag = kmalloc(CACHETAG_LEN, GFP_KERNEL);
if (!v9ses->cachetag)
return -ENOMEM;
return scnprintf(v9ses->cachetag, CACHETAG_LEN, "%lu", jiffies);
}
static uint16_t v9fs_cache_session_get_key(const void *cookie_netfs_data,
void *buffer, uint16_t bufmax)
{
struct v9fs_session_info *v9ses;
uint16_t klen = 0;
v9ses = (struct v9fs_session_info *)cookie_netfs_data;
p9_debug(P9_DEBUG_FSC, "session %p buf %p size %u\n",
v9ses, buffer, bufmax);
if (v9ses->cachetag)
klen = strlen(v9ses->cachetag);
if (klen > bufmax)
return 0;
memcpy(buffer, v9ses->cachetag, klen);
p9_debug(P9_DEBUG_FSC, "cache session tag %s\n", v9ses->cachetag);
return klen;
}
const struct fscache_cookie_def v9fs_cache_session_index_def = {
.name = "9P.session",
.type = FSCACHE_COOKIE_TYPE_INDEX,
.get_key = v9fs_cache_session_get_key,
};
void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses)
{
/* If no cache session tag was specified, we generate a random one. */
if (!v9ses->cachetag)
v9fs_random_cachetag(v9ses);
v9ses->fscache = fscache_acquire_cookie(v9fs_cache_netfs.primary_index,
&v9fs_cache_session_index_def,
v9ses);
p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n",
v9ses, v9ses->fscache);
}
void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses)
{
p9_debug(P9_DEBUG_FSC, "session %p put cookie %p\n",
v9ses, v9ses->fscache);
fscache_relinquish_cookie(v9ses->fscache, 0);
v9ses->fscache = NULL;
}
static uint16_t v9fs_cache_inode_get_key(const void *cookie_netfs_data,
void *buffer, uint16_t bufmax)
{
const struct v9fs_inode *v9inode = cookie_netfs_data;
memcpy(buffer, &v9inode->qid.path, sizeof(v9inode->qid.path));
p9_debug(P9_DEBUG_FSC, "inode %p get key %llu\n",
&v9inode->vfs_inode, v9inode->qid.path);
return sizeof(v9inode->qid.path);
}
static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data,
uint64_t *size)
{
const struct v9fs_inode *v9inode = cookie_netfs_data;
*size = i_size_read(&v9inode->vfs_inode);
p9_debug(P9_DEBUG_FSC, "inode %p get attr %llu\n",
&v9inode->vfs_inode, *size);
}
static uint16_t v9fs_cache_inode_get_aux(const void *cookie_netfs_data,
void *buffer, uint16_t buflen)
{
const struct v9fs_inode *v9inode = cookie_netfs_data;
memcpy(buffer, &v9inode->qid.version, sizeof(v9inode->qid.version));
p9_debug(P9_DEBUG_FSC, "inode %p get aux %u\n",
&v9inode->vfs_inode, v9inode->qid.version);
return sizeof(v9inode->qid.version);
}
static enum
fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
const void *buffer,
uint16_t buflen)
{
const struct v9fs_inode *v9inode = cookie_netfs_data;
if (buflen != sizeof(v9inode->qid.version))
return FSCACHE_CHECKAUX_OBSOLETE;
if (memcmp(buffer, &v9inode->qid.version,
sizeof(v9inode->qid.version)))
return FSCACHE_CHECKAUX_OBSOLETE;
return FSCACHE_CHECKAUX_OKAY;
}
static void v9fs_cache_inode_now_uncached(void *cookie_netfs_data)
{
struct v9fs_inode *v9inode = cookie_netfs_data;
struct pagevec pvec;
pgoff_t first;
int loop, nr_pages;
pagevec_init(&pvec, 0);
first = 0;
for (;;) {
nr_pages = pagevec_lookup(&pvec, v9inode->vfs_inode.i_mapping,
first,
PAGEVEC_SIZE - pagevec_count(&pvec));
if (!nr_pages)
break;
for (loop = 0; loop < nr_pages; loop++)
ClearPageFsCache(pvec.pages[loop]);
first = pvec.pages[nr_pages - 1]->index + 1;
pvec.nr = nr_pages;
pagevec_release(&pvec);
cond_resched();
}
}
const struct fscache_cookie_def v9fs_cache_inode_index_def = {
.name = "9p.inode",
.type = FSCACHE_COOKIE_TYPE_DATAFILE,
.get_key = v9fs_cache_inode_get_key,
.get_attr = v9fs_cache_inode_get_attr,
.get_aux = v9fs_cache_inode_get_aux,
.check_aux = v9fs_cache_inode_check_aux,
.now_uncached = v9fs_cache_inode_now_uncached,
};
void v9fs_cache_inode_get_cookie(struct inode *inode)
{
struct v9fs_inode *v9inode;
struct v9fs_session_info *v9ses;
if (!S_ISREG(inode->i_mode))
return;
v9inode = V9FS_I(inode);
if (v9inode->fscache)
return;
v9ses = v9fs_inode2v9ses(inode);
v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
&v9fs_cache_inode_index_def,
v9inode);
p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",
inode, v9inode->fscache);
}
void v9fs_cache_inode_put_cookie(struct inode *inode)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
if (!v9inode->fscache)
return;
p9_debug(P9_DEBUG_FSC, "inode %p put cookie %p\n",
inode, v9inode->fscache);
fscache_relinquish_cookie(v9inode->fscache, 0);
v9inode->fscache = NULL;
}
void v9fs_cache_inode_flush_cookie(struct inode *inode)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
if (!v9inode->fscache)
return;
p9_debug(P9_DEBUG_FSC, "inode %p flush cookie %p\n",
inode, v9inode->fscache);
fscache_relinquish_cookie(v9inode->fscache, 1);
v9inode->fscache = NULL;
}
void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
struct p9_fid *fid;
if (!v9inode->fscache)
return;
spin_lock(&v9inode->fscache_lock);
fid = filp->private_data;
if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
v9fs_cache_inode_flush_cookie(inode);
else
v9fs_cache_inode_get_cookie(inode);
spin_unlock(&v9inode->fscache_lock);
}
void v9fs_cache_inode_reset_cookie(struct inode *inode)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
struct v9fs_session_info *v9ses;
struct fscache_cookie *old;
if (!v9inode->fscache)
return;
old = v9inode->fscache;
spin_lock(&v9inode->fscache_lock);
fscache_relinquish_cookie(v9inode->fscache, 1);
v9ses = v9fs_inode2v9ses(inode);
v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
&v9fs_cache_inode_index_def,
v9inode);
p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n",
inode, old, v9inode->fscache);
spin_unlock(&v9inode->fscache_lock);
}
int __v9fs_fscache_release_page(struct page *page, gfp_t gfp)
{
struct inode *inode = page->mapping->host;
struct v9fs_inode *v9inode = V9FS_I(inode);
BUG_ON(!v9inode->fscache);
return fscache_maybe_release_page(v9inode->fscache, page, gfp);
}
void __v9fs_fscache_invalidate_page(struct page *page)
{
struct inode *inode = page->mapping->host;
struct v9fs_inode *v9inode = V9FS_I(inode);
BUG_ON(!v9inode->fscache);
if (PageFsCache(page)) {
fscache_wait_on_page_write(v9inode->fscache, page);
BUG_ON(!PageLocked(page));
fscache_uncache_page(v9inode->fscache, page);
}
}
static void v9fs_vfs_readpage_complete(struct page *page, void *data,
int error)
{
if (!error)
SetPageUptodate(page);
unlock_page(page);
}
/**
* __v9fs_readpage_from_fscache - read a page from cache
*
* Returns 0 if the pages are in cache and a BIO is submitted,
* 1 if the pages are not in cache and -error otherwise.
*/
int __v9fs_readpage_from_fscache(struct inode *inode, struct page *page)
{
int ret;
const struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
if (!v9inode->fscache)
return -ENOBUFS;
ret = fscache_read_or_alloc_page(v9inode->fscache,
page,
v9fs_vfs_readpage_complete,
NULL,
GFP_KERNEL);
switch (ret) {
case -ENOBUFS:
case -ENODATA:
p9_debug(P9_DEBUG_FSC, "page/inode not in cache %d\n", ret);
return 1;
case 0:
p9_debug(P9_DEBUG_FSC, "BIO submitted\n");
return ret;
default:
p9_debug(P9_DEBUG_FSC, "ret %d\n", ret);
return ret;
}
}
/**
* __v9fs_readpages_from_fscache - read multiple pages from cache
*
* Returns 0 if the pages are in cache and a BIO is submitted,
* 1 if the pages are not in cache and -error otherwise.
*/
int __v9fs_readpages_from_fscache(struct inode *inode,
struct address_space *mapping,
struct list_head *pages,
unsigned *nr_pages)
{
int ret;
const struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_FSC, "inode %p pages %u\n", inode, *nr_pages);
if (!v9inode->fscache)
return -ENOBUFS;
ret = fscache_read_or_alloc_pages(v9inode->fscache,
mapping, pages, nr_pages,
v9fs_vfs_readpage_complete,
NULL,
mapping_gfp_mask(mapping));
switch (ret) {
case -ENOBUFS:
case -ENODATA:
p9_debug(P9_DEBUG_FSC, "pages/inodes not in cache %d\n", ret);
return 1;
case 0:
BUG_ON(!list_empty(pages));
BUG_ON(*nr_pages != 0);
p9_debug(P9_DEBUG_FSC, "BIO submitted\n");
return ret;
default:
p9_debug(P9_DEBUG_FSC, "ret %d\n", ret);
return ret;
}
}
/**
* __v9fs_readpage_to_fscache - write a page to the cache
*
*/
void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page)
{
int ret;
const struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
ret = fscache_write_page(v9inode->fscache, page, GFP_KERNEL);
p9_debug(P9_DEBUG_FSC, "ret = %d\n", ret);
if (ret != 0)
v9fs_uncache_page(inode, page);
}
/*
* wait for a page to complete writing to the cache
*/
void __v9fs_fscache_wait_on_page_write(struct inode *inode, struct page *page)
{
const struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
if (PageFsCache(page))
fscache_wait_on_page_write(v9inode->fscache, page);
}

View File

@@ -1,139 +0,0 @@
/*
* V9FS cache definitions.
*
* Copyright (C) 2009 by Abhishek Kulkarni <adkulkar@umail.iu.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#ifndef _9P_CACHE_H
#ifdef CONFIG_9P_FSCACHE
#include <linux/fscache.h>
#include <linux/spinlock.h>
extern struct fscache_netfs v9fs_cache_netfs;
extern const struct fscache_cookie_def v9fs_cache_session_index_def;
extern const struct fscache_cookie_def v9fs_cache_inode_index_def;
extern void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses);
extern void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses);
extern void v9fs_cache_inode_get_cookie(struct inode *inode);
extern void v9fs_cache_inode_put_cookie(struct inode *inode);
extern void v9fs_cache_inode_flush_cookie(struct inode *inode);
extern void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp);
extern void v9fs_cache_inode_reset_cookie(struct inode *inode);
extern int __v9fs_cache_register(void);
extern void __v9fs_cache_unregister(void);
extern int __v9fs_fscache_release_page(struct page *page, gfp_t gfp);
extern void __v9fs_fscache_invalidate_page(struct page *page);
extern int __v9fs_readpage_from_fscache(struct inode *inode,
struct page *page);
extern int __v9fs_readpages_from_fscache(struct inode *inode,
struct address_space *mapping,
struct list_head *pages,
unsigned *nr_pages);
extern void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page);
extern void __v9fs_fscache_wait_on_page_write(struct inode *inode,
struct page *page);
static inline int v9fs_fscache_release_page(struct page *page,
gfp_t gfp)
{
return __v9fs_fscache_release_page(page, gfp);
}
static inline void v9fs_fscache_invalidate_page(struct page *page)
{
__v9fs_fscache_invalidate_page(page);
}
static inline int v9fs_readpage_from_fscache(struct inode *inode,
struct page *page)
{
return __v9fs_readpage_from_fscache(inode, page);
}
static inline int v9fs_readpages_from_fscache(struct inode *inode,
struct address_space *mapping,
struct list_head *pages,
unsigned *nr_pages)
{
return __v9fs_readpages_from_fscache(inode, mapping, pages,
nr_pages);
}
static inline void v9fs_readpage_to_fscache(struct inode *inode,
struct page *page)
{
if (PageFsCache(page))
__v9fs_readpage_to_fscache(inode, page);
}
static inline void v9fs_uncache_page(struct inode *inode, struct page *page)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
fscache_uncache_page(v9inode->fscache, page);
BUG_ON(PageFsCache(page));
}
static inline void v9fs_fscache_wait_on_page_write(struct inode *inode,
struct page *page)
{
return __v9fs_fscache_wait_on_page_write(inode, page);
}
#else /* CONFIG_9P_FSCACHE */
static inline int v9fs_fscache_release_page(struct page *page,
gfp_t gfp) {
return 1;
}
static inline void v9fs_fscache_invalidate_page(struct page *page) {}
static inline int v9fs_readpage_from_fscache(struct inode *inode,
struct page *page)
{
return -ENOBUFS;
}
static inline int v9fs_readpages_from_fscache(struct inode *inode,
struct address_space *mapping,
struct list_head *pages,
unsigned *nr_pages)
{
return -ENOBUFS;
}
static inline void v9fs_readpage_to_fscache(struct inode *inode,
struct page *page)
{}
static inline void v9fs_uncache_page(struct inode *inode, struct page *page)
{}
static inline void v9fs_fscache_wait_on_page_write(struct inode *inode,
struct page *page)
{
return;
}
#endif /* CONFIG_9P_FSCACHE */
#endif /* _9P_CACHE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,247 +0,0 @@
/*
* linux/fs/9p/error.c
*
* Error string handling
*
* Plan 9 uses error strings, Unix uses error numbers. These functions
* try to help manage that and provide for dynamically adding error
* mappings.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/list.h>
#include <linux/jhash.h>
#include <linux/errno.h>
#include <net/9p/9p.h>
/**
* struct errormap - map string errors from Plan 9 to Linux numeric ids
* @name: string sent over 9P
* @val: numeric id most closely representing @name
* @namelen: length of string
* @list: hash-table list for string lookup
*/
struct errormap {
char *name;
int val;
int namelen;
struct hlist_node list;
};
#define ERRHASHSZ 32
static struct hlist_head hash_errmap[ERRHASHSZ];
/* FixMe - reduce to a reasonable size */
static struct errormap errmap[] = {
{"Operation not permitted", EPERM},
{"wstat prohibited", EPERM},
{"No such file or directory", ENOENT},
{"directory entry not found", ENOENT},
{"file not found", ENOENT},
{"Interrupted system call", EINTR},
{"Input/output error", EIO},
{"No such device or address", ENXIO},
{"Argument list too long", E2BIG},
{"Bad file descriptor", EBADF},
{"Resource temporarily unavailable", EAGAIN},
{"Cannot allocate memory", ENOMEM},
{"Permission denied", EACCES},
{"Bad address", EFAULT},
{"Block device required", ENOTBLK},
{"Device or resource busy", EBUSY},
{"File exists", EEXIST},
{"Invalid cross-device link", EXDEV},
{"No such device", ENODEV},
{"Not a directory", ENOTDIR},
{"Is a directory", EISDIR},
{"Invalid argument", EINVAL},
{"Too many open files in system", ENFILE},
{"Too many open files", EMFILE},
{"Text file busy", ETXTBSY},
{"File too large", EFBIG},
{"No space left on device", ENOSPC},
{"Illegal seek", ESPIPE},
{"Read-only file system", EROFS},
{"Too many links", EMLINK},
{"Broken pipe", EPIPE},
{"Numerical argument out of domain", EDOM},
{"Numerical result out of range", ERANGE},
{"Resource deadlock avoided", EDEADLK},
{"File name too long", ENAMETOOLONG},
{"No locks available", ENOLCK},
{"Function not implemented", ENOSYS},
{"Directory not empty", ENOTEMPTY},
{"Too many levels of symbolic links", ELOOP},
{"No message of desired type", ENOMSG},
{"Identifier removed", EIDRM},
{"No data available", ENODATA},
{"Machine is not on the network", ENONET},
{"Package not installed", ENOPKG},
{"Object is remote", EREMOTE},
{"Link has been severed", ENOLINK},
{"Communication error on send", ECOMM},
{"Protocol error", EPROTO},
{"Bad message", EBADMSG},
{"File descriptor in bad state", EBADFD},
{"Streams pipe error", ESTRPIPE},
{"Too many users", EUSERS},
{"Socket operation on non-socket", ENOTSOCK},
{"Message too long", EMSGSIZE},
{"Protocol not available", ENOPROTOOPT},
{"Protocol not supported", EPROTONOSUPPORT},
{"Socket type not supported", ESOCKTNOSUPPORT},
{"Operation not supported", EOPNOTSUPP},
{"Protocol family not supported", EPFNOSUPPORT},
{"Network is down", ENETDOWN},
{"Network is unreachable", ENETUNREACH},
{"Network dropped connection on reset", ENETRESET},
{"Software caused connection abort", ECONNABORTED},
{"Connection reset by peer", ECONNRESET},
{"No buffer space available", ENOBUFS},
{"Transport endpoint is already connected", EISCONN},
{"Transport endpoint is not connected", ENOTCONN},
{"Cannot send after transport endpoint shutdown", ESHUTDOWN},
{"Connection timed out", ETIMEDOUT},
{"Connection refused", ECONNREFUSED},
{"Host is down", EHOSTDOWN},
{"No route to host", EHOSTUNREACH},
{"Operation already in progress", EALREADY},
{"Operation now in progress", EINPROGRESS},
{"Is a named type file", EISNAM},
{"Remote I/O error", EREMOTEIO},
{"Disk quota exceeded", EDQUOT},
/* errors from fossil, vacfs, and u9fs */
{"fid unknown or out of range", EBADF},
{"permission denied", EACCES},
{"file does not exist", ENOENT},
{"authentication failed", ECONNREFUSED},
{"bad offset in directory read", ESPIPE},
{"bad use of fid", EBADF},
{"wstat can't convert between files and directories", EPERM},
{"directory is not empty", ENOTEMPTY},
{"file exists", EEXIST},
{"file already exists", EEXIST},
{"file or directory already exists", EEXIST},
{"fid already in use", EBADF},
{"file in use", ETXTBSY},
{"i/o error", EIO},
{"file already open for I/O", ETXTBSY},
{"illegal mode", EINVAL},
{"illegal name", ENAMETOOLONG},
{"not a directory", ENOTDIR},
{"not a member of proposed group", EPERM},
{"not owner", EACCES},
{"only owner can change group in wstat", EACCES},
{"read only file system", EROFS},
{"no access to special file", EPERM},
{"i/o count too large", EIO},
{"unknown group", EINVAL},
{"unknown user", EINVAL},
{"bogus wstat buffer", EPROTO},
{"exclusive use file already open", EAGAIN},
{"corrupted directory entry", EIO},
{"corrupted file entry", EIO},
{"corrupted block label", EIO},
{"corrupted meta data", EIO},
{"illegal offset", EINVAL},
{"illegal path element", ENOENT},
{"root of file system is corrupted", EIO},
{"corrupted super block", EIO},
{"protocol botch", EPROTO},
{"file system is full", ENOSPC},
{"file is in use", EAGAIN},
{"directory entry is not allocated", ENOENT},
{"file is read only", EROFS},
{"file has been removed", EIDRM},
{"only support truncation to zero length", EPERM},
{"cannot remove root", EPERM},
{"file too big", EFBIG},
{"venti i/o error", EIO},
/* these are not errors */
{"u9fs rhostsauth: no authentication required", 0},
{"u9fs authnone: no authentication required", 0},
{NULL, -1}
};
/**
* p9_error_init - preload mappings into hash list
*
*/
int p9_error_init(void)
{
struct errormap *c;
int bucket;
/* initialize hash table */
for (bucket = 0; bucket < ERRHASHSZ; bucket++)
INIT_HLIST_HEAD(&hash_errmap[bucket]);
/* load initial error map into hash table */
for (c = errmap; c->name != NULL; c++) {
c->namelen = strlen(c->name);
bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ;
INIT_HLIST_NODE(&c->list);
hlist_add_head(&c->list, &hash_errmap[bucket]);
}
return 1;
}
EXPORT_SYMBOL(p9_error_init);
/**
* errstr2errno - convert error string to error number
* @errstr: error string
* @len: length of error string
*
*/
int p9_errstr2errno(char *errstr, int len)
{
int errno;
struct errormap *c;
int bucket;
errno = 0;
c = NULL;
bucket = jhash(errstr, len, 0) % ERRHASHSZ;
hlist_for_each_entry(c, &hash_errmap[bucket], list) {
if (c->namelen == len && !memcmp(c->name, errstr, len)) {
errno = c->val;
break;
}
}
if (errno == 0) {
/* TODO: if error isn't found, add it dynamically */
errstr[len] = 0;
pr_err("%s: server reported unknown error %s\n",
__func__, errstr);
errno = ESERVERFAULT;
}
return -errno;
}
EXPORT_SYMBOL(p9_errstr2errno);

View File

@@ -1,306 +0,0 @@
/*
* V9FS FID Management
*
* Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
* Copyright (C) 2005, 2006 by Eric Van Hensbergen <ericvh@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/idr.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
/**
* v9fs_fid_add - add a fid to a dentry
* @dentry: dentry that the fid is being added to
* @fid: fid to add
*
*/
static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
{
hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata);
}
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
{
spin_lock(&dentry->d_lock);
__add_fid(dentry, fid);
spin_unlock(&dentry->d_lock);
}
/**
* v9fs_fid_find - retrieve a fid that belongs to the specified uid
* @dentry: dentry to look for fid in
* @uid: return fid that belongs to the specified user
* @any: if non-zero, return any fid associated with the dentry
*
*/
static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
{
struct p9_fid *fid, *ret;
p9_debug(P9_DEBUG_VFS, " dentry: %s (%p) uid %d any %d\n",
dentry->d_name.name, dentry, from_kuid(&init_user_ns, uid),
any);
ret = NULL;
/* we'll recheck under lock if there's anything to look in */
if (dentry->d_fsdata) {
struct hlist_head *h = (struct hlist_head *)&dentry->d_fsdata;
spin_lock(&dentry->d_lock);
hlist_for_each_entry(fid, h, dlist) {
if (any || uid_eq(fid->uid, uid)) {
ret = fid;
break;
}
}
spin_unlock(&dentry->d_lock);
}
return ret;
}
/*
* We need to hold v9ses->rename_sem as long as we hold references
* to returned path array. Array element contain pointers to
* dentry names.
*/
static int build_path_from_dentry(struct v9fs_session_info *v9ses,
struct dentry *dentry, char ***names)
{
int n = 0, i;
char **wnames;
struct dentry *ds;
for (ds = dentry; !IS_ROOT(ds); ds = ds->d_parent)
n++;
wnames = kmalloc(sizeof(char *) * n, GFP_KERNEL);
if (!wnames)
goto err_out;
for (ds = dentry, i = (n-1); i >= 0; i--, ds = ds->d_parent)
wnames[i] = (char *)ds->d_name.name;
*names = wnames;
return n;
err_out:
return -ENOMEM;
}
static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
kuid_t uid, int any)
{
struct dentry *ds;
char **wnames, *uname;
int i, n, l, clone, access;
struct v9fs_session_info *v9ses;
struct p9_fid *fid, *old_fid = NULL;
v9ses = v9fs_dentry2v9ses(dentry);
access = v9ses->flags & V9FS_ACCESS_MASK;
fid = v9fs_fid_find(dentry, uid, any);
if (fid)
return fid;
/*
* we don't have a matching fid. To do a TWALK we need
* parent fid. We need to prevent rename when we want to
* look at the parent.
*/
down_read(&v9ses->rename_sem);
ds = dentry->d_parent;
fid = v9fs_fid_find(ds, uid, any);
if (fid) {
/* Found the parent fid do a lookup with that */
fid = p9_client_walk(fid, 1, (char **)&dentry->d_name.name, 1);
goto fid_out;
}
up_read(&v9ses->rename_sem);
/* start from the root and try to do a lookup */
fid = v9fs_fid_find(dentry->d_sb->s_root, uid, any);
if (!fid) {
/* the user is not attached to the fs yet */
if (access == V9FS_ACCESS_SINGLE)
return ERR_PTR(-EPERM);
if (v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses))
uname = NULL;
else
uname = v9ses->uname;
fid = p9_client_attach(v9ses->clnt, NULL, uname, uid,
v9ses->aname);
if (IS_ERR(fid))
return fid;
v9fs_fid_add(dentry->d_sb->s_root, fid);
}
/* If we are root ourself just return that */
if (dentry->d_sb->s_root == dentry)
return fid;
/*
* Do a multipath walk with attached root.
* When walking parent we need to make sure we
* don't have a parallel rename happening
*/
down_read(&v9ses->rename_sem);
n = build_path_from_dentry(v9ses, dentry, &wnames);
if (n < 0) {
fid = ERR_PTR(n);
goto err_out;
}
clone = 1;
i = 0;
while (i < n) {
l = min(n - i, P9_MAXWELEM);
/*
* We need to hold rename lock when doing a multipath
* walk to ensure none of the patch component change
*/
fid = p9_client_walk(fid, l, &wnames[i], clone);
if (IS_ERR(fid)) {
if (old_fid) {
/*
* If we fail, clunk fid which are mapping
* to path component and not the last component
* of the path.
*/
p9_client_clunk(old_fid);
}
kfree(wnames);
goto err_out;
}
old_fid = fid;
i += l;
clone = 0;
}
kfree(wnames);
fid_out:
if (!IS_ERR(fid)) {
spin_lock(&dentry->d_lock);
if (d_unhashed(dentry)) {
spin_unlock(&dentry->d_lock);
p9_client_clunk(fid);
fid = ERR_PTR(-ENOENT);
} else {
__add_fid(dentry, fid);
spin_unlock(&dentry->d_lock);
}
}
err_out:
up_read(&v9ses->rename_sem);
return fid;
}
/**
* v9fs_fid_lookup - lookup for a fid, try to walk if not found
* @dentry: dentry to look for fid in
*
* Look for a fid in the specified dentry for the current user.
* If no fid is found, try to create one walking from a fid from the parent
* dentry (if it has one), or the root dentry. If the user haven't accessed
* the fs yet, attach now and walk from the root.
*/
struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
{
kuid_t uid;
int any, access;
struct v9fs_session_info *v9ses;
v9ses = v9fs_dentry2v9ses(dentry);
access = v9ses->flags & V9FS_ACCESS_MASK;
switch (access) {
case V9FS_ACCESS_SINGLE:
case V9FS_ACCESS_USER:
case V9FS_ACCESS_CLIENT:
uid = current_fsuid();
any = 0;
break;
case V9FS_ACCESS_ANY:
uid = v9ses->uid;
any = 1;
break;
default:
uid = INVALID_UID;
any = 0;
break;
}
return v9fs_fid_lookup_with_uid(dentry, uid, any);
}
struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
{
struct p9_fid *fid, *ret;
fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid))
return fid;
ret = p9_client_walk(fid, 0, NULL, 1);
return ret;
}
static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, kuid_t uid)
{
struct p9_fid *fid, *ret;
fid = v9fs_fid_lookup_with_uid(dentry, uid, 0);
if (IS_ERR(fid))
return fid;
ret = p9_client_walk(fid, 0, NULL, 1);
return ret;
}
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
{
int err;
struct p9_fid *fid;
fid = v9fs_fid_clone_with_uid(dentry, GLOBAL_ROOT_UID);
if (IS_ERR(fid))
goto error_out;
/*
* writeback fid will only be used to write back the
* dirty pages. We always request for the open fid in read-write
* mode so that a partial page write which result in page
* read can work.
*/
err = p9_client_open(fid, O_RDWR);
if (err < 0) {
p9_client_clunk(fid);
fid = ERR_PTR(err);
goto error_out;
}
error_out:
return fid;
}

View File

@@ -1,30 +0,0 @@
/*
* V9FS FID Management
*
* Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#ifndef FS_9P_FID_H
#define FS_9P_FID_H
#include <linux/list.h>
struct p9_fid *v9fs_fid_lookup(struct dentry *dentry);
struct p9_fid *v9fs_fid_clone(struct dentry *dentry);
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry);
#endif

View File

@@ -1,201 +0,0 @@
/*
* net/9p/9p.c
*
* 9P entry point
*
* Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/moduleparam.h>
#include <net/9p/9p.h>
#include <linux/fs.h>
#include <linux/parser.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#ifdef CONFIG_NET_9P_DEBUG
unsigned int p9_debug_level = 0; /* feature-rific global debug level */
EXPORT_SYMBOL(p9_debug_level);
module_param_named(debug, p9_debug_level, uint, 0);
MODULE_PARM_DESC(debug, "9P debugging level");
void _p9_debug(enum p9_debug_flags level, const char *func,
const char *fmt, ...)
{
struct va_format vaf;
va_list args;
if ((p9_debug_level & level) != level)
return;
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
if (level == P9_DEBUG_9P)
pr_notice("(%8.8d) %pV", task_pid_nr(current), &vaf);
else
pr_notice("-- %s (%d): %pV", func, task_pid_nr(current), &vaf);
va_end(args);
}
EXPORT_SYMBOL(_p9_debug);
#endif
/*
* Dynamic Transport Registration Routines
*
*/
static DEFINE_SPINLOCK(v9fs_trans_lock);
static LIST_HEAD(v9fs_trans_list);
/**
* v9fs_register_trans - register a new transport with 9p
* @m: structure describing the transport module and entry points
*
*/
void v9fs_register_trans(struct p9_trans_module *m)
{
spin_lock(&v9fs_trans_lock);
list_add_tail(&m->list, &v9fs_trans_list);
spin_unlock(&v9fs_trans_lock);
}
EXPORT_SYMBOL(v9fs_register_trans);
/**
* v9fs_unregister_trans - unregister a 9p transport
* @m: the transport to remove
*
*/
void v9fs_unregister_trans(struct p9_trans_module *m)
{
spin_lock(&v9fs_trans_lock);
list_del_init(&m->list);
spin_unlock(&v9fs_trans_lock);
}
EXPORT_SYMBOL(v9fs_unregister_trans);
/**
* v9fs_get_trans_by_name - get transport with the matching name
* @name: string identifying transport
*
*/
struct p9_trans_module *v9fs_get_trans_by_name(char *s)
{
struct p9_trans_module *t, *found = NULL;
spin_lock(&v9fs_trans_lock);
list_for_each_entry(t, &v9fs_trans_list, list)
if (strcmp(t->name, s) == 0 &&
try_module_get(t->owner)) {
found = t;
break;
}
spin_unlock(&v9fs_trans_lock);
return found;
}
EXPORT_SYMBOL(v9fs_get_trans_by_name);
/**
* v9fs_get_default_trans - get the default transport
*
*/
struct p9_trans_module *v9fs_get_default_trans(void)
{
struct p9_trans_module *t, *found = NULL;
spin_lock(&v9fs_trans_lock);
list_for_each_entry(t, &v9fs_trans_list, list)
if (t->def && try_module_get(t->owner)) {
found = t;
break;
}
if (!found)
list_for_each_entry(t, &v9fs_trans_list, list)
if (try_module_get(t->owner)) {
found = t;
break;
}
spin_unlock(&v9fs_trans_lock);
return found;
}
EXPORT_SYMBOL(v9fs_get_default_trans);
/**
* v9fs_put_trans - put trans
* @m: transport to put
*
*/
void v9fs_put_trans(struct p9_trans_module *m)
{
if (m)
module_put(m->owner);
}
/**
* init_p9 - Initialize module
*
*/
static int __init init_p9(void)
{
int ret = 0;
p9_error_init();
pr_info("Installing 9P2000 support\n");
p9_trans_fd_init();
return ret;
}
/**
* exit_p9 - shutdown module
*
*/
static void __exit exit_p9(void)
{
pr_info("Unloading 9P2000 support\n");
p9_trans_fd_exit();
}
module_init(init_p9)
module_exit(exit_p9)
MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>");
MODULE_LICENSE("GPL");

View File

@@ -1,636 +0,0 @@
/*
* net/9p/protocol.c
*
* 9P Protocol Support Code
*
* Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com>
*
* Base on code from Anthony Liguori <aliguori@us.ibm.com>
* Copyright (C) 2008 by IBM, Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/stddef.h>
#include <linux/types.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "protocol.h"
#include <trace/events/9p.h>
static int
p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
void p9stat_free(struct p9_wstat *stbuf)
{
kfree(stbuf->name);
kfree(stbuf->uid);
kfree(stbuf->gid);
kfree(stbuf->muid);
kfree(stbuf->extension);
}
EXPORT_SYMBOL(p9stat_free);
size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
{
size_t len = min(pdu->size - pdu->offset, size);
memcpy(data, &pdu->sdata[pdu->offset], len);
pdu->offset += len;
return size - len;
}
static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
{
size_t len = min(pdu->capacity - pdu->size, size);
memcpy(&pdu->sdata[pdu->size], data, len);
pdu->size += len;
return size - len;
}
static size_t
pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
{
size_t len = min(pdu->capacity - pdu->size, size);
if (copy_from_user(&pdu->sdata[pdu->size], udata, len))
len = 0;
pdu->size += len;
return size - len;
}
/*
b - int8_t
w - int16_t
d - int32_t
q - int64_t
s - string
u - numeric uid
g - numeric gid
S - stat
Q - qid
D - data blob (int32_t size followed by void *, results are not freed)
T - array of strings (int16_t count, followed by strings)
R - array of qids (int16_t count, followed by qids)
A - stat for 9p2000.L (p9_stat_dotl)
? - if optional = 1, continue parsing
*/
static int
p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
va_list ap)
{
const char *ptr;
int errcode = 0;
for (ptr = fmt; *ptr; ptr++) {
switch (*ptr) {
case 'b':{
int8_t *val = va_arg(ap, int8_t *);
if (pdu_read(pdu, val, sizeof(*val))) {
errcode = -EFAULT;
break;
}
}
break;
case 'w':{
int16_t *val = va_arg(ap, int16_t *);
__le16 le_val;
if (pdu_read(pdu, &le_val, sizeof(le_val))) {
errcode = -EFAULT;
break;
}
*val = le16_to_cpu(le_val);
}
break;
case 'd':{
int32_t *val = va_arg(ap, int32_t *);
__le32 le_val;
if (pdu_read(pdu, &le_val, sizeof(le_val))) {
errcode = -EFAULT;
break;
}
*val = le32_to_cpu(le_val);
}
break;
case 'q':{
int64_t *val = va_arg(ap, int64_t *);
__le64 le_val;
if (pdu_read(pdu, &le_val, sizeof(le_val))) {
errcode = -EFAULT;
break;
}
*val = le64_to_cpu(le_val);
}
break;
case 's':{
char **sptr = va_arg(ap, char **);
uint16_t len;
errcode = p9pdu_readf(pdu, proto_version,
"w", &len);
if (errcode)
break;
*sptr = kmalloc(len + 1, GFP_NOFS);
if (*sptr == NULL) {
errcode = -EFAULT;
break;
}
if (pdu_read(pdu, *sptr, len)) {
errcode = -EFAULT;
kfree(*sptr);
*sptr = NULL;
} else
(*sptr)[len] = 0;
}
break;
case 'u': {
kuid_t *uid = va_arg(ap, kuid_t *);
__le32 le_val;
if (pdu_read(pdu, &le_val, sizeof(le_val))) {
errcode = -EFAULT;
break;
}
*uid = make_kuid(&init_user_ns,
le32_to_cpu(le_val));
} break;
case 'g': {
kgid_t *gid = va_arg(ap, kgid_t *);
__le32 le_val;
if (pdu_read(pdu, &le_val, sizeof(le_val))) {
errcode = -EFAULT;
break;
}
*gid = make_kgid(&init_user_ns,
le32_to_cpu(le_val));
} break;
case 'Q':{
struct p9_qid *qid =
va_arg(ap, struct p9_qid *);
errcode = p9pdu_readf(pdu, proto_version, "bdq",
&qid->type, &qid->version,
&qid->path);
}
break;
case 'S':{
struct p9_wstat *stbuf =
va_arg(ap, struct p9_wstat *);
memset(stbuf, 0, sizeof(struct p9_wstat));
stbuf->n_uid = stbuf->n_muid = INVALID_UID;
stbuf->n_gid = INVALID_GID;
errcode =
p9pdu_readf(pdu, proto_version,
"wwdQdddqssss?sugu",
&stbuf->size, &stbuf->type,
&stbuf->dev, &stbuf->qid,
&stbuf->mode, &stbuf->atime,
&stbuf->mtime, &stbuf->length,
&stbuf->name, &stbuf->uid,
&stbuf->gid, &stbuf->muid,
&stbuf->extension,
&stbuf->n_uid, &stbuf->n_gid,
&stbuf->n_muid);
if (errcode)
p9stat_free(stbuf);
}
break;
case 'D':{
uint32_t *count = va_arg(ap, uint32_t *);
void **data = va_arg(ap, void **);
errcode =
p9pdu_readf(pdu, proto_version, "d", count);
if (!errcode) {
*count =
min_t(uint32_t, *count,
pdu->size - pdu->offset);
*data = &pdu->sdata[pdu->offset];
}
}
break;
case 'T':{
uint16_t *nwname = va_arg(ap, uint16_t *);
char ***wnames = va_arg(ap, char ***);
errcode = p9pdu_readf(pdu, proto_version,
"w", nwname);
if (!errcode) {
*wnames =
kmalloc(sizeof(char *) * *nwname,
GFP_NOFS);
if (!*wnames)
errcode = -ENOMEM;
}
if (!errcode) {
int i;
for (i = 0; i < *nwname; i++) {
errcode =
p9pdu_readf(pdu,
proto_version,
"s",
&(*wnames)[i]);
if (errcode)
break;
}
}
if (errcode) {
if (*wnames) {
int i;
for (i = 0; i < *nwname; i++)
kfree((*wnames)[i]);
}
kfree(*wnames);
*wnames = NULL;
}
}
break;
case 'R':{
int16_t *nwqid = va_arg(ap, int16_t *);
struct p9_qid **wqids =
va_arg(ap, struct p9_qid **);
*wqids = NULL;
errcode =
p9pdu_readf(pdu, proto_version, "w", nwqid);
if (!errcode) {
*wqids =
kmalloc(*nwqid *
sizeof(struct p9_qid),
GFP_NOFS);
if (*wqids == NULL)
errcode = -ENOMEM;
}
if (!errcode) {
int i;
for (i = 0; i < *nwqid; i++) {
errcode =
p9pdu_readf(pdu,
proto_version,
"Q",
&(*wqids)[i]);
if (errcode)
break;
}
}
if (errcode) {
kfree(*wqids);
*wqids = NULL;
}
}
break;
case 'A': {
struct p9_stat_dotl *stbuf =
va_arg(ap, struct p9_stat_dotl *);
memset(stbuf, 0, sizeof(struct p9_stat_dotl));
errcode =
p9pdu_readf(pdu, proto_version,
"qQdugqqqqqqqqqqqqqqq",
&stbuf->st_result_mask,
&stbuf->qid,
&stbuf->st_mode,
&stbuf->st_uid, &stbuf->st_gid,
&stbuf->st_nlink,
&stbuf->st_rdev, &stbuf->st_size,
&stbuf->st_blksize, &stbuf->st_blocks,
&stbuf->st_atime_sec,
&stbuf->st_atime_nsec,
&stbuf->st_mtime_sec,
&stbuf->st_mtime_nsec,
&stbuf->st_ctime_sec,
&stbuf->st_ctime_nsec,
&stbuf->st_btime_sec,
&stbuf->st_btime_nsec,
&stbuf->st_gen,
&stbuf->st_data_version);
}
break;
case '?':
if ((proto_version != p9_proto_2000u) &&
(proto_version != p9_proto_2000L))
return 0;
break;
default:
BUG();
break;
}
if (errcode)
break;
}
return errcode;
}
int
p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
va_list ap)
{
const char *ptr;
int errcode = 0;
for (ptr = fmt; *ptr; ptr++) {
switch (*ptr) {
case 'b':{
int8_t val = va_arg(ap, int);
if (pdu_write(pdu, &val, sizeof(val)))
errcode = -EFAULT;
}
break;
case 'w':{
__le16 val = cpu_to_le16(va_arg(ap, int));
if (pdu_write(pdu, &val, sizeof(val)))
errcode = -EFAULT;
}
break;
case 'd':{
__le32 val = cpu_to_le32(va_arg(ap, int32_t));
if (pdu_write(pdu, &val, sizeof(val)))
errcode = -EFAULT;
}
break;
case 'q':{
__le64 val = cpu_to_le64(va_arg(ap, int64_t));
if (pdu_write(pdu, &val, sizeof(val)))
errcode = -EFAULT;
}
break;
case 's':{
const char *sptr = va_arg(ap, const char *);
uint16_t len = 0;
if (sptr)
len = min_t(size_t, strlen(sptr),
USHRT_MAX);
errcode = p9pdu_writef(pdu, proto_version,
"w", len);
if (!errcode && pdu_write(pdu, sptr, len))
errcode = -EFAULT;
}
break;
case 'u': {
kuid_t uid = va_arg(ap, kuid_t);
__le32 val = cpu_to_le32(
from_kuid(&init_user_ns, uid));
if (pdu_write(pdu, &val, sizeof(val)))
errcode = -EFAULT;
} break;
case 'g': {
kgid_t gid = va_arg(ap, kgid_t);
__le32 val = cpu_to_le32(
from_kgid(&init_user_ns, gid));
if (pdu_write(pdu, &val, sizeof(val)))
errcode = -EFAULT;
} break;
case 'Q':{
const struct p9_qid *qid =
va_arg(ap, const struct p9_qid *);
errcode =
p9pdu_writef(pdu, proto_version, "bdq",
qid->type, qid->version,
qid->path);
} break;
case 'S':{
const struct p9_wstat *stbuf =
va_arg(ap, const struct p9_wstat *);
errcode =
p9pdu_writef(pdu, proto_version,
"wwdQdddqssss?sugu",
stbuf->size, stbuf->type,
stbuf->dev, &stbuf->qid,
stbuf->mode, stbuf->atime,
stbuf->mtime, stbuf->length,
stbuf->name, stbuf->uid,
stbuf->gid, stbuf->muid,
stbuf->extension, stbuf->n_uid,
stbuf->n_gid, stbuf->n_muid);
} break;
case 'D':{
uint32_t count = va_arg(ap, uint32_t);
const void *data = va_arg(ap, const void *);
errcode = p9pdu_writef(pdu, proto_version, "d",
count);
if (!errcode && pdu_write(pdu, data, count))
errcode = -EFAULT;
}
break;
case 'U':{
int32_t count = va_arg(ap, int32_t);
const char __user *udata =
va_arg(ap, const void __user *);
errcode = p9pdu_writef(pdu, proto_version, "d",
count);
if (!errcode && pdu_write_u(pdu, udata, count))
errcode = -EFAULT;
}
break;
case 'T':{
uint16_t nwname = va_arg(ap, int);
const char **wnames = va_arg(ap, const char **);
errcode = p9pdu_writef(pdu, proto_version, "w",
nwname);
if (!errcode) {
int i;
for (i = 0; i < nwname; i++) {
errcode =
p9pdu_writef(pdu,
proto_version,
"s",
wnames[i]);
if (errcode)
break;
}
}
}
break;
case 'R':{
int16_t nwqid = va_arg(ap, int);
struct p9_qid *wqids =
va_arg(ap, struct p9_qid *);
errcode = p9pdu_writef(pdu, proto_version, "w",
nwqid);
if (!errcode) {
int i;
for (i = 0; i < nwqid; i++) {
errcode =
p9pdu_writef(pdu,
proto_version,
"Q",
&wqids[i]);
if (errcode)
break;
}
}
}
break;
case 'I':{
struct p9_iattr_dotl *p9attr = va_arg(ap,
struct p9_iattr_dotl *);
errcode = p9pdu_writef(pdu, proto_version,
"ddugqqqqq",
p9attr->valid,
p9attr->mode,
p9attr->uid,
p9attr->gid,
p9attr->size,
p9attr->atime_sec,
p9attr->atime_nsec,
p9attr->mtime_sec,
p9attr->mtime_nsec);
}
break;
case '?':
if ((proto_version != p9_proto_2000u) &&
(proto_version != p9_proto_2000L))
return 0;
break;
default:
BUG();
break;
}
if (errcode)
break;
}
return errcode;
}
int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = p9pdu_vreadf(pdu, proto_version, fmt, ap);
va_end(ap);
return ret;
}
static int
p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = p9pdu_vwritef(pdu, proto_version, fmt, ap);
va_end(ap);
return ret;
}
int p9stat_read(struct p9_client *clnt, char *buf, int len, struct p9_wstat *st)
{
struct p9_fcall fake_pdu;
int ret;
fake_pdu.size = len;
fake_pdu.capacity = len;
fake_pdu.sdata = buf;
fake_pdu.offset = 0;
ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "S", st);
if (ret) {
p9_debug(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
trace_9p_protocol_dump(clnt, &fake_pdu);
}
return ret;
}
EXPORT_SYMBOL(p9stat_read);
int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type)
{
pdu->id = type;
return p9pdu_writef(pdu, 0, "dbw", 0, type, tag);
}
int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu)
{
int size = pdu->size;
int err;
pdu->size = 0;
err = p9pdu_writef(pdu, 0, "d", size);
pdu->size = size;
trace_9p_protocol_dump(clnt, pdu);
p9_debug(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n",
pdu->size, pdu->id, pdu->tag);
return err;
}
void p9pdu_reset(struct p9_fcall *pdu)
{
pdu->offset = 0;
pdu->size = 0;
}
int p9dirent_read(struct p9_client *clnt, char *buf, int len,
struct p9_dirent *dirent)
{
struct p9_fcall fake_pdu;
int ret;
char *nameptr;
fake_pdu.size = len;
fake_pdu.capacity = len;
fake_pdu.sdata = buf;
fake_pdu.offset = 0;
ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "Qqbs", &dirent->qid,
&dirent->d_off, &dirent->d_type, &nameptr);
if (ret) {
p9_debug(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
trace_9p_protocol_dump(clnt, &fake_pdu);
goto out;
}
strcpy(dirent->d_name, nameptr);
kfree(nameptr);
out:
return fake_pdu.offset;
}
EXPORT_SYMBOL(p9dirent_read);

View File

@@ -1,34 +0,0 @@
/*
* net/9p/protocol.h
*
* 9P Protocol Support Code
*
* Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com>
*
* Base on code from Anthony Liguori <aliguori@us.ibm.com>
* Copyright (C) 2008 by IBM, Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
int p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
va_list ap);
int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type);
int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu);
void p9pdu_reset(struct p9_fcall *pdu);
size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size);

View File

@@ -1,69 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <linux/slab.h>
#include <linux/module.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <linux/scatterlist.h>
#include "trans_common.h"
/**
* p9_release_req_pages - Release pages after the transaction.
*/
void p9_release_pages(struct page **pages, int nr_pages)
{
int i;
for (i = 0; i < nr_pages; i++)
if (pages[i])
put_page(pages[i]);
}
EXPORT_SYMBOL(p9_release_pages);
/**
* p9_nr_pages - Return number of pages needed to accommodate the payload.
*/
int p9_nr_pages(char *data, int len)
{
unsigned long start_page, end_page;
start_page = (unsigned long)data >> PAGE_SHIFT;
end_page = ((unsigned long)data + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
return end_page - start_page;
}
EXPORT_SYMBOL(p9_nr_pages);
/**
* payload_gup - Translates user buffer into kernel pages and
* pins them either for read/write through get_user_pages_fast().
* @req: Request to be sent to server.
* @pdata_off: data offset into the first page after translation (gup).
* @pdata_len: Total length of the IO. gup may not return requested # of pages.
* @nr_pages: number of pages to accommodate the payload
* @rw: Indicates if the pages are for read or write.
*/
int p9_payload_gup(char *data, int *nr_pages, struct page **pages, int write)
{
int nr_mapped_pages;
nr_mapped_pages = get_user_pages_fast((unsigned long)data,
*nr_pages, write, pages);
if (nr_mapped_pages <= 0)
return nr_mapped_pages;
*nr_pages = nr_mapped_pages;
return 0;
}
EXPORT_SYMBOL(p9_payload_gup);

View File

@@ -1,17 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
void p9_release_pages(struct page **, int);
int p9_payload_gup(char *, int *, struct page **, int);
int p9_nr_pages(char *, int);

File diff suppressed because it is too large Load Diff

View File

@@ -1,719 +0,0 @@
/*
* linux/fs/9p/trans_rdma.c
*
* RDMA transport layer based on the trans_fd.c implementation.
*
* Copyright (C) 2008 by Tom Tucker <tom@opengridcomputing.com>
* Copyright (C) 2006 by Russ Cox <rsc@swtch.com>
* Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
* Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/in.h>
#include <linux/module.h>
#include <linux/net.h>
#include <linux/ipv6.h>
#include <linux/kthread.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/un.h>
#include <linux/uaccess.h>
#include <linux/inet.h>
#include <linux/idr.h>
#include <linux/file.h>
#include <linux/parser.h>
#include <linux/semaphore.h>
#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
#include <rdma/ib_verbs.h>
#include <rdma/rdma_cm.h>
#define P9_PORT 5640
#define P9_RDMA_SQ_DEPTH 32
#define P9_RDMA_RQ_DEPTH 32
#define P9_RDMA_SEND_SGE 4
#define P9_RDMA_RECV_SGE 4
#define P9_RDMA_IRD 0
#define P9_RDMA_ORD 0
#define P9_RDMA_TIMEOUT 30000 /* 30 seconds */
#define P9_RDMA_MAXSIZE (4*4096) /* Min SGE is 4, so we can
* safely advertise a maxsize
* of 64k */
/**
* struct p9_trans_rdma - RDMA transport instance
*
* @state: tracks the transport state machine for connection setup and tear down
* @cm_id: The RDMA CM ID
* @pd: Protection Domain pointer
* @qp: Queue Pair pointer
* @cq: Completion Queue pointer
* @dm_mr: DMA Memory Region pointer
* @lkey: The local access only memory region key
* @timeout: Number of uSecs to wait for connection management events
* @sq_depth: The depth of the Send Queue
* @sq_sem: Semaphore for the SQ
* @rq_depth: The depth of the Receive Queue.
* @rq_count: Count of requests in the Receive Queue.
* @addr: The remote peer's address
* @req_lock: Protects the active request list
* @cm_done: Completion event for connection management tracking
*/
struct p9_trans_rdma {
enum {
P9_RDMA_INIT,
P9_RDMA_ADDR_RESOLVED,
P9_RDMA_ROUTE_RESOLVED,
P9_RDMA_CONNECTED,
P9_RDMA_FLUSHING,
P9_RDMA_CLOSING,
P9_RDMA_CLOSED,
} state;
struct rdma_cm_id *cm_id;
struct ib_pd *pd;
struct ib_qp *qp;
struct ib_cq *cq;
struct ib_mr *dma_mr;
u32 lkey;
long timeout;
int sq_depth;
struct semaphore sq_sem;
int rq_depth;
atomic_t rq_count;
struct sockaddr_in addr;
spinlock_t req_lock;
struct completion cm_done;
};
/**
* p9_rdma_context - Keeps track of in-process WR
*
* @wc_op: The original WR op for when the CQE completes in error.
* @busa: Bus address to unmap when the WR completes
* @req: Keeps track of requests (send)
* @rc: Keepts track of replies (receive)
*/
struct p9_rdma_req;
struct p9_rdma_context {
enum ib_wc_opcode wc_op;
dma_addr_t busa;
union {
struct p9_req_t *req;
struct p9_fcall *rc;
};
};
/**
* p9_rdma_opts - Collection of mount options
* @port: port of connection
* @sq_depth: The requested depth of the SQ. This really doesn't need
* to be any deeper than the number of threads used in the client
* @rq_depth: The depth of the RQ. Should be greater than or equal to SQ depth
* @timeout: Time to wait in msecs for CM events
*/
struct p9_rdma_opts {
short port;
int sq_depth;
int rq_depth;
long timeout;
};
/*
* Option Parsing (code inspired by NFS code)
*/
enum {
/* Options that take integer arguments */
Opt_port, Opt_rq_depth, Opt_sq_depth, Opt_timeout, Opt_err,
};
static match_table_t tokens = {
{Opt_port, "port=%u"},
{Opt_sq_depth, "sq=%u"},
{Opt_rq_depth, "rq=%u"},
{Opt_timeout, "timeout=%u"},
{Opt_err, NULL},
};
/**
* parse_opts - parse mount options into rdma options structure
* @params: options string passed from mount
* @opts: rdma transport-specific structure to parse options into
*
* Returns 0 upon success, -ERRNO upon failure
*/
static int parse_opts(char *params, struct p9_rdma_opts *opts)
{
char *p;
substring_t args[MAX_OPT_ARGS];
int option;
char *options, *tmp_options;
opts->port = P9_PORT;
opts->sq_depth = P9_RDMA_SQ_DEPTH;
opts->rq_depth = P9_RDMA_RQ_DEPTH;
opts->timeout = P9_RDMA_TIMEOUT;
if (!params)
return 0;
tmp_options = kstrdup(params, GFP_KERNEL);
if (!tmp_options) {
p9_debug(P9_DEBUG_ERROR,
"failed to allocate copy of option string\n");
return -ENOMEM;
}
options = tmp_options;
while ((p = strsep(&options, ",")) != NULL) {
int token;
int r;
if (!*p)
continue;
token = match_token(p, tokens, args);
r = match_int(&args[0], &option);
if (r < 0) {
p9_debug(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
continue;
}
switch (token) {
case Opt_port:
opts->port = option;
break;
case Opt_sq_depth:
opts->sq_depth = option;
break;
case Opt_rq_depth:
opts->rq_depth = option;
break;
case Opt_timeout:
opts->timeout = option;
break;
default:
continue;
}
}
/* RQ must be at least as large as the SQ */
opts->rq_depth = max(opts->rq_depth, opts->sq_depth);
kfree(tmp_options);
return 0;
}
static int
p9_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
{
struct p9_client *c = id->context;
struct p9_trans_rdma *rdma = c->trans;
switch (event->event) {
case RDMA_CM_EVENT_ADDR_RESOLVED:
BUG_ON(rdma->state != P9_RDMA_INIT);
rdma->state = P9_RDMA_ADDR_RESOLVED;
break;
case RDMA_CM_EVENT_ROUTE_RESOLVED:
BUG_ON(rdma->state != P9_RDMA_ADDR_RESOLVED);
rdma->state = P9_RDMA_ROUTE_RESOLVED;
break;
case RDMA_CM_EVENT_ESTABLISHED:
BUG_ON(rdma->state != P9_RDMA_ROUTE_RESOLVED);
rdma->state = P9_RDMA_CONNECTED;
break;
case RDMA_CM_EVENT_DISCONNECTED:
if (rdma)
rdma->state = P9_RDMA_CLOSED;
if (c)
c->status = Disconnected;
break;
case RDMA_CM_EVENT_TIMEWAIT_EXIT:
break;
case RDMA_CM_EVENT_ADDR_CHANGE:
case RDMA_CM_EVENT_ROUTE_ERROR:
case RDMA_CM_EVENT_DEVICE_REMOVAL:
case RDMA_CM_EVENT_MULTICAST_JOIN:
case RDMA_CM_EVENT_MULTICAST_ERROR:
case RDMA_CM_EVENT_REJECTED:
case RDMA_CM_EVENT_CONNECT_REQUEST:
case RDMA_CM_EVENT_CONNECT_RESPONSE:
case RDMA_CM_EVENT_CONNECT_ERROR:
case RDMA_CM_EVENT_ADDR_ERROR:
case RDMA_CM_EVENT_UNREACHABLE:
c->status = Disconnected;
rdma_disconnect(rdma->cm_id);
break;
default:
BUG();
}
complete(&rdma->cm_done);
return 0;
}
static void
handle_recv(struct p9_client *client, struct p9_trans_rdma *rdma,
struct p9_rdma_context *c, enum ib_wc_status status, u32 byte_len)
{
struct p9_req_t *req;
int err = 0;
int16_t tag;
req = NULL;
ib_dma_unmap_single(rdma->cm_id->device, c->busa, client->msize,
DMA_FROM_DEVICE);
if (status != IB_WC_SUCCESS)
goto err_out;
err = p9_parse_header(c->rc, NULL, NULL, &tag, 1);
if (err)
goto err_out;
req = p9_tag_lookup(client, tag);
if (!req)
goto err_out;
req->rc = c->rc;
req->status = REQ_STATUS_RCVD;
p9_client_cb(client, req);
return;
err_out:
p9_debug(P9_DEBUG_ERROR, "req %p err %d status %d\n", req, err, status);
rdma->state = P9_RDMA_FLUSHING;
client->status = Disconnected;
}
static void
handle_send(struct p9_client *client, struct p9_trans_rdma *rdma,
struct p9_rdma_context *c, enum ib_wc_status status, u32 byte_len)
{
ib_dma_unmap_single(rdma->cm_id->device,
c->busa, c->req->tc->size,
DMA_TO_DEVICE);
}
static void qp_event_handler(struct ib_event *event, void *context)
{
p9_debug(P9_DEBUG_ERROR, "QP event %d context %p\n",
event->event, context);
}
static void cq_comp_handler(struct ib_cq *cq, void *cq_context)
{
struct p9_client *client = cq_context;
struct p9_trans_rdma *rdma = client->trans;
int ret;
struct ib_wc wc;
ib_req_notify_cq(rdma->cq, IB_CQ_NEXT_COMP);
while ((ret = ib_poll_cq(cq, 1, &wc)) > 0) {
struct p9_rdma_context *c = (void *) (unsigned long) wc.wr_id;
switch (c->wc_op) {
case IB_WC_RECV:
atomic_dec(&rdma->rq_count);
handle_recv(client, rdma, c, wc.status, wc.byte_len);
break;
case IB_WC_SEND:
handle_send(client, rdma, c, wc.status, wc.byte_len);
up(&rdma->sq_sem);
break;
default:
pr_err("unexpected completion type, c->wc_op=%d, wc.opcode=%d, status=%d\n",
c->wc_op, wc.opcode, wc.status);
break;
}
kfree(c);
}
}
static void cq_event_handler(struct ib_event *e, void *v)
{
p9_debug(P9_DEBUG_ERROR, "CQ event %d context %p\n", e->event, v);
}
static void rdma_destroy_trans(struct p9_trans_rdma *rdma)
{
if (!rdma)
return;
if (rdma->dma_mr && !IS_ERR(rdma->dma_mr))
ib_dereg_mr(rdma->dma_mr);
if (rdma->qp && !IS_ERR(rdma->qp))
ib_destroy_qp(rdma->qp);
if (rdma->pd && !IS_ERR(rdma->pd))
ib_dealloc_pd(rdma->pd);
if (rdma->cq && !IS_ERR(rdma->cq))
ib_destroy_cq(rdma->cq);
if (rdma->cm_id && !IS_ERR(rdma->cm_id))
rdma_destroy_id(rdma->cm_id);
kfree(rdma);
}
static int
post_recv(struct p9_client *client, struct p9_rdma_context *c)
{
struct p9_trans_rdma *rdma = client->trans;
struct ib_recv_wr wr, *bad_wr;
struct ib_sge sge;
c->busa = ib_dma_map_single(rdma->cm_id->device,
c->rc->sdata, client->msize,
DMA_FROM_DEVICE);
if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
goto error;
sge.addr = c->busa;
sge.length = client->msize;
sge.lkey = rdma->lkey;
wr.next = NULL;
c->wc_op = IB_WC_RECV;
wr.wr_id = (unsigned long) c;
wr.sg_list = &sge;
wr.num_sge = 1;
return ib_post_recv(rdma->qp, &wr, &bad_wr);
error:
p9_debug(P9_DEBUG_ERROR, "EIO\n");
return -EIO;
}
static int rdma_request(struct p9_client *client, struct p9_req_t *req)
{
struct p9_trans_rdma *rdma = client->trans;
struct ib_send_wr wr, *bad_wr;
struct ib_sge sge;
int err = 0;
unsigned long flags;
struct p9_rdma_context *c = NULL;
struct p9_rdma_context *rpl_context = NULL;
/* Allocate an fcall for the reply */
rpl_context = kmalloc(sizeof *rpl_context, GFP_NOFS);
if (!rpl_context) {
err = -ENOMEM;
goto err_close;
}
/*
* If the request has a buffer, steal it, otherwise
* allocate a new one. Typically, requests should already
* have receive buffers allocated and just swap them around
*/
if (!req->rc) {
req->rc = kmalloc(sizeof(struct p9_fcall)+client->msize,
GFP_NOFS);
if (req->rc) {
req->rc->sdata = (char *) req->rc +
sizeof(struct p9_fcall);
req->rc->capacity = client->msize;
}
}
rpl_context->rc = req->rc;
if (!rpl_context->rc) {
err = -ENOMEM;
goto err_free2;
}
/*
* Post a receive buffer for this request. We need to ensure
* there is a reply buffer available for every outstanding
* request. A flushed request can result in no reply for an
* outstanding request, so we must keep a count to avoid
* overflowing the RQ.
*/
if (atomic_inc_return(&rdma->rq_count) <= rdma->rq_depth) {
err = post_recv(client, rpl_context);
if (err)
goto err_free1;
} else
atomic_dec(&rdma->rq_count);
/* remove posted receive buffer from request structure */
req->rc = NULL;
/* Post the request */
c = kmalloc(sizeof *c, GFP_NOFS);
if (!c) {
err = -ENOMEM;
goto err_free1;
}
c->req = req;
c->busa = ib_dma_map_single(rdma->cm_id->device,
c->req->tc->sdata, c->req->tc->size,
DMA_TO_DEVICE);
if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
goto error;
sge.addr = c->busa;
sge.length = c->req->tc->size;
sge.lkey = rdma->lkey;
wr.next = NULL;
c->wc_op = IB_WC_SEND;
wr.wr_id = (unsigned long) c;
wr.opcode = IB_WR_SEND;
wr.send_flags = IB_SEND_SIGNALED;
wr.sg_list = &sge;
wr.num_sge = 1;
if (down_interruptible(&rdma->sq_sem))
goto error;
return ib_post_send(rdma->qp, &wr, &bad_wr);
error:
kfree(c);
kfree(rpl_context->rc);
kfree(rpl_context);
p9_debug(P9_DEBUG_ERROR, "EIO\n");
return -EIO;
err_free1:
kfree(rpl_context->rc);
err_free2:
kfree(rpl_context);
err_close:
spin_lock_irqsave(&rdma->req_lock, flags);
if (rdma->state < P9_RDMA_CLOSING) {
rdma->state = P9_RDMA_CLOSING;
spin_unlock_irqrestore(&rdma->req_lock, flags);
rdma_disconnect(rdma->cm_id);
} else
spin_unlock_irqrestore(&rdma->req_lock, flags);
return err;
}
static void rdma_close(struct p9_client *client)
{
struct p9_trans_rdma *rdma;
if (!client)
return;
rdma = client->trans;
if (!rdma)
return;
client->status = Disconnected;
rdma_disconnect(rdma->cm_id);
rdma_destroy_trans(rdma);
}
/**
* alloc_rdma - Allocate and initialize the rdma transport structure
* @opts: Mount options structure
*/
static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts)
{
struct p9_trans_rdma *rdma;
rdma = kzalloc(sizeof(struct p9_trans_rdma), GFP_KERNEL);
if (!rdma)
return NULL;
rdma->sq_depth = opts->sq_depth;
rdma->rq_depth = opts->rq_depth;
rdma->timeout = opts->timeout;
spin_lock_init(&rdma->req_lock);
init_completion(&rdma->cm_done);
sema_init(&rdma->sq_sem, rdma->sq_depth);
atomic_set(&rdma->rq_count, 0);
return rdma;
}
/* its not clear to me we can do anything after send has been posted */
static int rdma_cancel(struct p9_client *client, struct p9_req_t *req)
{
return 1;
}
/**
* trans_create_rdma - Transport method for creating atransport instance
* @client: client instance
* @addr: IP address string
* @args: Mount options string
*/
static int
rdma_create_trans(struct p9_client *client, const char *addr, char *args)
{
int err;
struct p9_rdma_opts opts;
struct p9_trans_rdma *rdma;
struct rdma_conn_param conn_param;
struct ib_qp_init_attr qp_attr;
struct ib_device_attr devattr;
/* Parse the transport specific mount options */
err = parse_opts(args, &opts);
if (err < 0)
return err;
/* Create and initialize the RDMA transport structure */
rdma = alloc_rdma(&opts);
if (!rdma)
return -ENOMEM;
/* Create the RDMA CM ID */
rdma->cm_id = rdma_create_id(p9_cm_event_handler, client, RDMA_PS_TCP,
IB_QPT_RC);
if (IS_ERR(rdma->cm_id))
goto error;
/* Associate the client with the transport */
client->trans = rdma;
/* Resolve the server's address */
rdma->addr.sin_family = AF_INET;
rdma->addr.sin_addr.s_addr = in_aton(addr);
rdma->addr.sin_port = htons(opts.port);
err = rdma_resolve_addr(rdma->cm_id, NULL,
(struct sockaddr *)&rdma->addr,
rdma->timeout);
if (err)
goto error;
err = wait_for_completion_interruptible(&rdma->cm_done);
if (err || (rdma->state != P9_RDMA_ADDR_RESOLVED))
goto error;
/* Resolve the route to the server */
err = rdma_resolve_route(rdma->cm_id, rdma->timeout);
if (err)
goto error;
err = wait_for_completion_interruptible(&rdma->cm_done);
if (err || (rdma->state != P9_RDMA_ROUTE_RESOLVED))
goto error;
/* Query the device attributes */
err = ib_query_device(rdma->cm_id->device, &devattr);
if (err)
goto error;
/* Create the Completion Queue */
rdma->cq = ib_create_cq(rdma->cm_id->device, cq_comp_handler,
cq_event_handler, client,
opts.sq_depth + opts.rq_depth + 1, 0);
if (IS_ERR(rdma->cq))
goto error;
ib_req_notify_cq(rdma->cq, IB_CQ_NEXT_COMP);
/* Create the Protection Domain */
rdma->pd = ib_alloc_pd(rdma->cm_id->device);
if (IS_ERR(rdma->pd))
goto error;
/* Cache the DMA lkey in the transport */
rdma->dma_mr = NULL;
if (devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)
rdma->lkey = rdma->cm_id->device->local_dma_lkey;
else {
rdma->dma_mr = ib_get_dma_mr(rdma->pd, IB_ACCESS_LOCAL_WRITE);
if (IS_ERR(rdma->dma_mr))
goto error;
rdma->lkey = rdma->dma_mr->lkey;
}
/* Create the Queue Pair */
memset(&qp_attr, 0, sizeof qp_attr);
qp_attr.event_handler = qp_event_handler;
qp_attr.qp_context = client;
qp_attr.cap.max_send_wr = opts.sq_depth;
qp_attr.cap.max_recv_wr = opts.rq_depth;
qp_attr.cap.max_send_sge = P9_RDMA_SEND_SGE;
qp_attr.cap.max_recv_sge = P9_RDMA_RECV_SGE;
qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
qp_attr.qp_type = IB_QPT_RC;
qp_attr.send_cq = rdma->cq;
qp_attr.recv_cq = rdma->cq;
err = rdma_create_qp(rdma->cm_id, rdma->pd, &qp_attr);
if (err)
goto error;
rdma->qp = rdma->cm_id->qp;
/* Request a connection */
memset(&conn_param, 0, sizeof(conn_param));
conn_param.private_data = NULL;
conn_param.private_data_len = 0;
conn_param.responder_resources = P9_RDMA_IRD;
conn_param.initiator_depth = P9_RDMA_ORD;
err = rdma_connect(rdma->cm_id, &conn_param);
if (err)
goto error;
err = wait_for_completion_interruptible(&rdma->cm_done);
if (err || (rdma->state != P9_RDMA_CONNECTED))
goto error;
client->status = Connected;
return 0;
error:
rdma_destroy_trans(rdma);
return -ENOTCONN;
}
static struct p9_trans_module p9_rdma_trans = {
.name = "rdma",
.maxsize = P9_RDMA_MAXSIZE,
.def = 0,
.owner = THIS_MODULE,
.create = rdma_create_trans,
.close = rdma_close,
.request = rdma_request,
.cancel = rdma_cancel,
};
/**
* p9_trans_rdma_init - Register the 9P RDMA transport driver
*/
static int __init p9_trans_rdma_init(void)
{
v9fs_register_trans(&p9_rdma_trans);
return 0;
}
static void __exit p9_trans_rdma_exit(void)
{
v9fs_unregister_trans(&p9_rdma_trans);
}
module_init(p9_trans_rdma_init);
module_exit(p9_trans_rdma_exit);
MODULE_AUTHOR("Tom Tucker <tom@opengridcomputing.com>");
MODULE_DESCRIPTION("RDMA Transport for 9P");
MODULE_LICENSE("Dual BSD/GPL");

View File

@@ -1,730 +0,0 @@
/*
* The Virtio 9p transport driver
*
* This is a block based transport driver based on the lguest block driver
* code.
*
* Copyright (C) 2007, 2008 Eric Van Hensbergen, IBM Corporation
*
* Based on virtio console driver
* Copyright (C) 2006, 2007 Rusty Russell, IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/in.h>
#include <linux/module.h>
#include <linux/net.h>
#include <linux/ipv6.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/un.h>
#include <linux/uaccess.h>
#include <linux/inet.h>
#include <linux/idr.h>
#include <linux/file.h>
#include <linux/highmem.h>
#include <linux/slab.h>
#include <net/9p/9p.h>
#include <linux/parser.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
#include <linux/scatterlist.h>
#include <linux/swap.h>
#include <linux/virtio.h>
#include <linux/virtio_9p.h>
#include "trans_common.h"
#define VIRTQUEUE_NUM 128
/* a single mutex to manage channel initialization and attachment */
static DEFINE_MUTEX(virtio_9p_lock);
static DECLARE_WAIT_QUEUE_HEAD(vp_wq);
static atomic_t vp_pinned = ATOMIC_INIT(0);
/**
* struct virtio_chan - per-instance transport information
* @initialized: whether the channel is initialized
* @inuse: whether the channel is in use
* @lock: protects multiple elements within this structure
* @client: client instance
* @vdev: virtio dev associated with this channel
* @vq: virtio queue associated with this channel
* @sg: scatter gather list which is used to pack a request (protected?)
*
* We keep all per-channel information in a structure.
* This structure is allocated within the devices dev->mem space.
* A pointer to the structure will get put in the transport private.
*
*/
struct virtio_chan {
bool inuse;
spinlock_t lock;
struct p9_client *client;
struct virtio_device *vdev;
struct virtqueue *vq;
int ring_bufs_avail;
wait_queue_head_t *vc_wq;
/* This is global limit. Since we don't have a global structure,
* will be placing it in each channel.
*/
unsigned long p9_max_pages;
/* Scatterlist: can be too big for stack. */
struct scatterlist sg[VIRTQUEUE_NUM];
int tag_len;
/*
* tag name to identify a mount Non-null terminated
*/
char *tag;
struct list_head chan_list;
};
static struct list_head virtio_chan_list;
/* How many bytes left in this page. */
static unsigned int rest_of_page(void *data)
{
return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
}
/**
* p9_virtio_close - reclaim resources of a channel
* @client: client instance
*
* This reclaims a channel by freeing its resources and
* reseting its inuse flag.
*
*/
static void p9_virtio_close(struct p9_client *client)
{
struct virtio_chan *chan = client->trans;
mutex_lock(&virtio_9p_lock);
if (chan)
chan->inuse = false;
mutex_unlock(&virtio_9p_lock);
}
/**
* req_done - callback which signals activity from the server
* @vq: virtio queue activity was received on
*
* This notifies us that the server has triggered some activity
* on the virtio channel - most likely a response to request we
* sent. Figure out which requests now have responses and wake up
* those threads.
*
* Bugs: could do with some additional sanity checking, but appears to work.
*
*/
static void req_done(struct virtqueue *vq)
{
struct virtio_chan *chan = vq->vdev->priv;
struct p9_fcall *rc;
unsigned int len;
struct p9_req_t *req;
unsigned long flags;
p9_debug(P9_DEBUG_TRANS, ": request done\n");
while (1) {
spin_lock_irqsave(&chan->lock, flags);
rc = virtqueue_get_buf(chan->vq, &len);
if (rc == NULL) {
spin_unlock_irqrestore(&chan->lock, flags);
break;
}
chan->ring_bufs_avail = 1;
spin_unlock_irqrestore(&chan->lock, flags);
/* Wakeup if anyone waiting for VirtIO ring space. */
wake_up(chan->vc_wq);
p9_debug(P9_DEBUG_TRANS, ": rc %p\n", rc);
p9_debug(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag);
req = p9_tag_lookup(chan->client, rc->tag);
req->status = REQ_STATUS_RCVD;
p9_client_cb(chan->client, req);
}
}
/**
* pack_sg_list - pack a scatter gather list from a linear buffer
* @sg: scatter/gather list to pack into
* @start: which segment of the sg_list to start at
* @limit: maximum segment to pack data to
* @data: data to pack into scatter/gather list
* @count: amount of data to pack into the scatter/gather list
*
* sg_lists have multiple segments of various sizes. This will pack
* arbitrary data into an existing scatter gather list, segmenting the
* data as necessary within constraints.
*
*/
static int pack_sg_list(struct scatterlist *sg, int start,
int limit, char *data, int count)
{
int s;
int index = start;
while (count) {
s = rest_of_page(data);
if (s > count)
s = count;
BUG_ON(index > limit);
/* Make sure we don't terminate early. */
sg_unmark_end(&sg[index]);
sg_set_buf(&sg[index++], data, s);
count -= s;
data += s;
}
if (index-start)
sg_mark_end(&sg[index - 1]);
return index-start;
}
/* We don't currently allow canceling of virtio requests */
static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
{
return 1;
}
/**
* pack_sg_list_p - Just like pack_sg_list. Instead of taking a buffer,
* this takes a list of pages.
* @sg: scatter/gather list to pack into
* @start: which segment of the sg_list to start at
* @pdata: a list of pages to add into sg.
* @nr_pages: number of pages to pack into the scatter/gather list
* @data: data to pack into scatter/gather list
* @count: amount of data to pack into the scatter/gather list
*/
static int
pack_sg_list_p(struct scatterlist *sg, int start, int limit,
struct page **pdata, int nr_pages, char *data, int count)
{
int i = 0, s;
int data_off;
int index = start;
BUG_ON(nr_pages > (limit - start));
/*
* if the first page doesn't start at
* page boundary find the offset
*/
data_off = offset_in_page(data);
while (nr_pages) {
s = rest_of_page(data);
if (s > count)
s = count;
/* Make sure we don't terminate early. */
sg_unmark_end(&sg[index]);
sg_set_page(&sg[index++], pdata[i++], s, data_off);
data_off = 0;
data += s;
count -= s;
nr_pages--;
}
if (index-start)
sg_mark_end(&sg[index - 1]);
return index - start;
}
/**
* p9_virtio_request - issue a request
* @client: client instance issuing the request
* @req: request to be issued
*
*/
static int
p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
{
int err;
int in, out, out_sgs, in_sgs;
unsigned long flags;
struct virtio_chan *chan = client->trans;
struct scatterlist *sgs[2];
p9_debug(P9_DEBUG_TRANS, "9p debug: virtio request\n");
req->status = REQ_STATUS_SENT;
req_retry:
spin_lock_irqsave(&chan->lock, flags);
out_sgs = in_sgs = 0;
/* Handle out VirtIO ring buffers */
out = pack_sg_list(chan->sg, 0,
VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
if (out)
sgs[out_sgs++] = chan->sg;
in = pack_sg_list(chan->sg, out,
VIRTQUEUE_NUM, req->rc->sdata, req->rc->capacity);
if (in)
sgs[out_sgs + in_sgs++] = chan->sg + out;
err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req->tc,
GFP_ATOMIC);
if (err < 0) {
if (err == -ENOSPC) {
chan->ring_bufs_avail = 0;
spin_unlock_irqrestore(&chan->lock, flags);
err = wait_event_interruptible(*chan->vc_wq,
chan->ring_bufs_avail);
if (err == -ERESTARTSYS)
return err;
p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n");
goto req_retry;
} else {
spin_unlock_irqrestore(&chan->lock, flags);
p9_debug(P9_DEBUG_TRANS,
"virtio rpc add_sgs returned failure\n");
return -EIO;
}
}
virtqueue_kick(chan->vq);
spin_unlock_irqrestore(&chan->lock, flags);
p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
return 0;
}
static int p9_get_mapped_pages(struct virtio_chan *chan,
struct page **pages, char *data,
int nr_pages, int write, int kern_buf)
{
int err;
if (!kern_buf) {
/*
* We allow only p9_max_pages pinned. We wait for the
* Other zc request to finish here
*/
if (atomic_read(&vp_pinned) >= chan->p9_max_pages) {
err = wait_event_interruptible(vp_wq,
(atomic_read(&vp_pinned) < chan->p9_max_pages));
if (err == -ERESTARTSYS)
return err;
}
err = p9_payload_gup(data, &nr_pages, pages, write);
if (err < 0)
return err;
atomic_add(nr_pages, &vp_pinned);
} else {
/* kernel buffer, no need to pin pages */
int s, index = 0;
int count = nr_pages;
while (nr_pages) {
s = rest_of_page(data);
if (is_vmalloc_addr(data))
pages[index++] = vmalloc_to_page(data);
else
pages[index++] = kmap_to_page(data);
data += s;
nr_pages--;
}
nr_pages = count;
}
return nr_pages;
}
/**
* p9_virtio_zc_request - issue a zero copy request
* @client: client instance issuing the request
* @req: request to be issued
* @uidata: user bffer that should be ued for zero copy read
* @uodata: user buffer that shoud be user for zero copy write
* @inlen: read buffer size
* @olen: write buffer size
* @hdrlen: reader header size, This is the size of response protocol data
*
*/
static int
p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
char *uidata, char *uodata, int inlen,
int outlen, int in_hdr_len, int kern_buf)
{
int in, out, err, out_sgs, in_sgs;
unsigned long flags;
int in_nr_pages = 0, out_nr_pages = 0;
struct page **in_pages = NULL, **out_pages = NULL;
struct virtio_chan *chan = client->trans;
struct scatterlist *sgs[4];
p9_debug(P9_DEBUG_TRANS, "virtio request\n");
if (uodata) {
out_nr_pages = p9_nr_pages(uodata, outlen);
out_pages = kmalloc(sizeof(struct page *) * out_nr_pages,
GFP_NOFS);
if (!out_pages) {
err = -ENOMEM;
goto err_out;
}
out_nr_pages = p9_get_mapped_pages(chan, out_pages, uodata,
out_nr_pages, 0, kern_buf);
if (out_nr_pages < 0) {
err = out_nr_pages;
kfree(out_pages);
out_pages = NULL;
goto err_out;
}
}
if (uidata) {
in_nr_pages = p9_nr_pages(uidata, inlen);
in_pages = kmalloc(sizeof(struct page *) * in_nr_pages,
GFP_NOFS);
if (!in_pages) {
err = -ENOMEM;
goto err_out;
}
in_nr_pages = p9_get_mapped_pages(chan, in_pages, uidata,
in_nr_pages, 1, kern_buf);
if (in_nr_pages < 0) {
err = in_nr_pages;
kfree(in_pages);
in_pages = NULL;
goto err_out;
}
}
req->status = REQ_STATUS_SENT;
req_retry_pinned:
spin_lock_irqsave(&chan->lock, flags);
out_sgs = in_sgs = 0;
/* out data */
out = pack_sg_list(chan->sg, 0,
VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
if (out)
sgs[out_sgs++] = chan->sg;
if (out_pages) {
sgs[out_sgs++] = chan->sg + out;
out += pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM,
out_pages, out_nr_pages, uodata, outlen);
}
/*
* Take care of in data
* For example TREAD have 11.
* 11 is the read/write header = PDU Header(7) + IO Size (4).
* Arrange in such a way that server places header in the
* alloced memory and payload onto the user buffer.
*/
in = pack_sg_list(chan->sg, out,
VIRTQUEUE_NUM, req->rc->sdata, in_hdr_len);
if (in)
sgs[out_sgs + in_sgs++] = chan->sg + out;
if (in_pages) {
sgs[out_sgs + in_sgs++] = chan->sg + out + in;
in += pack_sg_list_p(chan->sg, out + in, VIRTQUEUE_NUM,
in_pages, in_nr_pages, uidata, inlen);
}
BUG_ON(out_sgs + in_sgs > ARRAY_SIZE(sgs));
err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req->tc,
GFP_ATOMIC);
if (err < 0) {
if (err == -ENOSPC) {
chan->ring_bufs_avail = 0;
spin_unlock_irqrestore(&chan->lock, flags);
err = wait_event_interruptible(*chan->vc_wq,
chan->ring_bufs_avail);
if (err == -ERESTARTSYS)
goto err_out;
p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n");
goto req_retry_pinned;
} else {
spin_unlock_irqrestore(&chan->lock, flags);
p9_debug(P9_DEBUG_TRANS,
"virtio rpc add_sgs returned failure\n");
err = -EIO;
goto err_out;
}
}
virtqueue_kick(chan->vq);
spin_unlock_irqrestore(&chan->lock, flags);
p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
err = wait_event_interruptible(*req->wq,
req->status >= REQ_STATUS_RCVD);
/*
* Non kernel buffers are pinned, unpin them
*/
err_out:
if (!kern_buf) {
if (in_pages) {
p9_release_pages(in_pages, in_nr_pages);
atomic_sub(in_nr_pages, &vp_pinned);
}
if (out_pages) {
p9_release_pages(out_pages, out_nr_pages);
atomic_sub(out_nr_pages, &vp_pinned);
}
/* wakeup anybody waiting for slots to pin pages */
wake_up(&vp_wq);
}
kfree(in_pages);
kfree(out_pages);
return err;
}
static ssize_t p9_mount_tag_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct virtio_chan *chan;
struct virtio_device *vdev;
vdev = dev_to_virtio(dev);
chan = vdev->priv;
return snprintf(buf, chan->tag_len + 1, "%s", chan->tag);
}
static DEVICE_ATTR(mount_tag, 0444, p9_mount_tag_show, NULL);
/**
* p9_virtio_probe - probe for existence of 9P virtio channels
* @vdev: virtio device to probe
*
* This probes for existing virtio channels.
*
*/
static int p9_virtio_probe(struct virtio_device *vdev)
{
__u16 tag_len;
char *tag;
int err;
struct virtio_chan *chan;
chan = kmalloc(sizeof(struct virtio_chan), GFP_KERNEL);
if (!chan) {
pr_err("Failed to allocate virtio 9P channel\n");
err = -ENOMEM;
goto fail;
}
chan->vdev = vdev;
/* We expect one virtqueue, for requests. */
chan->vq = virtio_find_single_vq(vdev, req_done, "requests");
if (IS_ERR(chan->vq)) {
err = PTR_ERR(chan->vq);
goto out_free_vq;
}
chan->vq->vdev->priv = chan;
spin_lock_init(&chan->lock);
sg_init_table(chan->sg, VIRTQUEUE_NUM);
chan->inuse = false;
if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) {
vdev->config->get(vdev,
offsetof(struct virtio_9p_config, tag_len),
&tag_len, sizeof(tag_len));
} else {
err = -EINVAL;
goto out_free_vq;
}
tag = kmalloc(tag_len, GFP_KERNEL);
if (!tag) {
err = -ENOMEM;
goto out_free_vq;
}
vdev->config->get(vdev, offsetof(struct virtio_9p_config, tag),
tag, tag_len);
chan->tag = tag;
chan->tag_len = tag_len;
err = sysfs_create_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
if (err) {
goto out_free_tag;
}
chan->vc_wq = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL);
if (!chan->vc_wq) {
err = -ENOMEM;
goto out_free_tag;
}
init_waitqueue_head(chan->vc_wq);
chan->ring_bufs_avail = 1;
/* Ceiling limit to avoid denial of service attacks */
chan->p9_max_pages = nr_free_buffer_pages()/4;
mutex_lock(&virtio_9p_lock);
list_add_tail(&chan->chan_list, &virtio_chan_list);
mutex_unlock(&virtio_9p_lock);
/* Let udev rules use the new mount_tag attribute. */
kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE);
return 0;
out_free_tag:
kfree(tag);
out_free_vq:
vdev->config->del_vqs(vdev);
kfree(chan);
fail:
return err;
}
/**
* p9_virtio_create - allocate a new virtio channel
* @client: client instance invoking this transport
* @devname: string identifying the channel to connect to (unused)
* @args: args passed from sys_mount() for per-transport options (unused)
*
* This sets up a transport channel for 9p communication. Right now
* we only match the first available channel, but eventually we couldlook up
* alternate channels by matching devname versus a virtio_config entry.
* We use a simple reference count mechanism to ensure that only a single
* mount has a channel open at a time.
*
*/
static int
p9_virtio_create(struct p9_client *client, const char *devname, char *args)
{
struct virtio_chan *chan;
int ret = -ENOENT;
int found = 0;
mutex_lock(&virtio_9p_lock);
list_for_each_entry(chan, &virtio_chan_list, chan_list) {
if (!strncmp(devname, chan->tag, chan->tag_len) &&
strlen(devname) == chan->tag_len) {
if (!chan->inuse) {
chan->inuse = true;
found = 1;
break;
}
ret = -EBUSY;
}
}
mutex_unlock(&virtio_9p_lock);
if (!found) {
pr_err("no channels available\n");
return ret;
}
client->trans = (void *)chan;
client->status = Connected;
chan->client = client;
return 0;
}
/**
* p9_virtio_remove - clean up resources associated with a virtio device
* @vdev: virtio device to remove
*
*/
static void p9_virtio_remove(struct virtio_device *vdev)
{
struct virtio_chan *chan = vdev->priv;
if (chan->inuse)
p9_virtio_close(chan->client);
vdev->config->del_vqs(vdev);
mutex_lock(&virtio_9p_lock);
list_del(&chan->chan_list);
mutex_unlock(&virtio_9p_lock);
sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE);
kfree(chan->tag);
kfree(chan->vc_wq);
kfree(chan);
}
static struct virtio_device_id id_table[] = {
{ VIRTIO_ID_9P, VIRTIO_DEV_ANY_ID },
{ 0 },
};
static unsigned int features[] = {
VIRTIO_9P_MOUNT_TAG,
};
/* The standard "struct lguest_driver": */
static struct virtio_driver p9_virtio_drv = {
.feature_table = features,
.feature_table_size = ARRAY_SIZE(features),
.driver.name = KBUILD_MODNAME,
.driver.owner = THIS_MODULE,
.id_table = id_table,
.probe = p9_virtio_probe,
.remove = p9_virtio_remove,
};
static struct p9_trans_module p9_virtio_trans = {
.name = "virtio",
.create = p9_virtio_create,
.close = p9_virtio_close,
.request = p9_virtio_request,
.zc_request = p9_virtio_zc_request,
.cancel = p9_virtio_cancel,
/*
* We leave one entry for input and one entry for response
* headers. We also skip one more entry to accomodate, address
* that are not at page boundary, that can result in an extra
* page in zero copy.
*/
.maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3),
.def = 0,
.owner = THIS_MODULE,
};
/* The standard init function */
static int __init p9_virtio_init(void)
{
INIT_LIST_HEAD(&virtio_chan_list);
v9fs_register_trans(&p9_virtio_trans);
return register_virtio_driver(&p9_virtio_drv);
}
static void __exit p9_virtio_cleanup(void)
{
unregister_virtio_driver(&p9_virtio_drv);
v9fs_unregister_trans(&p9_virtio_trans);
}
module_init(p9_virtio_init);
module_exit(p9_virtio_cleanup);
MODULE_DEVICE_TABLE(virtio, id_table);
MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
MODULE_DESCRIPTION("Virtio 9p Transport");
MODULE_LICENSE("GPL");

View File

@@ -1,141 +0,0 @@
/*
* net/9p/util.c
*
* This file contains some helper functions
*
* Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/parser.h>
#include <linux/idr.h>
#include <linux/slab.h>
#include <net/9p/9p.h>
/**
* struct p9_idpool - per-connection accounting for tag idpool
* @lock: protects the pool
* @pool: idr to allocate tag id from
*
*/
struct p9_idpool {
spinlock_t lock;
struct idr pool;
};
/**
* p9_idpool_create - create a new per-connection id pool
*
*/
struct p9_idpool *p9_idpool_create(void)
{
struct p9_idpool *p;
p = kmalloc(sizeof(struct p9_idpool), GFP_KERNEL);
if (!p)
return ERR_PTR(-ENOMEM);
spin_lock_init(&p->lock);
idr_init(&p->pool);
return p;
}
EXPORT_SYMBOL(p9_idpool_create);
/**
* p9_idpool_destroy - create a new per-connection id pool
* @p: idpool to destroy
*/
void p9_idpool_destroy(struct p9_idpool *p)
{
idr_destroy(&p->pool);
kfree(p);
}
EXPORT_SYMBOL(p9_idpool_destroy);
/**
* p9_idpool_get - allocate numeric id from pool
* @p: pool to allocate from
*
* Bugs: This seems to be an awful generic function, should it be in idr.c with
* the lock included in struct idr?
*/
int p9_idpool_get(struct p9_idpool *p)
{
int i;
unsigned long flags;
idr_preload(GFP_NOFS);
spin_lock_irqsave(&p->lock, flags);
/* no need to store exactly p, we just need something non-null */
i = idr_alloc(&p->pool, p, 0, 0, GFP_NOWAIT);
spin_unlock_irqrestore(&p->lock, flags);
idr_preload_end();
if (i < 0)
return -1;
p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", i, p);
return i;
}
EXPORT_SYMBOL(p9_idpool_get);
/**
* p9_idpool_put - release numeric id from pool
* @id: numeric id which is being released
* @p: pool to release id into
*
* Bugs: This seems to be an awful generic function, should it be in idr.c with
* the lock included in struct idr?
*/
void p9_idpool_put(int id, struct p9_idpool *p)
{
unsigned long flags;
p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", id, p);
spin_lock_irqsave(&p->lock, flags);
idr_remove(&p->pool, id);
spin_unlock_irqrestore(&p->lock, flags);
}
EXPORT_SYMBOL(p9_idpool_put);
/**
* p9_idpool_check - check if the specified id is available
* @id: id to check
* @p: pool to check
*/
int p9_idpool_check(int id, struct p9_idpool *p)
{
return idr_find(&p->pool, id) != NULL;
}
EXPORT_SYMBOL(p9_idpool_check);

View File

@@ -1,677 +0,0 @@
/*
* linux/fs/9p/v9fs.c
*
* This file contains functions assisting in mapping VFS to 9P2000
*
* Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/parser.h>
#include <linux/idr.h>
#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "cache.h"
static DEFINE_SPINLOCK(v9fs_sessionlist_lock);
static LIST_HEAD(v9fs_sessionlist);
struct kmem_cache *v9fs_inode_cache;
/*
* Option Parsing (code inspired by NFS code)
* NOTE: each transport will parse its own options
*/
enum {
/* Options that take integer arguments */
Opt_debug, Opt_dfltuid, Opt_dfltgid, Opt_afid,
/* String options */
Opt_uname, Opt_remotename, Opt_trans, Opt_cache, Opt_cachetag,
/* Options that take no arguments */
Opt_nodevmap,
/* Cache options */
Opt_cache_loose, Opt_fscache,
/* Access options */
Opt_access, Opt_posixacl,
/* Error token */
Opt_err
};
static const match_table_t tokens = {
{Opt_debug, "debug=%x"},
{Opt_dfltuid, "dfltuid=%u"},
{Opt_dfltgid, "dfltgid=%u"},
{Opt_afid, "afid=%u"},
{Opt_uname, "uname=%s"},
{Opt_remotename, "aname=%s"},
{Opt_nodevmap, "nodevmap"},
{Opt_cache, "cache=%s"},
{Opt_cache_loose, "loose"},
{Opt_fscache, "fscache"},
{Opt_cachetag, "cachetag=%s"},
{Opt_access, "access=%s"},
{Opt_posixacl, "posixacl"},
{Opt_err, NULL}
};
/* Interpret mount options for cache mode */
static int get_cache_mode(char *s)
{
int version = -EINVAL;
if (!strcmp(s, "loose")) {
version = CACHE_LOOSE;
p9_debug(P9_DEBUG_9P, "Cache mode: loose\n");
} else if (!strcmp(s, "fscache")) {
version = CACHE_FSCACHE;
p9_debug(P9_DEBUG_9P, "Cache mode: fscache\n");
} else if (!strcmp(s, "none")) {
version = CACHE_NONE;
p9_debug(P9_DEBUG_9P, "Cache mode: none\n");
} else
pr_info("Unknown Cache mode %s\n", s);
return version;
}
/**
* v9fs_parse_options - parse mount options into session structure
* @v9ses: existing v9fs session information
*
* Return 0 upon success, -ERRNO upon failure.
*/
static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
{
char *options, *tmp_options;
substring_t args[MAX_OPT_ARGS];
char *p;
int option = 0;
char *s, *e;
int ret = 0;
/* setup defaults */
v9ses->afid = ~0;
v9ses->debug = 0;
v9ses->cache = CACHE_NONE;
#ifdef CONFIG_9P_FSCACHE
v9ses->cachetag = NULL;
#endif
if (!opts)
return 0;
tmp_options = kstrdup(opts, GFP_KERNEL);
if (!tmp_options) {
ret = -ENOMEM;
goto fail_option_alloc;
}
options = tmp_options;
while ((p = strsep(&options, ",")) != NULL) {
int token, r;
if (!*p)
continue;
token = match_token(p, tokens, args);
switch (token) {
case Opt_debug:
r = match_int(&args[0], &option);
if (r < 0) {
p9_debug(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
ret = r;
continue;
}
v9ses->debug = option;
#ifdef CONFIG_NET_9P_DEBUG
p9_debug_level = option;
#endif
break;
case Opt_dfltuid:
r = match_int(&args[0], &option);
if (r < 0) {
p9_debug(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
ret = r;
continue;
}
v9ses->dfltuid = make_kuid(current_user_ns(), option);
if (!uid_valid(v9ses->dfltuid)) {
p9_debug(P9_DEBUG_ERROR,
"uid field, but not a uid?\n");
ret = -EINVAL;
continue;
}
break;
case Opt_dfltgid:
r = match_int(&args[0], &option);
if (r < 0) {
p9_debug(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
ret = r;
continue;
}
v9ses->dfltgid = make_kgid(current_user_ns(), option);
if (!gid_valid(v9ses->dfltgid)) {
p9_debug(P9_DEBUG_ERROR,
"gid field, but not a gid?\n");
ret = -EINVAL;
continue;
}
break;
case Opt_afid:
r = match_int(&args[0], &option);
if (r < 0) {
p9_debug(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
ret = r;
continue;
}
v9ses->afid = option;
break;
case Opt_uname:
kfree(v9ses->uname);
v9ses->uname = match_strdup(&args[0]);
if (!v9ses->uname) {
ret = -ENOMEM;
goto free_and_return;
}
break;
case Opt_remotename:
kfree(v9ses->aname);
v9ses->aname = match_strdup(&args[0]);
if (!v9ses->aname) {
ret = -ENOMEM;
goto free_and_return;
}
break;
case Opt_nodevmap:
v9ses->nodev = 1;
break;
case Opt_cache_loose:
v9ses->cache = CACHE_LOOSE;
break;
case Opt_fscache:
v9ses->cache = CACHE_FSCACHE;
break;
case Opt_cachetag:
#ifdef CONFIG_9P_FSCACHE
v9ses->cachetag = match_strdup(&args[0]);
#endif
break;
case Opt_cache:
s = match_strdup(&args[0]);
if (!s) {
ret = -ENOMEM;
p9_debug(P9_DEBUG_ERROR,
"problem allocating copy of cache arg\n");
goto free_and_return;
}
ret = get_cache_mode(s);
if (ret == -EINVAL) {
kfree(s);
goto free_and_return;
}
v9ses->cache = ret;
kfree(s);
break;
case Opt_access:
s = match_strdup(&args[0]);
if (!s) {
ret = -ENOMEM;
p9_debug(P9_DEBUG_ERROR,
"problem allocating copy of access arg\n");
goto free_and_return;
}
v9ses->flags &= ~V9FS_ACCESS_MASK;
if (strcmp(s, "user") == 0)
v9ses->flags |= V9FS_ACCESS_USER;
else if (strcmp(s, "any") == 0)
v9ses->flags |= V9FS_ACCESS_ANY;
else if (strcmp(s, "client") == 0) {
v9ses->flags |= V9FS_ACCESS_CLIENT;
} else {
uid_t uid;
v9ses->flags |= V9FS_ACCESS_SINGLE;
uid = simple_strtoul(s, &e, 10);
if (*e != '\0') {
ret = -EINVAL;
pr_info("Unknown access argument %s\n",
s);
kfree(s);
goto free_and_return;
}
v9ses->uid = make_kuid(current_user_ns(), uid);
if (!uid_valid(v9ses->uid)) {
ret = -EINVAL;
pr_info("Uknown uid %s\n", s);
kfree(s);
goto free_and_return;
}
}
kfree(s);
break;
case Opt_posixacl:
#ifdef CONFIG_9P_FS_POSIX_ACL
v9ses->flags |= V9FS_POSIX_ACL;
#else
p9_debug(P9_DEBUG_ERROR,
"Not defined CONFIG_9P_FS_POSIX_ACL. Ignoring posixacl option\n");
#endif
break;
default:
continue;
}
}
free_and_return:
kfree(tmp_options);
fail_option_alloc:
return ret;
}
/**
* v9fs_session_init - initialize session
* @v9ses: session information structure
* @dev_name: device being mounted
* @data: options
*
*/
struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
const char *dev_name, char *data)
{
int retval = -EINVAL;
struct p9_fid *fid;
int rc;
v9ses->uname = kstrdup(V9FS_DEFUSER, GFP_KERNEL);
if (!v9ses->uname)
return ERR_PTR(-ENOMEM);
v9ses->aname = kstrdup(V9FS_DEFANAME, GFP_KERNEL);
if (!v9ses->aname) {
kfree(v9ses->uname);
return ERR_PTR(-ENOMEM);
}
init_rwsem(&v9ses->rename_sem);
rc = bdi_setup_and_register(&v9ses->bdi, "9p", BDI_CAP_MAP_COPY);
if (rc) {
kfree(v9ses->aname);
kfree(v9ses->uname);
return ERR_PTR(rc);
}
spin_lock(&v9fs_sessionlist_lock);
list_add(&v9ses->slist, &v9fs_sessionlist);
spin_unlock(&v9fs_sessionlist_lock);
v9ses->uid = INVALID_UID;
v9ses->dfltuid = V9FS_DEFUID;
v9ses->dfltgid = V9FS_DEFGID;
v9ses->clnt = p9_client_create(dev_name, data);
if (IS_ERR(v9ses->clnt)) {
retval = PTR_ERR(v9ses->clnt);
v9ses->clnt = NULL;
p9_debug(P9_DEBUG_ERROR, "problem initializing 9p client\n");
goto error;
}
v9ses->flags = V9FS_ACCESS_USER;
if (p9_is_proto_dotl(v9ses->clnt)) {
v9ses->flags = V9FS_ACCESS_CLIENT;
v9ses->flags |= V9FS_PROTO_2000L;
} else if (p9_is_proto_dotu(v9ses->clnt)) {
v9ses->flags |= V9FS_PROTO_2000U;
}
rc = v9fs_parse_options(v9ses, data);
if (rc < 0) {
retval = rc;
goto error;
}
v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;
if (!v9fs_proto_dotl(v9ses) &&
((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
/*
* We support ACCESS_CLIENT only for dotl.
* Fall back to ACCESS_USER
*/
v9ses->flags &= ~V9FS_ACCESS_MASK;
v9ses->flags |= V9FS_ACCESS_USER;
}
/*FIXME !! */
/* for legacy mode, fall back to V9FS_ACCESS_ANY */
if (!(v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses)) &&
((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {
v9ses->flags &= ~V9FS_ACCESS_MASK;
v9ses->flags |= V9FS_ACCESS_ANY;
v9ses->uid = INVALID_UID;
}
if (!v9fs_proto_dotl(v9ses) ||
!((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
/*
* We support ACL checks on clinet only if the protocol is
* 9P2000.L and access is V9FS_ACCESS_CLIENT.
*/
v9ses->flags &= ~V9FS_ACL_MASK;
}
fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, INVALID_UID,
v9ses->aname);
if (IS_ERR(fid)) {
retval = PTR_ERR(fid);
fid = NULL;
p9_debug(P9_DEBUG_ERROR, "cannot attach\n");
goto error;
}
if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE)
fid->uid = v9ses->uid;
else
fid->uid = INVALID_UID;
#ifdef CONFIG_9P_FSCACHE
/* register the session for caching */
v9fs_cache_session_get_cookie(v9ses);
#endif
return fid;
error:
bdi_destroy(&v9ses->bdi);
return ERR_PTR(retval);
}
/**
* v9fs_session_close - shutdown a session
* @v9ses: session information structure
*
*/
void v9fs_session_close(struct v9fs_session_info *v9ses)
{
if (v9ses->clnt) {
p9_client_destroy(v9ses->clnt);
v9ses->clnt = NULL;
}
#ifdef CONFIG_9P_FSCACHE
if (v9ses->fscache) {
v9fs_cache_session_put_cookie(v9ses);
kfree(v9ses->cachetag);
}
#endif
kfree(v9ses->uname);
kfree(v9ses->aname);
bdi_destroy(&v9ses->bdi);
spin_lock(&v9fs_sessionlist_lock);
list_del(&v9ses->slist);
spin_unlock(&v9fs_sessionlist_lock);
}
/**
* v9fs_session_cancel - terminate a session
* @v9ses: session to terminate
*
* mark transport as disconnected and cancel all pending requests.
*/
void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
p9_debug(P9_DEBUG_ERROR, "cancel session %p\n", v9ses);
p9_client_disconnect(v9ses->clnt);
}
/**
* v9fs_session_begin_cancel - Begin terminate of a session
* @v9ses: session to terminate
*
* After this call we don't allow any request other than clunk.
*/
void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses)
{
p9_debug(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses);
p9_client_begin_disconnect(v9ses->clnt);
}
extern int v9fs_error_init(void);
static struct kobject *v9fs_kobj;
#ifdef CONFIG_9P_FSCACHE
/**
* caches_show - list caches associated with a session
*
* Returns the size of buffer written.
*/
static ssize_t caches_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
{
ssize_t n = 0, count = 0, limit = PAGE_SIZE;
struct v9fs_session_info *v9ses;
spin_lock(&v9fs_sessionlist_lock);
list_for_each_entry(v9ses, &v9fs_sessionlist, slist) {
if (v9ses->cachetag) {
n = snprintf(buf, limit, "%s\n", v9ses->cachetag);
if (n < 0) {
count = n;
break;
}
count += n;
limit -= n;
}
}
spin_unlock(&v9fs_sessionlist_lock);
return count;
}
static struct kobj_attribute v9fs_attr_cache = __ATTR_RO(caches);
#endif /* CONFIG_9P_FSCACHE */
static struct attribute *v9fs_attrs[] = {
#ifdef CONFIG_9P_FSCACHE
&v9fs_attr_cache.attr,
#endif
NULL,
};
static struct attribute_group v9fs_attr_group = {
.attrs = v9fs_attrs,
};
/**
* v9fs_sysfs_init - Initialize the v9fs sysfs interface
*
*/
static int v9fs_sysfs_init(void)
{
v9fs_kobj = kobject_create_and_add("9p", fs_kobj);
if (!v9fs_kobj)
return -ENOMEM;
if (sysfs_create_group(v9fs_kobj, &v9fs_attr_group)) {
kobject_put(v9fs_kobj);
return -ENOMEM;
}
return 0;
}
/**
* v9fs_sysfs_cleanup - Unregister the v9fs sysfs interface
*
*/
static void v9fs_sysfs_cleanup(void)
{
sysfs_remove_group(v9fs_kobj, &v9fs_attr_group);
kobject_put(v9fs_kobj);
}
static void v9fs_inode_init_once(void *foo)
{
struct v9fs_inode *v9inode = (struct v9fs_inode *)foo;
#ifdef CONFIG_9P_FSCACHE
v9inode->fscache = NULL;
#endif
memset(&v9inode->qid, 0, sizeof(v9inode->qid));
inode_init_once(&v9inode->vfs_inode);
}
/**
* v9fs_init_inode_cache - initialize a cache for 9P
* Returns 0 on success.
*/
static int v9fs_init_inode_cache(void)
{
v9fs_inode_cache = kmem_cache_create("v9fs_inode_cache",
sizeof(struct v9fs_inode),
0, (SLAB_RECLAIM_ACCOUNT|
SLAB_MEM_SPREAD),
v9fs_inode_init_once);
if (!v9fs_inode_cache)
return -ENOMEM;
return 0;
}
/**
* v9fs_destroy_inode_cache - destroy the cache of 9P inode
*
*/
static void v9fs_destroy_inode_cache(void)
{
/*
* Make sure all delayed rcu free inodes are flushed before we
* destroy cache.
*/
rcu_barrier();
kmem_cache_destroy(v9fs_inode_cache);
}
static int v9fs_cache_register(void)
{
int ret;
ret = v9fs_init_inode_cache();
if (ret < 0)
return ret;
#ifdef CONFIG_9P_FSCACHE
return fscache_register_netfs(&v9fs_cache_netfs);
#else
return ret;
#endif
}
static void v9fs_cache_unregister(void)
{
v9fs_destroy_inode_cache();
#ifdef CONFIG_9P_FSCACHE
fscache_unregister_netfs(&v9fs_cache_netfs);
#endif
}
/**
* init_v9fs - Initialize module
*
*/
static int __init init_v9fs(void)
{
int err;
pr_info("Installing v9fs 9p2000 file system support\n");
/* TODO: Setup list of registered trasnport modules */
err = v9fs_cache_register();
if (err < 0) {
pr_err("Failed to register v9fs for caching\n");
return err;
}
err = v9fs_sysfs_init();
if (err < 0) {
pr_err("Failed to register with sysfs\n");
goto out_cache;
}
err = register_filesystem(&v9fs_fs_type);
if (err < 0) {
pr_err("Failed to register filesystem\n");
goto out_sysfs_cleanup;
}
return 0;
out_sysfs_cleanup:
v9fs_sysfs_cleanup();
out_cache:
v9fs_cache_unregister();
return err;
}
/**
* exit_v9fs - shutdown module
*
*/
static void __exit exit_v9fs(void)
{
v9fs_sysfs_cleanup();
v9fs_cache_unregister();
unregister_filesystem(&v9fs_fs_type);
}
module_init(init_v9fs)
module_exit(exit_v9fs)
MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>");
MODULE_LICENSE("GPL");

View File

@@ -1,227 +0,0 @@
/*
* V9FS definitions.
*
* Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#ifndef FS_9P_V9FS_H
#define FS_9P_V9FS_H
#include <linux/backing-dev.h>
/**
* enum p9_session_flags - option flags for each 9P session
* @V9FS_PROTO_2000U: whether or not to use 9P2000.u extensions
* @V9FS_PROTO_2000L: whether or not to use 9P2000.l extensions
* @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
* @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
* @V9FS_ACCESS_CLIENT: Just like user, but access check is performed on client.
* @V9FS_ACCESS_ANY: use a single attach for all users
* @V9FS_ACCESS_MASK: bit mask of different ACCESS options
* @V9FS_POSIX_ACL: POSIX ACLs are enforced
*
* Session flags reflect options selected by users at mount time
*/
#define V9FS_ACCESS_ANY (V9FS_ACCESS_SINGLE | \
V9FS_ACCESS_USER | \
V9FS_ACCESS_CLIENT)
#define V9FS_ACCESS_MASK V9FS_ACCESS_ANY
#define V9FS_ACL_MASK V9FS_POSIX_ACL
enum p9_session_flags {
V9FS_PROTO_2000U = 0x01,
V9FS_PROTO_2000L = 0x02,
V9FS_ACCESS_SINGLE = 0x04,
V9FS_ACCESS_USER = 0x08,
V9FS_ACCESS_CLIENT = 0x10,
V9FS_POSIX_ACL = 0x20
};
/* possible values of ->cache */
/**
* enum p9_cache_modes - user specified cache preferences
* @CACHE_NONE: do not cache data, dentries, or directory contents (default)
* @CACHE_LOOSE: cache data, dentries, and directory contents w/no consistency
*
* eventually support loose, tight, time, session, default always none
*/
enum p9_cache_modes {
CACHE_NONE,
CACHE_LOOSE,
CACHE_FSCACHE,
};
/**
* struct v9fs_session_info - per-instance session information
* @flags: session options of type &p9_session_flags
* @nodev: set to 1 to disable device mapping
* @debug: debug level
* @afid: authentication handle
* @cache: cache mode of type &p9_cache_modes
* @cachetag: the tag of the cache associated with this session
* @fscache: session cookie associated with FS-Cache
* @options: copy of options string given by user
* @uname: string user name to mount hierarchy as
* @aname: mount specifier for remote hierarchy
* @maxdata: maximum data to be sent/recvd per protocol message
* @dfltuid: default numeric userid to mount hierarchy as
* @dfltgid: default numeric groupid to mount hierarchy as
* @uid: if %V9FS_ACCESS_SINGLE, the numeric uid which mounted the hierarchy
* @clnt: reference to 9P network client instantiated for this session
* @slist: reference to list of registered 9p sessions
*
* This structure holds state for each session instance established during
* a sys_mount() .
*
* Bugs: there seems to be a lot of state which could be condensed and/or
* removed.
*/
struct v9fs_session_info {
/* options */
unsigned char flags;
unsigned char nodev;
unsigned short debug;
unsigned int afid;
unsigned int cache;
#ifdef CONFIG_9P_FSCACHE
char *cachetag;
struct fscache_cookie *fscache;
#endif
char *uname; /* user name to mount as */
char *aname; /* name of remote hierarchy being mounted */
unsigned int maxdata; /* max data for client interface */
kuid_t dfltuid; /* default uid/muid for legacy support */
kgid_t dfltgid; /* default gid for legacy support */
kuid_t uid; /* if ACCESS_SINGLE, the uid that has access */
struct p9_client *clnt; /* 9p client */
struct list_head slist; /* list of sessions registered with v9fs */
struct backing_dev_info bdi;
struct rw_semaphore rename_sem;
};
/* cache_validity flags */
#define V9FS_INO_INVALID_ATTR 0x01
struct v9fs_inode {
#ifdef CONFIG_9P_FSCACHE
spinlock_t fscache_lock;
struct fscache_cookie *fscache;
#endif
struct p9_qid qid;
unsigned int cache_validity;
struct p9_fid *writeback_fid;
struct mutex v_mutex;
struct inode vfs_inode;
};
static inline struct v9fs_inode *V9FS_I(const struct inode *inode)
{
return container_of(inode, struct v9fs_inode, vfs_inode);
}
struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
char *);
extern void v9fs_session_close(struct v9fs_session_info *v9ses);
extern void v9fs_session_cancel(struct v9fs_session_info *v9ses);
extern void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses);
extern struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
unsigned int flags);
extern int v9fs_vfs_unlink(struct inode *i, struct dentry *d);
extern int v9fs_vfs_rmdir(struct inode *i, struct dentry *d);
extern int v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry);
extern void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd,
void *p);
extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
struct p9_fid *fid,
struct super_block *sb, int new);
extern const struct inode_operations v9fs_dir_inode_operations_dotl;
extern const struct inode_operations v9fs_file_inode_operations_dotl;
extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
struct p9_fid *fid,
struct super_block *sb, int new);
/* other default globals */
#define V9FS_PORT 564
#define V9FS_DEFUSER "nobody"
#define V9FS_DEFANAME ""
#define V9FS_DEFUID KUIDT_INIT(-2)
#define V9FS_DEFGID KGIDT_INIT(-2)
static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
{
return (inode->i_sb->s_fs_info);
}
static inline struct v9fs_session_info *v9fs_dentry2v9ses(struct dentry *dentry)
{
return dentry->d_sb->s_fs_info;
}
static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses)
{
return v9ses->flags & V9FS_PROTO_2000U;
}
static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
{
return v9ses->flags & V9FS_PROTO_2000L;
}
/**
* v9fs_get_inode_from_fid - Helper routine to populate an inode by
* issuing a attribute request
* @v9ses: session information
* @fid: fid to issue attribute request for
* @sb: superblock on which to create inode
*
*/
static inline struct inode *
v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb)
{
if (v9fs_proto_dotl(v9ses))
return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 0);
else
return v9fs_inode_from_fid(v9ses, fid, sb, 0);
}
/**
* v9fs_get_new_inode_from_fid - Helper routine to populate an inode by
* issuing a attribute request
* @v9ses: session information
* @fid: fid to issue attribute request for
* @sb: superblock on which to create inode
*
*/
static inline struct inode *
v9fs_get_new_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb)
{
if (v9fs_proto_dotl(v9ses))
return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 1);
else
return v9fs_inode_from_fid(v9ses, fid, sb, 1);
}
#endif

View File

@@ -1,88 +0,0 @@
/*
* V9FS VFS extensions.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#ifndef FS_9P_V9FS_VFS_H
#define FS_9P_V9FS_VFS_H
/* plan9 semantics are that created files are implicitly opened.
* But linux semantics are that you call create, then open.
* the plan9 approach is superior as it provides an atomic
* open.
* we track the create fid here. When the file is opened, if fidopen is
* non-zero, we use the fid and can skip some steps.
* there may be a better way to do this, but I don't know it.
* one BAD way is to clunk the fid on create, then open it again:
* you lose the atomicity of file open
*/
/* special case:
* unlink calls remove, which is an implicit clunk. So we have to track
* that kind of thing so that we don't try to clunk a dead fid.
*/
#define P9_LOCK_TIMEOUT (30*HZ)
extern struct file_system_type v9fs_fs_type;
extern const struct address_space_operations v9fs_addr_operations;
extern const struct file_operations v9fs_file_operations;
extern const struct file_operations v9fs_file_operations_dotl;
extern const struct file_operations v9fs_dir_operations;
extern const struct file_operations v9fs_dir_operations_dotl;
extern const struct dentry_operations v9fs_dentry_operations;
extern const struct dentry_operations v9fs_cached_dentry_operations;
extern const struct file_operations v9fs_cached_file_operations;
extern const struct file_operations v9fs_cached_file_operations_dotl;
extern struct kmem_cache *v9fs_inode_cache;
struct inode *v9fs_alloc_inode(struct super_block *sb);
void v9fs_destroy_inode(struct inode *inode);
struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t);
int v9fs_init_inode(struct v9fs_session_info *v9ses,
struct inode *inode, umode_t mode, dev_t);
void v9fs_evict_inode(struct inode *inode);
ino_t v9fs_qid2ino(struct p9_qid *qid);
void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
void v9fs_stat2inode_dotl(struct p9_stat_dotl *, struct inode *);
int v9fs_dir_release(struct inode *inode, struct file *filp);
int v9fs_file_open(struct inode *inode, struct file *file);
void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
int v9fs_uflags2omode(int uflags, int extended);
ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64);
ssize_t v9fs_fid_readn(struct p9_fid *, char *, char __user *, u32, u64);
void v9fs_blank_wstat(struct p9_wstat *wstat);
int v9fs_vfs_setattr_dotl(struct dentry *, struct iattr *);
int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
int datasync);
ssize_t v9fs_file_write_internal(struct inode *, struct p9_fid *,
const char __user *, size_t, loff_t *, int);
int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode);
int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode);
static inline void v9fs_invalidate_inode_attr(struct inode *inode)
{
struct v9fs_inode *v9inode;
v9inode = V9FS_I(inode);
v9inode->cache_validity |= V9FS_INO_INVALID_ATTR;
return;
}
int v9fs_open_to_dotl_flags(int flags);
#endif

View File

@@ -1,353 +0,0 @@
/*
* linux/fs/9p/vfs_addr.c
*
* This file contians vfs address (mmap) ops for 9P2000.
*
* Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/inet.h>
#include <linux/pagemap.h>
#include <linux/idr.h>
#include <linux/sched.h>
#include <linux/aio.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "cache.h"
#include "fid.h"
/**
* v9fs_fid_readpage - read an entire page in from 9P
*
* @fid: fid being read
* @page: structure to page
*
*/
static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
{
int retval;
loff_t offset;
char *buffer;
struct inode *inode;
inode = page->mapping->host;
p9_debug(P9_DEBUG_VFS, "\n");
BUG_ON(!PageLocked(page));
retval = v9fs_readpage_from_fscache(inode, page);
if (retval == 0)
return retval;
buffer = kmap(page);
offset = page_offset(page);
retval = v9fs_fid_readn(fid, buffer, NULL, PAGE_CACHE_SIZE, offset);
if (retval < 0) {
v9fs_uncache_page(inode, page);
goto done;
}
memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval);
flush_dcache_page(page);
SetPageUptodate(page);
v9fs_readpage_to_fscache(inode, page);
retval = 0;
done:
kunmap(page);
unlock_page(page);
return retval;
}
/**
* v9fs_vfs_readpage - read an entire page in from 9P
*
* @filp: file being read
* @page: structure to page
*
*/
static int v9fs_vfs_readpage(struct file *filp, struct page *page)
{
return v9fs_fid_readpage(filp->private_data, page);
}
/**
* v9fs_vfs_readpages - read a set of pages from 9P
*
* @filp: file being read
* @mapping: the address space
* @pages: list of pages to read
* @nr_pages: count of pages to read
*
*/
static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping,
struct list_head *pages, unsigned nr_pages)
{
int ret = 0;
struct inode *inode;
inode = mapping->host;
p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, filp);
ret = v9fs_readpages_from_fscache(inode, mapping, pages, &nr_pages);
if (ret == 0)
return ret;
ret = read_cache_pages(mapping, pages, (void *)v9fs_vfs_readpage, filp);
p9_debug(P9_DEBUG_VFS, " = %d\n", ret);
return ret;
}
/**
* v9fs_release_page - release the private state associated with a page
*
* Returns 1 if the page can be released, false otherwise.
*/
static int v9fs_release_page(struct page *page, gfp_t gfp)
{
if (PagePrivate(page))
return 0;
return v9fs_fscache_release_page(page, gfp);
}
/**
* v9fs_invalidate_page - Invalidate a page completely or partially
*
* @page: structure to page
* @offset: offset in the page
*/
static void v9fs_invalidate_page(struct page *page, unsigned long offset)
{
/*
* If called with zero offset, we should release
* the private state assocated with the page
*/
if (offset == 0)
v9fs_fscache_invalidate_page(page);
}
static int v9fs_vfs_writepage_locked(struct page *page)
{
char *buffer;
int retval, len;
loff_t offset, size;
mm_segment_t old_fs;
struct v9fs_inode *v9inode;
struct inode *inode = page->mapping->host;
v9inode = V9FS_I(inode);
size = i_size_read(inode);
if (page->index == size >> PAGE_CACHE_SHIFT)
len = size & ~PAGE_CACHE_MASK;
else
len = PAGE_CACHE_SIZE;
set_page_writeback(page);
buffer = kmap(page);
offset = page_offset(page);
old_fs = get_fs();
set_fs(get_ds());
/* We should have writeback_fid always set */
BUG_ON(!v9inode->writeback_fid);
retval = v9fs_file_write_internal(inode,
v9inode->writeback_fid,
(__force const char __user *)buffer,
len, &offset, 0);
if (retval > 0)
retval = 0;
set_fs(old_fs);
kunmap(page);
end_page_writeback(page);
return retval;
}
static int v9fs_vfs_writepage(struct page *page, struct writeback_control *wbc)
{
int retval;
retval = v9fs_vfs_writepage_locked(page);
if (retval < 0) {
if (retval == -EAGAIN) {
redirty_page_for_writepage(wbc, page);
retval = 0;
} else {
SetPageError(page);
mapping_set_error(page->mapping, retval);
}
} else
retval = 0;
unlock_page(page);
return retval;
}
/**
* v9fs_launder_page - Writeback a dirty page
* Returns 0 on success.
*/
static int v9fs_launder_page(struct page *page)
{
int retval;
struct inode *inode = page->mapping->host;
v9fs_fscache_wait_on_page_write(inode, page);
if (clear_page_dirty_for_io(page)) {
retval = v9fs_vfs_writepage_locked(page);
if (retval)
return retval;
}
return 0;
}
/**
* v9fs_direct_IO - 9P address space operation for direct I/O
* @rw: direction (read or write)
* @iocb: target I/O control block
* @iov: array of vectors that define I/O buffer
* @pos: offset in file to begin the operation
* @nr_segs: size of iovec array
*
* The presence of v9fs_direct_IO() in the address space ops vector
* allowes open() O_DIRECT flags which would have failed otherwise.
*
* In the non-cached mode, we shunt off direct read and write requests before
* the VFS gets them, so this method should never be called.
*
* Direct IO is not 'yet' supported in the cached mode. Hence when
* this routine is called through generic_file_aio_read(), the read/write fails
* with an error.
*
*/
static ssize_t
v9fs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
loff_t pos, unsigned long nr_segs)
{
/*
* FIXME
* Now that we do caching with cache mode enabled, We need
* to support direct IO
*/
p9_debug(P9_DEBUG_VFS, "v9fs_direct_IO: v9fs_direct_IO (%s) off/no(%lld/%lu) EINVAL\n",
iocb->ki_filp->f_path.dentry->d_name.name,
(long long)pos, nr_segs);
return -EINVAL;
}
static int v9fs_write_begin(struct file *filp, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
int retval = 0;
struct page *page;
struct v9fs_inode *v9inode;
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
struct inode *inode = mapping->host;
v9inode = V9FS_I(inode);
start:
page = grab_cache_page_write_begin(mapping, index, flags);
if (!page) {
retval = -ENOMEM;
goto out;
}
BUG_ON(!v9inode->writeback_fid);
if (PageUptodate(page))
goto out;
if (len == PAGE_CACHE_SIZE)
goto out;
retval = v9fs_fid_readpage(v9inode->writeback_fid, page);
page_cache_release(page);
if (!retval)
goto start;
out:
*pagep = page;
return retval;
}
static int v9fs_write_end(struct file *filp, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata)
{
loff_t last_pos = pos + copied;
struct inode *inode = page->mapping->host;
if (unlikely(copied < len)) {
/*
* zero out the rest of the area
*/
unsigned from = pos & (PAGE_CACHE_SIZE - 1);
zero_user(page, from + copied, len - copied);
flush_dcache_page(page);
}
if (!PageUptodate(page))
SetPageUptodate(page);
/*
* No need to use i_size_read() here, the i_size
* cannot change under us because we hold the i_mutex.
*/
if (last_pos > inode->i_size) {
inode_add_bytes(inode, last_pos - inode->i_size);
i_size_write(inode, last_pos);
}
set_page_dirty(page);
unlock_page(page);
page_cache_release(page);
return copied;
}
const struct address_space_operations v9fs_addr_operations = {
.readpage = v9fs_vfs_readpage,
.readpages = v9fs_vfs_readpages,
.set_page_dirty = __set_page_dirty_nobuffers,
.writepage = v9fs_vfs_writepage,
.write_begin = v9fs_write_begin,
.write_end = v9fs_write_end,
.releasepage = v9fs_release_page,
.invalidatepage = v9fs_invalidate_page,
.launder_page = v9fs_launder_page,
.direct_IO = v9fs_direct_IO,
};

View File

@@ -1,139 +0,0 @@
/*
* linux/fs/9p/vfs_dentry.c
*
* This file contians vfs dentry ops for the 9P2000 protocol.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/pagemap.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/inet.h>
#include <linux/namei.h>
#include <linux/idr.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
/**
* v9fs_dentry_delete - called when dentry refcount equals 0
* @dentry: dentry in question
*
* By returning 1 here we should remove cacheing of unused
* dentry components.
*
*/
static int v9fs_dentry_delete(const struct dentry *dentry)
{
p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n",
dentry->d_name.name, dentry);
return 1;
}
/**
* v9fs_cached_dentry_delete - called when dentry refcount equals 0
* @dentry: dentry in question
*
*/
static int v9fs_cached_dentry_delete(const struct dentry *dentry)
{
p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n",
dentry->d_name.name, dentry);
/* Don't cache negative dentries */
if (!dentry->d_inode)
return 1;
return 0;
}
/**
* v9fs_dentry_release - called when dentry is going to be freed
* @dentry: dentry that is being release
*
*/
static void v9fs_dentry_release(struct dentry *dentry)
{
struct hlist_node *p, *n;
p9_debug(P9_DEBUG_VFS, " dentry: %s (%p)\n",
dentry->d_name.name, dentry);
hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata)
p9_client_clunk(hlist_entry(p, struct p9_fid, dlist));
dentry->d_fsdata = NULL;
}
static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
{
struct p9_fid *fid;
struct inode *inode;
struct v9fs_inode *v9inode;
if (flags & LOOKUP_RCU)
return -ECHILD;
inode = dentry->d_inode;
if (!inode)
goto out_valid;
v9inode = V9FS_I(inode);
if (v9inode->cache_validity & V9FS_INO_INVALID_ATTR) {
int retval;
struct v9fs_session_info *v9ses;
fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid))
return PTR_ERR(fid);
v9ses = v9fs_inode2v9ses(inode);
if (v9fs_proto_dotl(v9ses))
retval = v9fs_refresh_inode_dotl(fid, inode);
else
retval = v9fs_refresh_inode(fid, inode);
if (retval == -ENOENT)
return 0;
if (retval < 0)
return retval;
}
out_valid:
return 1;
}
const struct dentry_operations v9fs_cached_dentry_operations = {
.d_revalidate = v9fs_lookup_revalidate,
.d_weak_revalidate = v9fs_lookup_revalidate,
.d_delete = v9fs_cached_dentry_delete,
.d_release = v9fs_dentry_release,
};
const struct dentry_operations v9fs_dentry_operations = {
.d_delete = v9fs_dentry_delete,
.d_release = v9fs_dentry_release,
};

View File

@@ -1,269 +0,0 @@
/*
* linux/fs/9p/vfs_dir.c
*
* This file contains vfs directory ops for the 9P2000 protocol.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/inet.h>
#include <linux/idr.h>
#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
/**
* struct p9_rdir - readdir accounting
* @mutex: mutex protecting readdir
* @head: start offset of current dirread buffer
* @tail: end offset of current dirread buffer
* @buf: dirread buffer
*
* private structure for keeping track of readdir
* allocated on demand
*/
struct p9_rdir {
int head;
int tail;
uint8_t buf[];
};
/**
* dt_type - return file type
* @mistat: mistat structure
*
*/
static inline int dt_type(struct p9_wstat *mistat)
{
unsigned long perm = mistat->mode;
int rettype = DT_REG;
if (perm & P9_DMDIR)
rettype = DT_DIR;
if (perm & P9_DMSYMLINK)
rettype = DT_LNK;
return rettype;
}
static void p9stat_init(struct p9_wstat *stbuf)
{
stbuf->name = NULL;
stbuf->uid = NULL;
stbuf->gid = NULL;
stbuf->muid = NULL;
stbuf->extension = NULL;
}
/**
* v9fs_alloc_rdir_buf - Allocate buffer used for read and readdir
* @filp: opened file structure
* @buflen: Length in bytes of buffer to allocate
*
*/
static struct p9_rdir *v9fs_alloc_rdir_buf(struct file *filp, int buflen)
{
struct p9_fid *fid = filp->private_data;
if (!fid->rdir)
fid->rdir = kzalloc(sizeof(struct p9_rdir) + buflen, GFP_KERNEL);
return fid->rdir;
}
/**
* v9fs_dir_readdir - read a directory
* @filp: opened file structure
* @dirent: directory structure ???
* @filldir: function to populate directory structure ???
*
*/
static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
int over;
struct p9_wstat st;
int err = 0;
struct p9_fid *fid;
int buflen;
int reclen = 0;
struct p9_rdir *rdir;
p9_debug(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
fid = filp->private_data;
buflen = fid->clnt->msize - P9_IOHDRSZ;
rdir = v9fs_alloc_rdir_buf(filp, buflen);
if (!rdir)
return -ENOMEM;
while (1) {
if (rdir->tail == rdir->head) {
err = v9fs_file_readn(filp, rdir->buf, NULL,
buflen, filp->f_pos);
if (err <= 0)
return err;
rdir->head = 0;
rdir->tail = err;
}
while (rdir->head < rdir->tail) {
p9stat_init(&st);
err = p9stat_read(fid->clnt, rdir->buf + rdir->head,
rdir->tail - rdir->head, &st);
if (err) {
p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
p9stat_free(&st);
return -EIO;
}
reclen = st.size+2;
over = filldir(dirent, st.name, strlen(st.name),
filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st));
p9stat_free(&st);
if (over)
return 0;
rdir->head += reclen;
filp->f_pos += reclen;
}
}
}
/**
* v9fs_dir_readdir_dotl - read a directory
* @filp: opened file structure
* @dirent: buffer to fill dirent structures
* @filldir: function to populate dirent structures
*
*/
static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent,
filldir_t filldir)
{
int over;
int err = 0;
struct p9_fid *fid;
int buflen;
struct p9_rdir *rdir;
struct p9_dirent curdirent;
u64 oldoffset = 0;
p9_debug(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
fid = filp->private_data;
buflen = fid->clnt->msize - P9_READDIRHDRSZ;
rdir = v9fs_alloc_rdir_buf(filp, buflen);
if (!rdir)
return -ENOMEM;
while (1) {
if (rdir->tail == rdir->head) {
err = p9_client_readdir(fid, rdir->buf, buflen,
filp->f_pos);
if (err <= 0)
return err;
rdir->head = 0;
rdir->tail = err;
}
while (rdir->head < rdir->tail) {
err = p9dirent_read(fid->clnt, rdir->buf + rdir->head,
rdir->tail - rdir->head,
&curdirent);
if (err < 0) {
p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
return -EIO;
}
/* d_off in dirent structure tracks the offset into
* the next dirent in the dir. However, filldir()
* expects offset into the current dirent. Hence
* while calling filldir send the offset from the
* previous dirent structure.
*/
over = filldir(dirent, curdirent.d_name,
strlen(curdirent.d_name),
oldoffset, v9fs_qid2ino(&curdirent.qid),
curdirent.d_type);
oldoffset = curdirent.d_off;
if (over)
return 0;
filp->f_pos = curdirent.d_off;
rdir->head += err;
}
}
}
/**
* v9fs_dir_release - close a directory
* @inode: inode of the directory
* @filp: file pointer to a directory
*
*/
int v9fs_dir_release(struct inode *inode, struct file *filp)
{
struct p9_fid *fid;
fid = filp->private_data;
p9_debug(P9_DEBUG_VFS, "inode: %p filp: %p fid: %d\n",
inode, filp, fid ? fid->fid : -1);
if (fid)
p9_client_clunk(fid);
return 0;
}
const struct file_operations v9fs_dir_operations = {
.read = generic_read_dir,
.llseek = generic_file_llseek,
.readdir = v9fs_dir_readdir,
.open = v9fs_file_open,
.release = v9fs_dir_release,
};
const struct file_operations v9fs_dir_operations_dotl = {
.read = generic_read_dir,
.llseek = generic_file_llseek,
.readdir = v9fs_dir_readdir_dotl,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.fsync = v9fs_file_fsync_dotl,
};

View File

@@ -1,790 +0,0 @@
/*
* linux/fs/9p/vfs_file.c
*
* This file contians vfs file ops for 9P2000.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/inet.h>
#include <linux/list.h>
#include <linux/pagemap.h>
#include <linux/utsname.h>
#include <asm/uaccess.h>
#include <linux/idr.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
#include "cache.h"
static const struct vm_operations_struct v9fs_file_vm_ops;
/**
* v9fs_file_open - open a file (or directory)
* @inode: inode to be opened
* @file: file being opened
*
*/
int v9fs_file_open(struct inode *inode, struct file *file)
{
int err;
struct v9fs_inode *v9inode;
struct v9fs_session_info *v9ses;
struct p9_fid *fid;
int omode;
p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file);
v9inode = V9FS_I(inode);
v9ses = v9fs_inode2v9ses(inode);
if (v9fs_proto_dotl(v9ses))
omode = v9fs_open_to_dotl_flags(file->f_flags);
else
omode = v9fs_uflags2omode(file->f_flags,
v9fs_proto_dotu(v9ses));
fid = file->private_data;
if (!fid) {
fid = v9fs_fid_clone(file->f_path.dentry);
if (IS_ERR(fid))
return PTR_ERR(fid);
err = p9_client_open(fid, omode);
if (err < 0) {
p9_client_clunk(fid);
return err;
}
if ((file->f_flags & O_APPEND) &&
(!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)))
generic_file_llseek(file, 0, SEEK_END);
}
file->private_data = fid;
mutex_lock(&v9inode->v_mutex);
if (v9ses->cache && !v9inode->writeback_fid &&
((file->f_flags & O_ACCMODE) != O_RDONLY)) {
/*
* clone a fid and add it to writeback_fid
* we do it during open time instead of
* page dirty time via write_begin/page_mkwrite
* because we want write after unlink usecase
* to work.
*/
fid = v9fs_writeback_fid(file->f_path.dentry);
if (IS_ERR(fid)) {
err = PTR_ERR(fid);
mutex_unlock(&v9inode->v_mutex);
goto out_error;
}
v9inode->writeback_fid = (void *) fid;
}
mutex_unlock(&v9inode->v_mutex);
#ifdef CONFIG_9P_FSCACHE
if (v9ses->cache)
v9fs_cache_inode_set_cookie(inode, file);
#endif
return 0;
out_error:
p9_client_clunk(file->private_data);
file->private_data = NULL;
return err;
}
/**
* v9fs_file_lock - lock a file (or directory)
* @filp: file to be locked
* @cmd: lock command
* @fl: file lock structure
*
* Bugs: this looks like a local only lock, we should extend into 9P
* by using open exclusive
*/
static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
{
int res = 0;
struct inode *inode = file_inode(filp);
p9_debug(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
/* No mandatory locks */
if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
return -ENOLCK;
if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
filemap_write_and_wait(inode->i_mapping);
invalidate_mapping_pages(&inode->i_data, 0, -1);
}
return res;
}
static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
{
struct p9_flock flock;
struct p9_fid *fid;
uint8_t status;
int res = 0;
unsigned char fl_type;
fid = filp->private_data;
BUG_ON(fid == NULL);
if ((fl->fl_flags & FL_POSIX) != FL_POSIX)
BUG();
res = posix_lock_file_wait(filp, fl);
if (res < 0)
goto out;
/* convert posix lock to p9 tlock args */
memset(&flock, 0, sizeof(flock));
/* map the lock type */
switch (fl->fl_type) {
case F_RDLCK:
flock.type = P9_LOCK_TYPE_RDLCK;
break;
case F_WRLCK:
flock.type = P9_LOCK_TYPE_WRLCK;
break;
case F_UNLCK:
flock.type = P9_LOCK_TYPE_UNLCK;
break;
}
flock.start = fl->fl_start;
if (fl->fl_end == OFFSET_MAX)
flock.length = 0;
else
flock.length = fl->fl_end - fl->fl_start + 1;
flock.proc_id = fl->fl_pid;
flock.client_id = utsname()->nodename;
if (IS_SETLKW(cmd))
flock.flags = P9_LOCK_FLAGS_BLOCK;
/*
* if its a blocked request and we get P9_LOCK_BLOCKED as the status
* for lock request, keep on trying
*/
for (;;) {
res = p9_client_lock_dotl(fid, &flock, &status);
if (res < 0)
break;
if (status != P9_LOCK_BLOCKED)
break;
if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd))
break;
if (schedule_timeout_interruptible(P9_LOCK_TIMEOUT) != 0)
break;
}
/* map 9p status to VFS status */
switch (status) {
case P9_LOCK_SUCCESS:
res = 0;
break;
case P9_LOCK_BLOCKED:
res = -EAGAIN;
break;
case P9_LOCK_ERROR:
case P9_LOCK_GRACE:
res = -ENOLCK;
break;
default:
BUG();
}
/*
* incase server returned error for lock request, revert
* it locally
*/
if (res < 0 && fl->fl_type != F_UNLCK) {
fl_type = fl->fl_type;
fl->fl_type = F_UNLCK;
res = posix_lock_file_wait(filp, fl);
fl->fl_type = fl_type;
}
out:
return res;
}
static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
{
struct p9_getlock glock;
struct p9_fid *fid;
int res = 0;
fid = filp->private_data;
BUG_ON(fid == NULL);
posix_test_lock(filp, fl);
/*
* if we have a conflicting lock locally, no need to validate
* with server
*/
if (fl->fl_type != F_UNLCK)
return res;
/* convert posix lock to p9 tgetlock args */
memset(&glock, 0, sizeof(glock));
glock.type = P9_LOCK_TYPE_UNLCK;
glock.start = fl->fl_start;
if (fl->fl_end == OFFSET_MAX)
glock.length = 0;
else
glock.length = fl->fl_end - fl->fl_start + 1;
glock.proc_id = fl->fl_pid;
glock.client_id = utsname()->nodename;
res = p9_client_getlock_dotl(fid, &glock);
if (res < 0)
return res;
/* map 9p lock type to os lock type */
switch (glock.type) {
case P9_LOCK_TYPE_RDLCK:
fl->fl_type = F_RDLCK;
break;
case P9_LOCK_TYPE_WRLCK:
fl->fl_type = F_WRLCK;
break;
case P9_LOCK_TYPE_UNLCK:
fl->fl_type = F_UNLCK;
break;
}
if (glock.type != P9_LOCK_TYPE_UNLCK) {
fl->fl_start = glock.start;
if (glock.length == 0)
fl->fl_end = OFFSET_MAX;
else
fl->fl_end = glock.start + glock.length - 1;
fl->fl_pid = glock.proc_id;
}
return res;
}
/**
* v9fs_file_lock_dotl - lock a file (or directory)
* @filp: file to be locked
* @cmd: lock command
* @fl: file lock structure
*
*/
static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl)
{
struct inode *inode = file_inode(filp);
int ret = -ENOLCK;
p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %s\n",
filp, cmd, fl, filp->f_path.dentry->d_name.name);
/* No mandatory locks */
if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
goto out_err;
if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
filemap_write_and_wait(inode->i_mapping);
invalidate_mapping_pages(&inode->i_data, 0, -1);
}
if (IS_SETLK(cmd) || IS_SETLKW(cmd))
ret = v9fs_file_do_lock(filp, cmd, fl);
else if (IS_GETLK(cmd))
ret = v9fs_file_getlock(filp, fl);
else
ret = -EINVAL;
out_err:
return ret;
}
/**
* v9fs_file_flock_dotl - lock a file
* @filp: file to be locked
* @cmd: lock command
* @fl: file lock structure
*
*/
static int v9fs_file_flock_dotl(struct file *filp, int cmd,
struct file_lock *fl)
{
struct inode *inode = file_inode(filp);
int ret = -ENOLCK;
p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %s\n",
filp, cmd, fl, filp->f_path.dentry->d_name.name);
/* No mandatory locks */
if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
goto out_err;
if (!(fl->fl_flags & FL_FLOCK))
goto out_err;
if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
filemap_write_and_wait(inode->i_mapping);
invalidate_mapping_pages(&inode->i_data, 0, -1);
}
/* Convert flock to posix lock */
fl->fl_owner = (fl_owner_t)filp;
fl->fl_start = 0;
fl->fl_end = OFFSET_MAX;
fl->fl_flags |= FL_POSIX;
fl->fl_flags ^= FL_FLOCK;
if (IS_SETLK(cmd) | IS_SETLKW(cmd))
ret = v9fs_file_do_lock(filp, cmd, fl);
else
ret = -EINVAL;
out_err:
return ret;
}
/**
* v9fs_fid_readn - read from a fid
* @fid: fid to read
* @data: data buffer to read data into
* @udata: user data buffer to read data into
* @count: size of buffer
* @offset: offset at which to read data
*
*/
ssize_t
v9fs_fid_readn(struct p9_fid *fid, char *data, char __user *udata, u32 count,
u64 offset)
{
int n, total, size;
p9_debug(P9_DEBUG_VFS, "fid %d offset %llu count %d\n",
fid->fid, (long long unsigned)offset, count);
n = 0;
total = 0;
size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
do {
n = p9_client_read(fid, data, udata, offset, count);
if (n <= 0)
break;
if (data)
data += n;
if (udata)
udata += n;
offset += n;
count -= n;
total += n;
} while (count > 0 && n == size);
if (n < 0)
total = n;
return total;
}
/**
* v9fs_file_readn - read from a file
* @filp: file pointer to read
* @data: data buffer to read data into
* @udata: user data buffer to read data into
* @count: size of buffer
* @offset: offset at which to read data
*
*/
ssize_t
v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count,
u64 offset)
{
return v9fs_fid_readn(filp->private_data, data, udata, count, offset);
}
/**
* v9fs_file_read - read from a file
* @filp: file pointer to read
* @udata: user data buffer to read data into
* @count: size of buffer
* @offset: offset at which to read data
*
*/
static ssize_t
v9fs_file_read(struct file *filp, char __user *udata, size_t count,
loff_t * offset)
{
int ret;
struct p9_fid *fid;
size_t size;
p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n", count, *offset);
fid = filp->private_data;
size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
if (count > size)
ret = v9fs_file_readn(filp, NULL, udata, count, *offset);
else
ret = p9_client_read(fid, NULL, udata, *offset, count);
if (ret > 0)
*offset += ret;
return ret;
}
ssize_t
v9fs_file_write_internal(struct inode *inode, struct p9_fid *fid,
const char __user *data, size_t count,
loff_t *offset, int invalidate)
{
int n;
loff_t i_size;
size_t total = 0;
struct p9_client *clnt;
loff_t origin = *offset;
unsigned long pg_start, pg_end;
p9_debug(P9_DEBUG_VFS, "data %p count %d offset %x\n",
data, (int)count, (int)*offset);
clnt = fid->clnt;
do {
n = p9_client_write(fid, NULL, data+total, origin+total, count);
if (n <= 0)
break;
count -= n;
total += n;
} while (count > 0);
if (invalidate && (total > 0)) {
pg_start = origin >> PAGE_CACHE_SHIFT;
pg_end = (origin + total - 1) >> PAGE_CACHE_SHIFT;
if (inode->i_mapping && inode->i_mapping->nrpages)
invalidate_inode_pages2_range(inode->i_mapping,
pg_start, pg_end);
*offset += total;
i_size = i_size_read(inode);
if (*offset > i_size) {
inode_add_bytes(inode, *offset - i_size);
i_size_write(inode, *offset);
}
}
if (n < 0)
return n;
return total;
}
/**
* v9fs_file_write - write to a file
* @filp: file pointer to write
* @data: data buffer to write data from
* @count: size of buffer
* @offset: offset at which to write data
*
*/
static ssize_t
v9fs_file_write(struct file *filp, const char __user * data,
size_t count, loff_t *offset)
{
ssize_t retval = 0;
loff_t origin = *offset;
retval = generic_write_checks(filp, &origin, &count, 0);
if (retval)
goto out;
retval = -EINVAL;
if ((ssize_t) count < 0)
goto out;
retval = 0;
if (!count)
goto out;
retval = v9fs_file_write_internal(file_inode(filp),
filp->private_data,
data, count, &origin, 1);
/* update offset on successful write */
if (retval > 0)
*offset = origin;
out:
return retval;
}
static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end,
int datasync)
{
struct p9_fid *fid;
struct inode *inode = filp->f_mapping->host;
struct p9_wstat wstat;
int retval;
retval = filemap_write_and_wait_range(inode->i_mapping, start, end);
if (retval)
return retval;
mutex_lock(&inode->i_mutex);
p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
fid = filp->private_data;
v9fs_blank_wstat(&wstat);
retval = p9_client_wstat(fid, &wstat);
mutex_unlock(&inode->i_mutex);
return retval;
}
int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
int datasync)
{
struct p9_fid *fid;
struct inode *inode = filp->f_mapping->host;
int retval;
retval = filemap_write_and_wait_range(inode->i_mapping, start, end);
if (retval)
return retval;
mutex_lock(&inode->i_mutex);
p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
fid = filp->private_data;
retval = p9_client_fsync(fid, datasync);
mutex_unlock(&inode->i_mutex);
return retval;
}
static int
v9fs_file_mmap(struct file *file, struct vm_area_struct *vma)
{
int retval;
retval = generic_file_mmap(file, vma);
if (!retval)
vma->vm_ops = &v9fs_file_vm_ops;
return retval;
}
static int
v9fs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct v9fs_inode *v9inode;
struct page *page = vmf->page;
struct file *filp = vma->vm_file;
struct inode *inode = file_inode(filp);
p9_debug(P9_DEBUG_VFS, "page %p fid %lx\n",
page, (unsigned long)filp->private_data);
/* Update file times before taking page lock */
file_update_time(filp);
v9inode = V9FS_I(inode);
/* make sure the cache has finished storing the page */
v9fs_fscache_wait_on_page_write(inode, page);
BUG_ON(!v9inode->writeback_fid);
lock_page(page);
if (page->mapping != inode->i_mapping)
goto out_unlock;
wait_for_stable_page(page);
return VM_FAULT_LOCKED;
out_unlock:
unlock_page(page);
return VM_FAULT_NOPAGE;
}
static ssize_t
v9fs_direct_read(struct file *filp, char __user *udata, size_t count,
loff_t *offsetp)
{
loff_t size, offset;
struct inode *inode;
struct address_space *mapping;
offset = *offsetp;
mapping = filp->f_mapping;
inode = mapping->host;
if (!count)
return 0;
size = i_size_read(inode);
if (offset < size)
filemap_write_and_wait_range(mapping, offset,
offset + count - 1);
return v9fs_file_read(filp, udata, count, offsetp);
}
/**
* v9fs_cached_file_read - read from a file
* @filp: file pointer to read
* @udata: user data buffer to read data into
* @count: size of buffer
* @offset: offset at which to read data
*
*/
static ssize_t
v9fs_cached_file_read(struct file *filp, char __user *data, size_t count,
loff_t *offset)
{
if (filp->f_flags & O_DIRECT)
return v9fs_direct_read(filp, data, count, offset);
return do_sync_read(filp, data, count, offset);
}
static ssize_t
v9fs_direct_write(struct file *filp, const char __user * data,
size_t count, loff_t *offsetp)
{
loff_t offset;
ssize_t retval;
struct inode *inode;
struct address_space *mapping;
offset = *offsetp;
mapping = filp->f_mapping;
inode = mapping->host;
if (!count)
return 0;
mutex_lock(&inode->i_mutex);
retval = filemap_write_and_wait_range(mapping, offset,
offset + count - 1);
if (retval)
goto err_out;
/*
* After a write we want buffered reads to be sure to go to disk to get
* the new data. We invalidate clean cached page from the region we're
* about to write. We do this *before* the write so that if we fail
* here we fall back to buffered write
*/
if (mapping->nrpages) {
pgoff_t pg_start = offset >> PAGE_CACHE_SHIFT;
pgoff_t pg_end = (offset + count - 1) >> PAGE_CACHE_SHIFT;
retval = invalidate_inode_pages2_range(mapping,
pg_start, pg_end);
/*
* If a page can not be invalidated, fall back
* to buffered write.
*/
if (retval) {
if (retval == -EBUSY)
goto buff_write;
goto err_out;
}
}
retval = v9fs_file_write(filp, data, count, offsetp);
err_out:
mutex_unlock(&inode->i_mutex);
return retval;
buff_write:
mutex_unlock(&inode->i_mutex);
return do_sync_write(filp, data, count, offsetp);
}
/**
* v9fs_cached_file_write - write to a file
* @filp: file pointer to write
* @data: data buffer to write data from
* @count: size of buffer
* @offset: offset at which to write data
*
*/
static ssize_t
v9fs_cached_file_write(struct file *filp, const char __user * data,
size_t count, loff_t *offset)
{
if (filp->f_flags & O_DIRECT)
return v9fs_direct_write(filp, data, count, offset);
return do_sync_write(filp, data, count, offset);
}
static const struct vm_operations_struct v9fs_file_vm_ops = {
.fault = filemap_fault,
.page_mkwrite = v9fs_vm_page_mkwrite,
.remap_pages = generic_file_remap_pages,
};
const struct file_operations v9fs_cached_file_operations = {
.llseek = generic_file_llseek,
.read = v9fs_cached_file_read,
.write = v9fs_cached_file_write,
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.lock = v9fs_file_lock,
.mmap = v9fs_file_mmap,
.fsync = v9fs_file_fsync,
};
const struct file_operations v9fs_cached_file_operations_dotl = {
.llseek = generic_file_llseek,
.read = v9fs_cached_file_read,
.write = v9fs_cached_file_write,
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.lock = v9fs_file_lock_dotl,
.flock = v9fs_file_flock_dotl,
.mmap = v9fs_file_mmap,
.fsync = v9fs_file_fsync_dotl,
};
const struct file_operations v9fs_file_operations = {
.llseek = generic_file_llseek,
.read = v9fs_file_read,
.write = v9fs_file_write,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.lock = v9fs_file_lock,
.mmap = generic_file_readonly_mmap,
.fsync = v9fs_file_fsync,
};
const struct file_operations v9fs_file_operations_dotl = {
.llseek = generic_file_llseek,
.read = v9fs_file_read,
.write = v9fs_file_write,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.lock = v9fs_file_lock_dotl,
.flock = v9fs_file_flock_dotl,
.mmap = generic_file_readonly_mmap,
.fsync = v9fs_file_fsync_dotl,
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,368 +0,0 @@
/*
* linux/fs/9p/vfs_super.c
*
* This file contians superblock ops for 9P2000. It is intended that
* you mount this file system on directories.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/inet.h>
#include <linux/pagemap.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/idr.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/statfs.h>
#include <linux/magic.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
#include "xattr.h"
#include "acl.h"
static const struct super_operations v9fs_super_ops, v9fs_super_ops_dotl;
/**
* v9fs_set_super - set the superblock
* @s: super block
* @data: file system specific data
*
*/
static int v9fs_set_super(struct super_block *s, void *data)
{
s->s_fs_info = data;
return set_anon_super(s, data);
}
/**
* v9fs_fill_super - populate superblock with info
* @sb: superblock
* @v9ses: session information
* @flags: flags propagated from v9fs_mount()
*
*/
static void
v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
int flags, void *data)
{
sb->s_maxbytes = MAX_LFS_FILESIZE;
sb->s_blocksize_bits = fls(v9ses->maxdata - 1);
sb->s_blocksize = 1 << sb->s_blocksize_bits;
sb->s_magic = V9FS_MAGIC;
if (v9fs_proto_dotl(v9ses)) {
sb->s_op = &v9fs_super_ops_dotl;
sb->s_xattr = v9fs_xattr_handlers;
} else
sb->s_op = &v9fs_super_ops;
sb->s_bdi = &v9ses->bdi;
if (v9ses->cache)
sb->s_bdi->ra_pages = (VM_MAX_READAHEAD * 1024)/PAGE_CACHE_SIZE;
sb->s_flags |= MS_ACTIVE | MS_DIRSYNC | MS_NOATIME;
if (!v9ses->cache)
sb->s_flags |= MS_SYNCHRONOUS;
#ifdef CONFIG_9P_FS_POSIX_ACL
if ((v9ses->flags & V9FS_ACL_MASK) == V9FS_POSIX_ACL)
sb->s_flags |= MS_POSIXACL;
#endif
save_mount_options(sb, data);
}
/**
* v9fs_mount - mount a superblock
* @fs_type: file system type
* @flags: mount flags
* @dev_name: device name that was mounted
* @data: mount options
*
*/
static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data)
{
struct super_block *sb = NULL;
struct inode *inode = NULL;
struct dentry *root = NULL;
struct v9fs_session_info *v9ses = NULL;
umode_t mode = S_IRWXUGO | S_ISVTX;
struct p9_fid *fid;
int retval = 0;
p9_debug(P9_DEBUG_VFS, "\n");
v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);
if (!v9ses)
return ERR_PTR(-ENOMEM);
fid = v9fs_session_init(v9ses, dev_name, data);
if (IS_ERR(fid)) {
retval = PTR_ERR(fid);
/*
* we need to call session_close to tear down some
* of the data structure setup by session_init
*/
goto close_session;
}
sb = sget(fs_type, NULL, v9fs_set_super, flags, v9ses);
if (IS_ERR(sb)) {
retval = PTR_ERR(sb);
goto clunk_fid;
}
v9fs_fill_super(sb, v9ses, flags, data);
if (v9ses->cache)
sb->s_d_op = &v9fs_cached_dentry_operations;
else
sb->s_d_op = &v9fs_dentry_operations;
inode = v9fs_get_inode(sb, S_IFDIR | mode, 0);
if (IS_ERR(inode)) {
retval = PTR_ERR(inode);
goto release_sb;
}
root = d_make_root(inode);
if (!root) {
retval = -ENOMEM;
goto release_sb;
}
sb->s_root = root;
if (v9fs_proto_dotl(v9ses)) {
struct p9_stat_dotl *st = NULL;
st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
if (IS_ERR(st)) {
retval = PTR_ERR(st);
goto release_sb;
}
root->d_inode->i_ino = v9fs_qid2ino(&st->qid);
v9fs_stat2inode_dotl(st, root->d_inode);
kfree(st);
} else {
struct p9_wstat *st = NULL;
st = p9_client_stat(fid);
if (IS_ERR(st)) {
retval = PTR_ERR(st);
goto release_sb;
}
root->d_inode->i_ino = v9fs_qid2ino(&st->qid);
v9fs_stat2inode(st, root->d_inode, sb);
p9stat_free(st);
kfree(st);
}
retval = v9fs_get_acl(inode, fid);
if (retval)
goto release_sb;
v9fs_fid_add(root, fid);
p9_debug(P9_DEBUG_VFS, " simple set mount, return 0\n");
return dget(sb->s_root);
clunk_fid:
p9_client_clunk(fid);
close_session:
v9fs_session_close(v9ses);
kfree(v9ses);
return ERR_PTR(retval);
release_sb:
/*
* we will do the session_close and root dentry release
* in the below call. But we need to clunk fid, because we haven't
* attached the fid to dentry so it won't get clunked
* automatically.
*/
p9_client_clunk(fid);
deactivate_locked_super(sb);
return ERR_PTR(retval);
}
/**
* v9fs_kill_super - Kill Superblock
* @s: superblock
*
*/
static void v9fs_kill_super(struct super_block *s)
{
struct v9fs_session_info *v9ses = s->s_fs_info;
p9_debug(P9_DEBUG_VFS, " %p\n", s);
kill_anon_super(s);
v9fs_session_cancel(v9ses);
v9fs_session_close(v9ses);
kfree(v9ses);
s->s_fs_info = NULL;
p9_debug(P9_DEBUG_VFS, "exiting kill_super\n");
}
static void
v9fs_umount_begin(struct super_block *sb)
{
struct v9fs_session_info *v9ses;
v9ses = sb->s_fs_info;
v9fs_session_begin_cancel(v9ses);
}
static int v9fs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
struct v9fs_session_info *v9ses;
struct p9_fid *fid;
struct p9_rstatfs rs;
int res;
fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid)) {
res = PTR_ERR(fid);
goto done;
}
v9ses = v9fs_dentry2v9ses(dentry);
if (v9fs_proto_dotl(v9ses)) {
res = p9_client_statfs(fid, &rs);
if (res == 0) {
buf->f_type = rs.type;
buf->f_bsize = rs.bsize;
buf->f_blocks = rs.blocks;
buf->f_bfree = rs.bfree;
buf->f_bavail = rs.bavail;
buf->f_files = rs.files;
buf->f_ffree = rs.ffree;
buf->f_fsid.val[0] = rs.fsid & 0xFFFFFFFFUL;
buf->f_fsid.val[1] = (rs.fsid >> 32) & 0xFFFFFFFFUL;
buf->f_namelen = rs.namelen;
}
if (res != -ENOSYS)
goto done;
}
res = simple_statfs(dentry, buf);
done:
return res;
}
static int v9fs_drop_inode(struct inode *inode)
{
struct v9fs_session_info *v9ses;
v9ses = v9fs_inode2v9ses(inode);
if (v9ses->cache)
return generic_drop_inode(inode);
/*
* in case of non cached mode always drop the
* the inode because we want the inode attribute
* to always match that on the server.
*/
return 1;
}
static int v9fs_write_inode(struct inode *inode,
struct writeback_control *wbc)
{
int ret;
struct p9_wstat wstat;
struct v9fs_inode *v9inode;
/*
* send an fsync request to server irrespective of
* wbc->sync_mode.
*/
p9_debug(P9_DEBUG_VFS, "%s: inode %p\n", __func__, inode);
v9inode = V9FS_I(inode);
if (!v9inode->writeback_fid)
return 0;
v9fs_blank_wstat(&wstat);
ret = p9_client_wstat(v9inode->writeback_fid, &wstat);
if (ret < 0) {
__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
return ret;
}
return 0;
}
static int v9fs_write_inode_dotl(struct inode *inode,
struct writeback_control *wbc)
{
int ret;
struct v9fs_inode *v9inode;
/*
* send an fsync request to server irrespective of
* wbc->sync_mode.
*/
p9_debug(P9_DEBUG_VFS, "%s: inode %p\n", __func__, inode);
v9inode = V9FS_I(inode);
if (!v9inode->writeback_fid)
return 0;
ret = p9_client_fsync(v9inode->writeback_fid, 0);
if (ret < 0) {
__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
return ret;
}
return 0;
}
static const struct super_operations v9fs_super_ops = {
.alloc_inode = v9fs_alloc_inode,
.destroy_inode = v9fs_destroy_inode,
.statfs = simple_statfs,
.evict_inode = v9fs_evict_inode,
.show_options = generic_show_options,
.umount_begin = v9fs_umount_begin,
.write_inode = v9fs_write_inode,
};
static const struct super_operations v9fs_super_ops_dotl = {
.alloc_inode = v9fs_alloc_inode,
.destroy_inode = v9fs_destroy_inode,
.statfs = v9fs_statfs,
.drop_inode = v9fs_drop_inode,
.evict_inode = v9fs_evict_inode,
.show_options = generic_show_options,
.umount_begin = v9fs_umount_begin,
.write_inode = v9fs_write_inode_dotl,
};
struct file_system_type v9fs_fs_type = {
.name = "9p",
.mount = v9fs_mount,
.kill_sb = v9fs_kill_super,
.owner = THIS_MODULE,
.fs_flags = FS_RENAME_DOES_D_MOVE,
};
MODULE_ALIAS_FS("9p");

View File

@@ -1,175 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "fid.h"
#include "xattr.h"
ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
void *buffer, size_t buffer_size)
{
ssize_t retval;
int msize, read_count;
u64 offset = 0, attr_size;
struct p9_fid *attr_fid;
attr_fid = p9_client_xattrwalk(fid, name, &attr_size);
if (IS_ERR(attr_fid)) {
retval = PTR_ERR(attr_fid);
p9_debug(P9_DEBUG_VFS, "p9_client_attrwalk failed %zd\n",
retval);
attr_fid = NULL;
goto error;
}
if (!buffer_size) {
/* request to get the attr_size */
retval = attr_size;
goto error;
}
if (attr_size > buffer_size) {
retval = -ERANGE;
goto error;
}
msize = attr_fid->clnt->msize;
while (attr_size) {
if (attr_size > (msize - P9_IOHDRSZ))
read_count = msize - P9_IOHDRSZ;
else
read_count = attr_size;
read_count = p9_client_read(attr_fid, ((char *)buffer)+offset,
NULL, offset, read_count);
if (read_count < 0) {
/* error in xattr read */
retval = read_count;
goto error;
}
offset += read_count;
attr_size -= read_count;
}
/* Total read xattr bytes */
retval = offset;
error:
if (attr_fid)
p9_client_clunk(attr_fid);
return retval;
}
/*
* v9fs_xattr_get()
*
* Copy an extended attribute into the buffer
* provided, or compute the buffer size required.
* Buffer is NULL to compute the size of the buffer required.
*
* Returns a negative error number on failure, or the number of bytes
* used / required on success.
*/
ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
void *buffer, size_t buffer_size)
{
struct p9_fid *fid;
p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu\n",
name, buffer_size);
fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid))
return PTR_ERR(fid);
return v9fs_fid_xattr_get(fid, name, buffer, buffer_size);
}
/*
* v9fs_xattr_set()
*
* Create, replace or remove an extended attribute for this inode. Buffer
* is NULL to remove an existing extended attribute, and non-NULL to
* either replace an existing extended attribute, or create a new extended
* attribute. The flags XATTR_REPLACE and XATTR_CREATE
* specify that an extended attribute must exist and must not exist
* previous to the call, respectively.
*
* Returns 0, or a negative error number on failure.
*/
int v9fs_xattr_set(struct dentry *dentry, const char *name,
const void *value, size_t value_len, int flags)
{
struct p9_fid *fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid))
return PTR_ERR(fid);
return v9fs_fid_xattr_set(fid, name, value, value_len, flags);
}
int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
const void *value, size_t value_len, int flags)
{
u64 offset = 0;
int retval, msize, write_count;
p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu flags = %d\n",
name, value_len, flags);
/* Clone it */
fid = p9_client_walk(fid, 0, NULL, 1);
if (IS_ERR(fid))
return PTR_ERR(fid);
/*
* On success fid points to xattr
*/
retval = p9_client_xattrcreate(fid, name, value_len, flags);
if (retval < 0) {
p9_debug(P9_DEBUG_VFS, "p9_client_xattrcreate failed %d\n",
retval);
p9_client_clunk(fid);
return retval;
}
msize = fid->clnt->msize;
while (value_len) {
if (value_len > (msize - P9_IOHDRSZ))
write_count = msize - P9_IOHDRSZ;
else
write_count = value_len;
write_count = p9_client_write(fid, ((char *)value)+offset,
NULL, offset, write_count);
if (write_count < 0) {
/* error in xattr write */
retval = write_count;
break;
}
offset += write_count;
value_len -= write_count;
}
return p9_client_clunk(fid);
}
ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
{
return v9fs_xattr_get(dentry, NULL, buffer, buffer_size);
}
const struct xattr_handler *v9fs_xattr_handlers[] = {
&v9fs_xattr_user_handler,
#ifdef CONFIG_9P_FS_POSIX_ACL
&v9fs_xattr_acl_access_handler,
&v9fs_xattr_acl_default_handler,
#endif
NULL
};

View File

@@ -1,35 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef FS_9P_XATTR_H
#define FS_9P_XATTR_H
#include <linux/xattr.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
extern const struct xattr_handler *v9fs_xattr_handlers[];
extern struct xattr_handler v9fs_xattr_user_handler;
extern const struct xattr_handler v9fs_xattr_acl_access_handler;
extern const struct xattr_handler v9fs_xattr_acl_default_handler;
extern ssize_t v9fs_fid_xattr_get(struct p9_fid *, const char *,
void *, size_t);
extern ssize_t v9fs_xattr_get(struct dentry *, const char *,
void *, size_t);
extern int v9fs_fid_xattr_set(struct p9_fid *, const char *,
const void *, size_t, int);
extern int v9fs_xattr_set(struct dentry *, const char *,
const void *, size_t, int);
extern ssize_t v9fs_listxattr(struct dentry *, char *, size_t);
#endif /* FS_9P_XATTR_H */

View File

@@ -1,80 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include "xattr.h"
static int v9fs_xattr_user_get(struct dentry *dentry, const char *name,
void *buffer, size_t size, int type)
{
int retval;
char *full_name;
size_t name_len;
size_t prefix_len = XATTR_USER_PREFIX_LEN;
if (name == NULL)
return -EINVAL;
if (strcmp(name, "") == 0)
return -EINVAL;
name_len = strlen(name);
full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
if (!full_name)
return -ENOMEM;
memcpy(full_name, XATTR_USER_PREFIX, prefix_len);
memcpy(full_name+prefix_len, name, name_len);
full_name[prefix_len + name_len] = '\0';
retval = v9fs_xattr_get(dentry, full_name, buffer, size);
kfree(full_name);
return retval;
}
static int v9fs_xattr_user_set(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags, int type)
{
int retval;
char *full_name;
size_t name_len;
size_t prefix_len = XATTR_USER_PREFIX_LEN;
if (name == NULL)
return -EINVAL;
if (strcmp(name, "") == 0)
return -EINVAL;
name_len = strlen(name);
full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
if (!full_name)
return -ENOMEM;
memcpy(full_name, XATTR_USER_PREFIX, prefix_len);
memcpy(full_name + prefix_len, name, name_len);
full_name[prefix_len + name_len] = '\0';
retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
kfree(full_name);
return retval;
}
struct xattr_handler v9fs_xattr_user_handler = {
.prefix = XATTR_USER_PREFIX,
.get = v9fs_xattr_user_get,
.set = v9fs_xattr_user_set,
};

View File

@@ -1,35 +0,0 @@
obj-m := 9p.o
9p-objs := \
vfs_super.o \
vfs_inode.o \
vfs_inode_dotl.o \
vfs_addr.o \
vfs_file.o \
vfs_dir.o \
vfs_dentry.o \
v9fs.o \
fid.o \
xattr.o
9p-y += cache.o
9p-n += acl.o
obj-m := 9pnet.o
obj-m += 9pnet_virtio.o
obj-n += 9pnet_rdma.o
9pnet-objs := \
mod.o \
client.o \
error.o \
util.o \
protocol.o \
trans_fd.o \
trans_common.o \
9pnet_virtio-objs := \
trans_virtio.o
9pnet_rdma-objs := \
trans_rdma.o

View File

@@ -1,338 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <linux/module.h>
#include <linux/fs.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/posix_acl_xattr.h>
#include "xattr.h"
#include "acl.h"
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name)
{
ssize_t size;
void *value = NULL;
struct posix_acl *acl = NULL;
size = v9fs_fid_xattr_get(fid, name, NULL, 0);
if (size > 0) {
value = kzalloc(size, GFP_NOFS);
if (!value)
return ERR_PTR(-ENOMEM);
size = v9fs_fid_xattr_get(fid, name, value, size);
if (size > 0) {
acl = posix_acl_from_xattr(&init_user_ns, value, size);
if (IS_ERR(acl))
goto err_out;
}
} else if (size == -ENODATA || size == 0 ||
size == -ENOSYS || size == -EOPNOTSUPP) {
acl = NULL;
} else
acl = ERR_PTR(-EIO);
err_out:
kfree(value);
return acl;
}
int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
{
int retval = 0;
struct posix_acl *pacl, *dacl;
struct v9fs_session_info *v9ses;
v9ses = v9fs_inode2v9ses(inode);
if (((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) ||
((v9ses->flags & V9FS_ACL_MASK) != V9FS_POSIX_ACL)) {
set_cached_acl(inode, ACL_TYPE_DEFAULT, NULL);
set_cached_acl(inode, ACL_TYPE_ACCESS, NULL);
return 0;
}
/* get the default/access acl values and cache them */
dacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_DEFAULT);
pacl = __v9fs_get_acl(fid, POSIX_ACL_XATTR_ACCESS);
if (!IS_ERR(dacl) && !IS_ERR(pacl)) {
set_cached_acl(inode, ACL_TYPE_DEFAULT, dacl);
set_cached_acl(inode, ACL_TYPE_ACCESS, pacl);
} else
retval = -EIO;
if (!IS_ERR(dacl))
posix_acl_release(dacl);
if (!IS_ERR(pacl))
posix_acl_release(pacl);
return retval;
}
static struct posix_acl *v9fs_get_cached_acl(struct inode *inode, int type)
{
struct posix_acl *acl;
/*
* 9p Always cache the acl value when
* instantiating the inode (v9fs_inode_from_fid)
*/
acl = get_cached_acl(inode, type);
BUG_ON(acl == ACL_NOT_CACHED);
return acl;
}
struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type)
{
struct v9fs_session_info *v9ses;
v9ses = v9fs_inode2v9ses(inode);
if (((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT) ||
((v9ses->flags & V9FS_ACL_MASK) != V9FS_POSIX_ACL)) {
/*
* On access = client and acl = on mode get the acl
* values from the server
*/
return NULL;
}
return v9fs_get_cached_acl(inode, type);
}
static int v9fs_set_acl(struct p9_fid *fid, int type, struct posix_acl *acl)
{
int retval;
char *name;
size_t size;
void *buffer;
if (!acl)
return 0;
/* Set a setxattr request to server */
size = posix_acl_xattr_size(acl->a_count);
buffer = kmalloc(size, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
retval = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
if (retval < 0)
goto err_free_out;
switch (type) {
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
break;
case ACL_TYPE_DEFAULT:
name = POSIX_ACL_XATTR_DEFAULT;
break;
default:
BUG();
}
retval = v9fs_fid_xattr_set(fid, name, buffer, size, 0);
err_free_out:
kfree(buffer);
return retval;
}
int v9fs_acl_chmod(struct inode *inode, struct p9_fid *fid)
{
int retval = 0;
struct posix_acl *acl;
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
acl = v9fs_get_cached_acl(inode, ACL_TYPE_ACCESS);
if (acl) {
retval = __posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
if (retval)
return retval;
set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
retval = v9fs_set_acl(fid, ACL_TYPE_ACCESS, acl);
posix_acl_release(acl);
}
return retval;
}
int v9fs_set_create_acl(struct inode *inode, struct p9_fid *fid,
struct posix_acl *dacl, struct posix_acl *acl)
{
set_cached_acl(inode, ACL_TYPE_DEFAULT, dacl);
set_cached_acl(inode, ACL_TYPE_ACCESS, acl);
v9fs_set_acl(fid, ACL_TYPE_DEFAULT, dacl);
v9fs_set_acl(fid, ACL_TYPE_ACCESS, acl);
return 0;
}
void v9fs_put_acl(struct posix_acl *dacl,
struct posix_acl *acl)
{
posix_acl_release(dacl);
posix_acl_release(acl);
}
int v9fs_acl_mode(struct inode *dir, umode_t *modep,
struct posix_acl **dpacl, struct posix_acl **pacl)
{
int retval = 0;
umode_t mode = *modep;
struct posix_acl *acl = NULL;
if (!S_ISLNK(mode)) {
acl = v9fs_get_cached_acl(dir, ACL_TYPE_DEFAULT);
if (IS_ERR(acl))
return PTR_ERR(acl);
if (!acl)
mode &= ~current_umask();
}
if (acl) {
if (S_ISDIR(mode))
*dpacl = posix_acl_dup(acl);
retval = __posix_acl_create(&acl, GFP_NOFS, &mode);
if (retval < 0)
return retval;
if (retval > 0)
*pacl = acl;
else
posix_acl_release(acl);
}
*modep = mode;
return 0;
}
static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
struct dentry *dentry, const char *name,
void *buffer, size_t size)
{
struct v9fs_session_info *v9ses;
struct posix_acl *acl;
int error;
if (strcmp(name, "") != 0)
return -EINVAL;
v9ses = v9fs_dentry2v9ses(dentry);
/*
* We allow set/get/list of acl when access=client is not specified
*/
if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
return v9fs_xattr_get(dentry, handler->prefix, buffer, size);
acl = v9fs_get_cached_acl(d_inode(dentry), handler->flags);
if (IS_ERR(acl))
return PTR_ERR(acl);
if (acl == NULL)
return -ENODATA;
error = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
posix_acl_release(acl);
return error;
}
static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
struct dentry *dentry, const char *name,
const void *value, size_t size, int flags)
{
int retval;
struct posix_acl *acl;
struct v9fs_session_info *v9ses;
struct inode *inode = d_inode(dentry);
if (strcmp(name, "") != 0)
return -EINVAL;
v9ses = v9fs_dentry2v9ses(dentry);
/*
* set the attribute on the remote. Without even looking at the
* xattr value. We leave it to the server to validate
*/
if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
return v9fs_xattr_set(dentry, handler->prefix, value, size,
flags);
if (S_ISLNK(inode->i_mode))
return -EOPNOTSUPP;
if (!inode_owner_or_capable(inode))
return -EPERM;
if (value) {
/* update the cached acl value */
acl = posix_acl_from_xattr(&init_user_ns, value, size);
if (IS_ERR(acl))
return PTR_ERR(acl);
else if (acl) {
retval = posix_acl_valid(acl);
if (retval)
goto err_out;
}
} else
acl = NULL;
switch (handler->flags) {
case ACL_TYPE_ACCESS:
if (acl) {
struct iattr iattr;
struct posix_acl *old_acl = acl;
retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
if (retval)
goto err_out;
if (!acl) {
/*
* ACL can be represented
* by the mode bits. So don't
* update ACL.
*/
posix_acl_release(old_acl);
value = NULL;
size = 0;
}
iattr.ia_valid = ATTR_MODE;
/* FIXME should we update ctime ?
* What is the following setxattr update the
* mode ?
*/
v9fs_vfs_setattr_dotl(dentry, &iattr);
}
break;
case ACL_TYPE_DEFAULT:
if (!S_ISDIR(inode->i_mode)) {
retval = acl ? -EINVAL : 0;
goto err_out;
}
break;
default:
BUG();
}
retval = v9fs_xattr_set(dentry, handler->prefix, value, size, flags);
if (!retval)
set_cached_acl(inode, handler->flags, acl);
err_out:
posix_acl_release(acl);
return retval;
}
const struct xattr_handler v9fs_xattr_acl_access_handler = {
.prefix = POSIX_ACL_XATTR_ACCESS,
.flags = ACL_TYPE_ACCESS,
.get = v9fs_xattr_get_acl,
.set = v9fs_xattr_set_acl,
};
const struct xattr_handler v9fs_xattr_acl_default_handler = {
.prefix = POSIX_ACL_XATTR_DEFAULT,
.flags = ACL_TYPE_DEFAULT,
.get = v9fs_xattr_get_acl,
.set = v9fs_xattr_set_acl,
};

View File

@@ -1,55 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef FS_9P_ACL_H
#define FS_9P_ACL_H
#ifdef CONFIG_9P_FS_POSIX_ACL
extern int v9fs_get_acl(struct inode *, struct p9_fid *);
extern struct posix_acl *v9fs_iop_get_acl(struct inode *inode, int type);
extern int v9fs_acl_chmod(struct inode *, struct p9_fid *);
extern int v9fs_set_create_acl(struct inode *, struct p9_fid *,
struct posix_acl *, struct posix_acl *);
extern int v9fs_acl_mode(struct inode *dir, umode_t *modep,
struct posix_acl **dpacl, struct posix_acl **pacl);
extern void v9fs_put_acl(struct posix_acl *dacl, struct posix_acl *acl);
#else
#define v9fs_iop_get_acl NULL
static inline int v9fs_get_acl(struct inode *inode, struct p9_fid *fid)
{
return 0;
}
static inline int v9fs_acl_chmod(struct inode *inode, struct p9_fid *fid)
{
return 0;
}
static inline int v9fs_set_create_acl(struct inode *inode,
struct p9_fid *fid,
struct posix_acl *dacl,
struct posix_acl *acl)
{
return 0;
}
static inline void v9fs_put_acl(struct posix_acl *dacl,
struct posix_acl *acl)
{
}
static inline int v9fs_acl_mode(struct inode *dir, umode_t *modep,
struct posix_acl **dpacl,
struct posix_acl **pacl)
{
return 0;
}
#endif
#endif /* FS_9P_XATTR_H */

View File

@@ -1,414 +0,0 @@
/*
* V9FS cache definitions.
*
* Copyright (C) 2009 by Abhishek Kulkarni <adkulkar@umail.iu.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/jiffies.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <net/9p/9p.h>
#include "v9fs.h"
#include "cache.h"
#define CACHETAG_LEN 11
struct fscache_netfs v9fs_cache_netfs = {
.name = "9p",
.version = 0,
};
/**
* v9fs_random_cachetag - Generate a random tag to be associated
* with a new cache session.
*
* The value of jiffies is used for a fairly randomly cache tag.
*/
static
int v9fs_random_cachetag(struct v9fs_session_info *v9ses)
{
v9ses->cachetag = kmalloc(CACHETAG_LEN, GFP_KERNEL);
if (!v9ses->cachetag)
return -ENOMEM;
return scnprintf(v9ses->cachetag, CACHETAG_LEN, "%lu", jiffies);
}
static uint16_t v9fs_cache_session_get_key(const void *cookie_netfs_data,
void *buffer, uint16_t bufmax)
{
struct v9fs_session_info *v9ses;
uint16_t klen = 0;
v9ses = (struct v9fs_session_info *)cookie_netfs_data;
p9_debug(P9_DEBUG_FSC, "session %p buf %p size %u\n",
v9ses, buffer, bufmax);
if (v9ses->cachetag)
klen = strlen(v9ses->cachetag);
if (klen > bufmax)
return 0;
memcpy(buffer, v9ses->cachetag, klen);
p9_debug(P9_DEBUG_FSC, "cache session tag %s\n", v9ses->cachetag);
return klen;
}
const struct fscache_cookie_def v9fs_cache_session_index_def = {
.name = "9P.session",
.type = FSCACHE_COOKIE_TYPE_INDEX,
.get_key = v9fs_cache_session_get_key,
};
void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses)
{
/* If no cache session tag was specified, we generate a random one. */
if (!v9ses->cachetag)
v9fs_random_cachetag(v9ses);
v9ses->fscache = fscache_acquire_cookie(v9fs_cache_netfs.primary_index,
&v9fs_cache_session_index_def,
v9ses, true);
p9_debug(P9_DEBUG_FSC, "session %p get cookie %p\n",
v9ses, v9ses->fscache);
}
void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses)
{
p9_debug(P9_DEBUG_FSC, "session %p put cookie %p\n",
v9ses, v9ses->fscache);
fscache_relinquish_cookie(v9ses->fscache, 0);
v9ses->fscache = NULL;
}
static uint16_t v9fs_cache_inode_get_key(const void *cookie_netfs_data,
void *buffer, uint16_t bufmax)
{
const struct v9fs_inode *v9inode = cookie_netfs_data;
memcpy(buffer, &v9inode->qid.path, sizeof(v9inode->qid.path));
p9_debug(P9_DEBUG_FSC, "inode %p get key %llu\n",
&v9inode->vfs_inode, v9inode->qid.path);
return sizeof(v9inode->qid.path);
}
static void v9fs_cache_inode_get_attr(const void *cookie_netfs_data,
uint64_t *size)
{
const struct v9fs_inode *v9inode = cookie_netfs_data;
*size = i_size_read(&v9inode->vfs_inode);
p9_debug(P9_DEBUG_FSC, "inode %p get attr %llu\n",
&v9inode->vfs_inode, *size);
}
static uint16_t v9fs_cache_inode_get_aux(const void *cookie_netfs_data,
void *buffer, uint16_t buflen)
{
const struct v9fs_inode *v9inode = cookie_netfs_data;
memcpy(buffer, &v9inode->qid.version, sizeof(v9inode->qid.version));
p9_debug(P9_DEBUG_FSC, "inode %p get aux %u\n",
&v9inode->vfs_inode, v9inode->qid.version);
return sizeof(v9inode->qid.version);
}
static enum
fscache_checkaux v9fs_cache_inode_check_aux(void *cookie_netfs_data,
const void *buffer,
uint16_t buflen)
{
const struct v9fs_inode *v9inode = cookie_netfs_data;
if (buflen != sizeof(v9inode->qid.version))
return FSCACHE_CHECKAUX_OBSOLETE;
if (memcmp(buffer, &v9inode->qid.version,
sizeof(v9inode->qid.version)))
return FSCACHE_CHECKAUX_OBSOLETE;
return FSCACHE_CHECKAUX_OKAY;
}
static void v9fs_cache_inode_now_uncached(void *cookie_netfs_data)
{
struct v9fs_inode *v9inode = cookie_netfs_data;
struct pagevec pvec;
pgoff_t first;
int loop, nr_pages;
pagevec_init(&pvec, 0);
first = 0;
for (;;) {
nr_pages = pagevec_lookup(&pvec, v9inode->vfs_inode.i_mapping,
first,
PAGEVEC_SIZE - pagevec_count(&pvec));
if (!nr_pages)
break;
for (loop = 0; loop < nr_pages; loop++)
ClearPageFsCache(pvec.pages[loop]);
first = pvec.pages[nr_pages - 1]->index + 1;
pvec.nr = nr_pages;
pagevec_release(&pvec);
cond_resched();
}
}
const struct fscache_cookie_def v9fs_cache_inode_index_def = {
.name = "9p.inode",
.type = FSCACHE_COOKIE_TYPE_DATAFILE,
.get_key = v9fs_cache_inode_get_key,
.get_attr = v9fs_cache_inode_get_attr,
.get_aux = v9fs_cache_inode_get_aux,
.check_aux = v9fs_cache_inode_check_aux,
.now_uncached = v9fs_cache_inode_now_uncached,
};
void v9fs_cache_inode_get_cookie(struct inode *inode)
{
struct v9fs_inode *v9inode;
struct v9fs_session_info *v9ses;
if (!S_ISREG(inode->i_mode))
return;
v9inode = V9FS_I(inode);
if (v9inode->fscache)
return;
v9ses = v9fs_inode2v9ses(inode);
v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
&v9fs_cache_inode_index_def,
v9inode, true);
p9_debug(P9_DEBUG_FSC, "inode %p get cookie %p\n",
inode, v9inode->fscache);
}
void v9fs_cache_inode_put_cookie(struct inode *inode)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
if (!v9inode->fscache)
return;
p9_debug(P9_DEBUG_FSC, "inode %p put cookie %p\n",
inode, v9inode->fscache);
fscache_relinquish_cookie(v9inode->fscache, 0);
v9inode->fscache = NULL;
}
void v9fs_cache_inode_flush_cookie(struct inode *inode)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
if (!v9inode->fscache)
return;
p9_debug(P9_DEBUG_FSC, "inode %p flush cookie %p\n",
inode, v9inode->fscache);
fscache_relinquish_cookie(v9inode->fscache, 1);
v9inode->fscache = NULL;
}
void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
if (!v9inode->fscache)
return;
mutex_lock(&v9inode->fscache_lock);
if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
v9fs_cache_inode_flush_cookie(inode);
else
v9fs_cache_inode_get_cookie(inode);
mutex_unlock(&v9inode->fscache_lock);
}
void v9fs_cache_inode_reset_cookie(struct inode *inode)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
struct v9fs_session_info *v9ses;
struct fscache_cookie *old;
if (!v9inode->fscache)
return;
old = v9inode->fscache;
mutex_lock(&v9inode->fscache_lock);
fscache_relinquish_cookie(v9inode->fscache, 1);
v9ses = v9fs_inode2v9ses(inode);
v9inode->fscache = fscache_acquire_cookie(v9ses->fscache,
&v9fs_cache_inode_index_def,
v9inode, true);
p9_debug(P9_DEBUG_FSC, "inode %p revalidating cookie old %p new %p\n",
inode, old, v9inode->fscache);
mutex_unlock(&v9inode->fscache_lock);
}
int __v9fs_fscache_release_page(struct page *page, gfp_t gfp)
{
struct inode *inode = page->mapping->host;
struct v9fs_inode *v9inode = V9FS_I(inode);
BUG_ON(!v9inode->fscache);
return fscache_maybe_release_page(v9inode->fscache, page, gfp);
}
void __v9fs_fscache_invalidate_page(struct page *page)
{
struct inode *inode = page->mapping->host;
struct v9fs_inode *v9inode = V9FS_I(inode);
BUG_ON(!v9inode->fscache);
if (PageFsCache(page)) {
fscache_wait_on_page_write(v9inode->fscache, page);
BUG_ON(!PageLocked(page));
fscache_uncache_page(v9inode->fscache, page);
}
}
static void v9fs_vfs_readpage_complete(struct page *page, void *data,
int error)
{
if (!error)
SetPageUptodate(page);
unlock_page(page);
}
/**
* __v9fs_readpage_from_fscache - read a page from cache
*
* Returns 0 if the pages are in cache and a BIO is submitted,
* 1 if the pages are not in cache and -error otherwise.
*/
int __v9fs_readpage_from_fscache(struct inode *inode, struct page *page)
{
int ret;
const struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
if (!v9inode->fscache)
return -ENOBUFS;
ret = fscache_read_or_alloc_page(v9inode->fscache,
page,
v9fs_vfs_readpage_complete,
NULL,
GFP_KERNEL);
switch (ret) {
case -ENOBUFS:
case -ENODATA:
p9_debug(P9_DEBUG_FSC, "page/inode not in cache %d\n", ret);
return 1;
case 0:
p9_debug(P9_DEBUG_FSC, "BIO submitted\n");
return ret;
default:
p9_debug(P9_DEBUG_FSC, "ret %d\n", ret);
return ret;
}
}
/**
* __v9fs_readpages_from_fscache - read multiple pages from cache
*
* Returns 0 if the pages are in cache and a BIO is submitted,
* 1 if the pages are not in cache and -error otherwise.
*/
int __v9fs_readpages_from_fscache(struct inode *inode,
struct address_space *mapping,
struct list_head *pages,
unsigned *nr_pages)
{
int ret;
const struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_FSC, "inode %p pages %u\n", inode, *nr_pages);
if (!v9inode->fscache)
return -ENOBUFS;
ret = fscache_read_or_alloc_pages(v9inode->fscache,
mapping, pages, nr_pages,
v9fs_vfs_readpage_complete,
NULL,
mapping_gfp_mask(mapping));
switch (ret) {
case -ENOBUFS:
case -ENODATA:
p9_debug(P9_DEBUG_FSC, "pages/inodes not in cache %d\n", ret);
return 1;
case 0:
BUG_ON(!list_empty(pages));
BUG_ON(*nr_pages != 0);
p9_debug(P9_DEBUG_FSC, "BIO submitted\n");
return ret;
default:
p9_debug(P9_DEBUG_FSC, "ret %d\n", ret);
return ret;
}
}
/**
* __v9fs_readpage_to_fscache - write a page to the cache
*
*/
void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page)
{
int ret;
const struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
ret = fscache_write_page(v9inode->fscache, page, GFP_KERNEL);
p9_debug(P9_DEBUG_FSC, "ret = %d\n", ret);
if (ret != 0)
v9fs_uncache_page(inode, page);
}
/*
* wait for a page to complete writing to the cache
*/
void __v9fs_fscache_wait_on_page_write(struct inode *inode, struct page *page)
{
const struct v9fs_inode *v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_FSC, "inode %p page %p\n", inode, page);
if (PageFsCache(page))
fscache_wait_on_page_write(v9inode->fscache, page);
}

View File

@@ -1,152 +0,0 @@
/*
* V9FS cache definitions.
*
* Copyright (C) 2009 by Abhishek Kulkarni <adkulkar@umail.iu.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#ifndef _9P_CACHE_H
#define _9P_CACHE_H
#ifdef CONFIG_9P_FSCACHE
#include <linux/fscache.h>
#include <linux/spinlock.h>
extern struct fscache_netfs v9fs_cache_netfs;
extern const struct fscache_cookie_def v9fs_cache_session_index_def;
extern const struct fscache_cookie_def v9fs_cache_inode_index_def;
extern void v9fs_cache_session_get_cookie(struct v9fs_session_info *v9ses);
extern void v9fs_cache_session_put_cookie(struct v9fs_session_info *v9ses);
extern void v9fs_cache_inode_get_cookie(struct inode *inode);
extern void v9fs_cache_inode_put_cookie(struct inode *inode);
extern void v9fs_cache_inode_flush_cookie(struct inode *inode);
extern void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *filp);
extern void v9fs_cache_inode_reset_cookie(struct inode *inode);
extern int __v9fs_cache_register(void);
extern void __v9fs_cache_unregister(void);
extern int __v9fs_fscache_release_page(struct page *page, gfp_t gfp);
extern void __v9fs_fscache_invalidate_page(struct page *page);
extern int __v9fs_readpage_from_fscache(struct inode *inode,
struct page *page);
extern int __v9fs_readpages_from_fscache(struct inode *inode,
struct address_space *mapping,
struct list_head *pages,
unsigned *nr_pages);
extern void __v9fs_readpage_to_fscache(struct inode *inode, struct page *page);
extern void __v9fs_fscache_wait_on_page_write(struct inode *inode,
struct page *page);
static inline int v9fs_fscache_release_page(struct page *page,
gfp_t gfp)
{
return __v9fs_fscache_release_page(page, gfp);
}
static inline void v9fs_fscache_invalidate_page(struct page *page)
{
__v9fs_fscache_invalidate_page(page);
}
static inline int v9fs_readpage_from_fscache(struct inode *inode,
struct page *page)
{
return __v9fs_readpage_from_fscache(inode, page);
}
static inline int v9fs_readpages_from_fscache(struct inode *inode,
struct address_space *mapping,
struct list_head *pages,
unsigned *nr_pages)
{
return __v9fs_readpages_from_fscache(inode, mapping, pages,
nr_pages);
}
static inline void v9fs_readpage_to_fscache(struct inode *inode,
struct page *page)
{
if (PageFsCache(page))
__v9fs_readpage_to_fscache(inode, page);
}
static inline void v9fs_uncache_page(struct inode *inode, struct page *page)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
fscache_uncache_page(v9inode->fscache, page);
BUG_ON(PageFsCache(page));
}
static inline void v9fs_fscache_wait_on_page_write(struct inode *inode,
struct page *page)
{
return __v9fs_fscache_wait_on_page_write(inode, page);
}
#else /* CONFIG_9P_FSCACHE */
static inline void v9fs_cache_inode_get_cookie(struct inode *inode)
{
}
static inline void v9fs_cache_inode_put_cookie(struct inode *inode)
{
}
static inline void v9fs_cache_inode_set_cookie(struct inode *inode, struct file *file)
{
}
static inline int v9fs_fscache_release_page(struct page *page,
gfp_t gfp) {
return 1;
}
static inline void v9fs_fscache_invalidate_page(struct page *page) {}
static inline int v9fs_readpage_from_fscache(struct inode *inode,
struct page *page)
{
return -ENOBUFS;
}
static inline int v9fs_readpages_from_fscache(struct inode *inode,
struct address_space *mapping,
struct list_head *pages,
unsigned *nr_pages)
{
return -ENOBUFS;
}
static inline void v9fs_readpage_to_fscache(struct inode *inode,
struct page *page)
{}
static inline void v9fs_uncache_page(struct inode *inode, struct page *page)
{}
static inline void v9fs_fscache_wait_on_page_write(struct inode *inode,
struct page *page)
{
return;
}
#endif /* CONFIG_9P_FSCACHE */
#endif /* _9P_CACHE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -1,247 +0,0 @@
/*
* linux/fs/9p/error.c
*
* Error string handling
*
* Plan 9 uses error strings, Unix uses error numbers. These functions
* try to help manage that and provide for dynamically adding error
* mappings.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/list.h>
#include <linux/jhash.h>
#include <linux/errno.h>
#include <net/9p/9p.h>
/**
* struct errormap - map string errors from Plan 9 to Linux numeric ids
* @name: string sent over 9P
* @val: numeric id most closely representing @name
* @namelen: length of string
* @list: hash-table list for string lookup
*/
struct errormap {
char *name;
int val;
int namelen;
struct hlist_node list;
};
#define ERRHASHSZ 32
static struct hlist_head hash_errmap[ERRHASHSZ];
/* FixMe - reduce to a reasonable size */
static struct errormap errmap[] = {
{"Operation not permitted", EPERM},
{"wstat prohibited", EPERM},
{"No such file or directory", ENOENT},
{"directory entry not found", ENOENT},
{"file not found", ENOENT},
{"Interrupted system call", EINTR},
{"Input/output error", EIO},
{"No such device or address", ENXIO},
{"Argument list too long", E2BIG},
{"Bad file descriptor", EBADF},
{"Resource temporarily unavailable", EAGAIN},
{"Cannot allocate memory", ENOMEM},
{"Permission denied", EACCES},
{"Bad address", EFAULT},
{"Block device required", ENOTBLK},
{"Device or resource busy", EBUSY},
{"File exists", EEXIST},
{"Invalid cross-device link", EXDEV},
{"No such device", ENODEV},
{"Not a directory", ENOTDIR},
{"Is a directory", EISDIR},
{"Invalid argument", EINVAL},
{"Too many open files in system", ENFILE},
{"Too many open files", EMFILE},
{"Text file busy", ETXTBSY},
{"File too large", EFBIG},
{"No space left on device", ENOSPC},
{"Illegal seek", ESPIPE},
{"Read-only file system", EROFS},
{"Too many links", EMLINK},
{"Broken pipe", EPIPE},
{"Numerical argument out of domain", EDOM},
{"Numerical result out of range", ERANGE},
{"Resource deadlock avoided", EDEADLK},
{"File name too long", ENAMETOOLONG},
{"No locks available", ENOLCK},
{"Function not implemented", ENOSYS},
{"Directory not empty", ENOTEMPTY},
{"Too many levels of symbolic links", ELOOP},
{"No message of desired type", ENOMSG},
{"Identifier removed", EIDRM},
{"No data available", ENODATA},
{"Machine is not on the network", ENONET},
{"Package not installed", ENOPKG},
{"Object is remote", EREMOTE},
{"Link has been severed", ENOLINK},
{"Communication error on send", ECOMM},
{"Protocol error", EPROTO},
{"Bad message", EBADMSG},
{"File descriptor in bad state", EBADFD},
{"Streams pipe error", ESTRPIPE},
{"Too many users", EUSERS},
{"Socket operation on non-socket", ENOTSOCK},
{"Message too long", EMSGSIZE},
{"Protocol not available", ENOPROTOOPT},
{"Protocol not supported", EPROTONOSUPPORT},
{"Socket type not supported", ESOCKTNOSUPPORT},
{"Operation not supported", EOPNOTSUPP},
{"Protocol family not supported", EPFNOSUPPORT},
{"Network is down", ENETDOWN},
{"Network is unreachable", ENETUNREACH},
{"Network dropped connection on reset", ENETRESET},
{"Software caused connection abort", ECONNABORTED},
{"Connection reset by peer", ECONNRESET},
{"No buffer space available", ENOBUFS},
{"Transport endpoint is already connected", EISCONN},
{"Transport endpoint is not connected", ENOTCONN},
{"Cannot send after transport endpoint shutdown", ESHUTDOWN},
{"Connection timed out", ETIMEDOUT},
{"Connection refused", ECONNREFUSED},
{"Host is down", EHOSTDOWN},
{"No route to host", EHOSTUNREACH},
{"Operation already in progress", EALREADY},
{"Operation now in progress", EINPROGRESS},
{"Is a named type file", EISNAM},
{"Remote I/O error", EREMOTEIO},
{"Disk quota exceeded", EDQUOT},
/* errors from fossil, vacfs, and u9fs */
{"fid unknown or out of range", EBADF},
{"permission denied", EACCES},
{"file does not exist", ENOENT},
{"authentication failed", ECONNREFUSED},
{"bad offset in directory read", ESPIPE},
{"bad use of fid", EBADF},
{"wstat can't convert between files and directories", EPERM},
{"directory is not empty", ENOTEMPTY},
{"file exists", EEXIST},
{"file already exists", EEXIST},
{"file or directory already exists", EEXIST},
{"fid already in use", EBADF},
{"file in use", ETXTBSY},
{"i/o error", EIO},
{"file already open for I/O", ETXTBSY},
{"illegal mode", EINVAL},
{"illegal name", ENAMETOOLONG},
{"not a directory", ENOTDIR},
{"not a member of proposed group", EPERM},
{"not owner", EACCES},
{"only owner can change group in wstat", EACCES},
{"read only file system", EROFS},
{"no access to special file", EPERM},
{"i/o count too large", EIO},
{"unknown group", EINVAL},
{"unknown user", EINVAL},
{"bogus wstat buffer", EPROTO},
{"exclusive use file already open", EAGAIN},
{"corrupted directory entry", EIO},
{"corrupted file entry", EIO},
{"corrupted block label", EIO},
{"corrupted meta data", EIO},
{"illegal offset", EINVAL},
{"illegal path element", ENOENT},
{"root of file system is corrupted", EIO},
{"corrupted super block", EIO},
{"protocol botch", EPROTO},
{"file system is full", ENOSPC},
{"file is in use", EAGAIN},
{"directory entry is not allocated", ENOENT},
{"file is read only", EROFS},
{"file has been removed", EIDRM},
{"only support truncation to zero length", EPERM},
{"cannot remove root", EPERM},
{"file too big", EFBIG},
{"venti i/o error", EIO},
/* these are not errors */
{"u9fs rhostsauth: no authentication required", 0},
{"u9fs authnone: no authentication required", 0},
{NULL, -1}
};
/**
* p9_error_init - preload mappings into hash list
*
*/
int p9_error_init(void)
{
struct errormap *c;
int bucket;
/* initialize hash table */
for (bucket = 0; bucket < ERRHASHSZ; bucket++)
INIT_HLIST_HEAD(&hash_errmap[bucket]);
/* load initial error map into hash table */
for (c = errmap; c->name != NULL; c++) {
c->namelen = strlen(c->name);
bucket = jhash(c->name, c->namelen, 0) % ERRHASHSZ;
INIT_HLIST_NODE(&c->list);
hlist_add_head(&c->list, &hash_errmap[bucket]);
}
return 1;
}
EXPORT_SYMBOL(p9_error_init);
/**
* errstr2errno - convert error string to error number
* @errstr: error string
* @len: length of error string
*
*/
int p9_errstr2errno(char *errstr, int len)
{
int errno;
struct errormap *c;
int bucket;
errno = 0;
c = NULL;
bucket = jhash(errstr, len, 0) % ERRHASHSZ;
hlist_for_each_entry(c, &hash_errmap[bucket], list) {
if (c->namelen == len && !memcmp(c->name, errstr, len)) {
errno = c->val;
break;
}
}
if (errno == 0) {
/* TODO: if error isn't found, add it dynamically */
errstr[len] = 0;
pr_err("%s: server reported unknown error %s\n",
__func__, errstr);
errno = ESERVERFAULT;
}
return -errno;
}
EXPORT_SYMBOL(p9_errstr2errno);

View File

@@ -1,306 +0,0 @@
/*
* V9FS FID Management
*
* Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
* Copyright (C) 2005, 2006 by Eric Van Hensbergen <ericvh@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/idr.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
/**
* v9fs_fid_add - add a fid to a dentry
* @dentry: dentry that the fid is being added to
* @fid: fid to add
*
*/
static inline void __add_fid(struct dentry *dentry, struct p9_fid *fid)
{
hlist_add_head(&fid->dlist, (struct hlist_head *)&dentry->d_fsdata);
}
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid)
{
spin_lock(&dentry->d_lock);
__add_fid(dentry, fid);
spin_unlock(&dentry->d_lock);
}
/**
* v9fs_fid_find - retrieve a fid that belongs to the specified uid
* @dentry: dentry to look for fid in
* @uid: return fid that belongs to the specified user
* @any: if non-zero, return any fid associated with the dentry
*
*/
static struct p9_fid *v9fs_fid_find(struct dentry *dentry, kuid_t uid, int any)
{
struct p9_fid *fid, *ret;
p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p) uid %d any %d\n",
dentry, dentry, from_kuid(&init_user_ns, uid),
any);
ret = NULL;
/* we'll recheck under lock if there's anything to look in */
if (dentry->d_fsdata) {
struct hlist_head *h = (struct hlist_head *)&dentry->d_fsdata;
spin_lock(&dentry->d_lock);
hlist_for_each_entry(fid, h, dlist) {
if (any || uid_eq(fid->uid, uid)) {
ret = fid;
break;
}
}
spin_unlock(&dentry->d_lock);
}
return ret;
}
/*
* We need to hold v9ses->rename_sem as long as we hold references
* to returned path array. Array element contain pointers to
* dentry names.
*/
static int build_path_from_dentry(struct v9fs_session_info *v9ses,
struct dentry *dentry, char ***names)
{
int n = 0, i;
char **wnames;
struct dentry *ds;
for (ds = dentry; !IS_ROOT(ds); ds = ds->d_parent)
n++;
wnames = kmalloc(sizeof(char *) * n, GFP_KERNEL);
if (!wnames)
goto err_out;
for (ds = dentry, i = (n-1); i >= 0; i--, ds = ds->d_parent)
wnames[i] = (char *)ds->d_name.name;
*names = wnames;
return n;
err_out:
return -ENOMEM;
}
static struct p9_fid *v9fs_fid_lookup_with_uid(struct dentry *dentry,
kuid_t uid, int any)
{
struct dentry *ds;
char **wnames, *uname;
int i, n, l, clone, access;
struct v9fs_session_info *v9ses;
struct p9_fid *fid, *old_fid = NULL;
v9ses = v9fs_dentry2v9ses(dentry);
access = v9ses->flags & V9FS_ACCESS_MASK;
fid = v9fs_fid_find(dentry, uid, any);
if (fid)
return fid;
/*
* we don't have a matching fid. To do a TWALK we need
* parent fid. We need to prevent rename when we want to
* look at the parent.
*/
down_read(&v9ses->rename_sem);
ds = dentry->d_parent;
fid = v9fs_fid_find(ds, uid, any);
if (fid) {
/* Found the parent fid do a lookup with that */
fid = p9_client_walk(fid, 1, (char **)&dentry->d_name.name, 1);
goto fid_out;
}
up_read(&v9ses->rename_sem);
/* start from the root and try to do a lookup */
fid = v9fs_fid_find(dentry->d_sb->s_root, uid, any);
if (!fid) {
/* the user is not attached to the fs yet */
if (access == V9FS_ACCESS_SINGLE)
return ERR_PTR(-EPERM);
if (v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses))
uname = NULL;
else
uname = v9ses->uname;
fid = p9_client_attach(v9ses->clnt, NULL, uname, uid,
v9ses->aname);
if (IS_ERR(fid))
return fid;
v9fs_fid_add(dentry->d_sb->s_root, fid);
}
/* If we are root ourself just return that */
if (dentry->d_sb->s_root == dentry)
return fid;
/*
* Do a multipath walk with attached root.
* When walking parent we need to make sure we
* don't have a parallel rename happening
*/
down_read(&v9ses->rename_sem);
n = build_path_from_dentry(v9ses, dentry, &wnames);
if (n < 0) {
fid = ERR_PTR(n);
goto err_out;
}
clone = 1;
i = 0;
while (i < n) {
l = min(n - i, P9_MAXWELEM);
/*
* We need to hold rename lock when doing a multipath
* walk to ensure none of the patch component change
*/
fid = p9_client_walk(fid, l, &wnames[i], clone);
if (IS_ERR(fid)) {
if (old_fid) {
/*
* If we fail, clunk fid which are mapping
* to path component and not the last component
* of the path.
*/
p9_client_clunk(old_fid);
}
kfree(wnames);
goto err_out;
}
old_fid = fid;
i += l;
clone = 0;
}
kfree(wnames);
fid_out:
if (!IS_ERR(fid)) {
spin_lock(&dentry->d_lock);
if (d_unhashed(dentry)) {
spin_unlock(&dentry->d_lock);
p9_client_clunk(fid);
fid = ERR_PTR(-ENOENT);
} else {
__add_fid(dentry, fid);
spin_unlock(&dentry->d_lock);
}
}
err_out:
up_read(&v9ses->rename_sem);
return fid;
}
/**
* v9fs_fid_lookup - lookup for a fid, try to walk if not found
* @dentry: dentry to look for fid in
*
* Look for a fid in the specified dentry for the current user.
* If no fid is found, try to create one walking from a fid from the parent
* dentry (if it has one), or the root dentry. If the user haven't accessed
* the fs yet, attach now and walk from the root.
*/
struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
{
kuid_t uid;
int any, access;
struct v9fs_session_info *v9ses;
v9ses = v9fs_dentry2v9ses(dentry);
access = v9ses->flags & V9FS_ACCESS_MASK;
switch (access) {
case V9FS_ACCESS_SINGLE:
case V9FS_ACCESS_USER:
case V9FS_ACCESS_CLIENT:
uid = current_fsuid();
any = 0;
break;
case V9FS_ACCESS_ANY:
uid = v9ses->uid;
any = 1;
break;
default:
uid = INVALID_UID;
any = 0;
break;
}
return v9fs_fid_lookup_with_uid(dentry, uid, any);
}
struct p9_fid *v9fs_fid_clone(struct dentry *dentry)
{
struct p9_fid *fid, *ret;
fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid))
return fid;
ret = p9_client_walk(fid, 0, NULL, 1);
return ret;
}
static struct p9_fid *v9fs_fid_clone_with_uid(struct dentry *dentry, kuid_t uid)
{
struct p9_fid *fid, *ret;
fid = v9fs_fid_lookup_with_uid(dentry, uid, 0);
if (IS_ERR(fid))
return fid;
ret = p9_client_walk(fid, 0, NULL, 1);
return ret;
}
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry)
{
int err;
struct p9_fid *fid;
fid = v9fs_fid_clone_with_uid(dentry, GLOBAL_ROOT_UID);
if (IS_ERR(fid))
goto error_out;
/*
* writeback fid will only be used to write back the
* dirty pages. We always request for the open fid in read-write
* mode so that a partial page write which result in page
* read can work.
*/
err = p9_client_open(fid, O_RDWR);
if (err < 0) {
p9_client_clunk(fid);
fid = ERR_PTR(err);
goto error_out;
}
error_out:
return fid;
}

View File

@@ -1,30 +0,0 @@
/*
* V9FS FID Management
*
* Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#ifndef FS_9P_FID_H
#define FS_9P_FID_H
#include <linux/list.h>
struct p9_fid *v9fs_fid_lookup(struct dentry *dentry);
struct p9_fid *v9fs_fid_clone(struct dentry *dentry);
void v9fs_fid_add(struct dentry *dentry, struct p9_fid *fid);
struct p9_fid *v9fs_writeback_fid(struct dentry *dentry);
#endif

View File

@@ -1,201 +0,0 @@
/*
* net/9p/9p.c
*
* 9P entry point
*
* Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/moduleparam.h>
#include <net/9p/9p.h>
#include <linux/fs.h>
#include <linux/parser.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#ifdef CONFIG_NET_9P_DEBUG
unsigned int p9_debug_level = 0; /* feature-rific global debug level */
EXPORT_SYMBOL(p9_debug_level);
module_param_named(debug, p9_debug_level, uint, 0);
MODULE_PARM_DESC(debug, "9P debugging level");
void _p9_debug(enum p9_debug_flags level, const char *func,
const char *fmt, ...)
{
struct va_format vaf;
va_list args;
if ((p9_debug_level & level) != level)
return;
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
if (level == P9_DEBUG_9P)
pr_notice("(%8.8d) %pV", task_pid_nr(current), &vaf);
else
pr_notice("-- %s (%d): %pV", func, task_pid_nr(current), &vaf);
va_end(args);
}
EXPORT_SYMBOL(_p9_debug);
#endif
/*
* Dynamic Transport Registration Routines
*
*/
static DEFINE_SPINLOCK(v9fs_trans_lock);
static LIST_HEAD(v9fs_trans_list);
/**
* v9fs_register_trans - register a new transport with 9p
* @m: structure describing the transport module and entry points
*
*/
void v9fs_register_trans(struct p9_trans_module *m)
{
spin_lock(&v9fs_trans_lock);
list_add_tail(&m->list, &v9fs_trans_list);
spin_unlock(&v9fs_trans_lock);
}
EXPORT_SYMBOL(v9fs_register_trans);
/**
* v9fs_unregister_trans - unregister a 9p transport
* @m: the transport to remove
*
*/
void v9fs_unregister_trans(struct p9_trans_module *m)
{
spin_lock(&v9fs_trans_lock);
list_del_init(&m->list);
spin_unlock(&v9fs_trans_lock);
}
EXPORT_SYMBOL(v9fs_unregister_trans);
/**
* v9fs_get_trans_by_name - get transport with the matching name
* @name: string identifying transport
*
*/
struct p9_trans_module *v9fs_get_trans_by_name(char *s)
{
struct p9_trans_module *t, *found = NULL;
spin_lock(&v9fs_trans_lock);
list_for_each_entry(t, &v9fs_trans_list, list)
if (strcmp(t->name, s) == 0 &&
try_module_get(t->owner)) {
found = t;
break;
}
spin_unlock(&v9fs_trans_lock);
return found;
}
EXPORT_SYMBOL(v9fs_get_trans_by_name);
/**
* v9fs_get_default_trans - get the default transport
*
*/
struct p9_trans_module *v9fs_get_default_trans(void)
{
struct p9_trans_module *t, *found = NULL;
spin_lock(&v9fs_trans_lock);
list_for_each_entry(t, &v9fs_trans_list, list)
if (t->def && try_module_get(t->owner)) {
found = t;
break;
}
if (!found)
list_for_each_entry(t, &v9fs_trans_list, list)
if (try_module_get(t->owner)) {
found = t;
break;
}
spin_unlock(&v9fs_trans_lock);
return found;
}
EXPORT_SYMBOL(v9fs_get_default_trans);
/**
* v9fs_put_trans - put trans
* @m: transport to put
*
*/
void v9fs_put_trans(struct p9_trans_module *m)
{
if (m)
module_put(m->owner);
}
/**
* init_p9 - Initialize module
*
*/
static int __init init_p9(void)
{
int ret = 0;
p9_error_init();
pr_info("Installing 9P2000 support\n");
p9_trans_fd_init();
return ret;
}
/**
* exit_p9 - shutdown module
*
*/
static void __exit exit_p9(void)
{
pr_info("Unloading 9P2000 support\n");
p9_trans_fd_exit();
}
module_init(init_p9)
module_exit(exit_p9)
MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>");
MODULE_LICENSE("GPL");

View File

@@ -1,634 +0,0 @@
/*
* net/9p/protocol.c
*
* 9P Protocol Support Code
*
* Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com>
*
* Base on code from Anthony Liguori <aliguori@us.ibm.com>
* Copyright (C) 2008 by IBM, Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/uio.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "protocol.h"
#include <trace/events/9p.h>
static int
p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
void p9stat_free(struct p9_wstat *stbuf)
{
kfree(stbuf->name);
stbuf->name = NULL;
kfree(stbuf->uid);
stbuf->uid = NULL;
kfree(stbuf->gid);
stbuf->gid = NULL;
kfree(stbuf->muid);
stbuf->muid = NULL;
kfree(stbuf->extension);
stbuf->extension = NULL;
}
EXPORT_SYMBOL(p9stat_free);
size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
{
size_t len = min(pdu->size - pdu->offset, size);
memcpy(data, &pdu->sdata[pdu->offset], len);
pdu->offset += len;
return size - len;
}
static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
{
size_t len = min(pdu->capacity - pdu->size, size);
memcpy(&pdu->sdata[pdu->size], data, len);
pdu->size += len;
return size - len;
}
static size_t
pdu_write_u(struct p9_fcall *pdu, struct iov_iter *from, size_t size)
{
size_t len = min(pdu->capacity - pdu->size, size);
struct iov_iter i = *from;
if (copy_from_iter(&pdu->sdata[pdu->size], len, &i) != len)
len = 0;
pdu->size += len;
return size - len;
}
/*
b - int8_t
w - int16_t
d - int32_t
q - int64_t
s - string
u - numeric uid
g - numeric gid
S - stat
Q - qid
D - data blob (int32_t size followed by void *, results are not freed)
T - array of strings (int16_t count, followed by strings)
R - array of qids (int16_t count, followed by qids)
A - stat for 9p2000.L (p9_stat_dotl)
? - if optional = 1, continue parsing
*/
static int
p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
va_list ap)
{
const char *ptr;
int errcode = 0;
for (ptr = fmt; *ptr; ptr++) {
switch (*ptr) {
case 'b':{
int8_t *val = va_arg(ap, int8_t *);
if (pdu_read(pdu, val, sizeof(*val))) {
errcode = -EFAULT;
break;
}
}
break;
case 'w':{
int16_t *val = va_arg(ap, int16_t *);
__le16 le_val;
if (pdu_read(pdu, &le_val, sizeof(le_val))) {
errcode = -EFAULT;
break;
}
*val = le16_to_cpu(le_val);
}
break;
case 'd':{
int32_t *val = va_arg(ap, int32_t *);
__le32 le_val;
if (pdu_read(pdu, &le_val, sizeof(le_val))) {
errcode = -EFAULT;
break;
}
*val = le32_to_cpu(le_val);
}
break;
case 'q':{
int64_t *val = va_arg(ap, int64_t *);
__le64 le_val;
if (pdu_read(pdu, &le_val, sizeof(le_val))) {
errcode = -EFAULT;
break;
}
*val = le64_to_cpu(le_val);
}
break;
case 's':{
char **sptr = va_arg(ap, char **);
uint16_t len;
errcode = p9pdu_readf(pdu, proto_version,
"w", &len);
if (errcode)
break;
*sptr = kmalloc(len + 1, GFP_NOFS);
if (*sptr == NULL) {
errcode = -EFAULT;
break;
}
if (pdu_read(pdu, *sptr, len)) {
errcode = -EFAULT;
kfree(*sptr);
*sptr = NULL;
} else
(*sptr)[len] = 0;
}
break;
case 'u': {
kuid_t *uid = va_arg(ap, kuid_t *);
__le32 le_val;
if (pdu_read(pdu, &le_val, sizeof(le_val))) {
errcode = -EFAULT;
break;
}
*uid = make_kuid(&init_user_ns,
le32_to_cpu(le_val));
} break;
case 'g': {
kgid_t *gid = va_arg(ap, kgid_t *);
__le32 le_val;
if (pdu_read(pdu, &le_val, sizeof(le_val))) {
errcode = -EFAULT;
break;
}
*gid = make_kgid(&init_user_ns,
le32_to_cpu(le_val));
} break;
case 'Q':{
struct p9_qid *qid =
va_arg(ap, struct p9_qid *);
errcode = p9pdu_readf(pdu, proto_version, "bdq",
&qid->type, &qid->version,
&qid->path);
}
break;
case 'S':{
struct p9_wstat *stbuf =
va_arg(ap, struct p9_wstat *);
memset(stbuf, 0, sizeof(struct p9_wstat));
stbuf->n_uid = stbuf->n_muid = INVALID_UID;
stbuf->n_gid = INVALID_GID;
errcode =
p9pdu_readf(pdu, proto_version,
"wwdQdddqssss?sugu",
&stbuf->size, &stbuf->type,
&stbuf->dev, &stbuf->qid,
&stbuf->mode, &stbuf->atime,
&stbuf->mtime, &stbuf->length,
&stbuf->name, &stbuf->uid,
&stbuf->gid, &stbuf->muid,
&stbuf->extension,
&stbuf->n_uid, &stbuf->n_gid,
&stbuf->n_muid);
if (errcode)
p9stat_free(stbuf);
}
break;
case 'D':{
uint32_t *count = va_arg(ap, uint32_t *);
void **data = va_arg(ap, void **);
errcode =
p9pdu_readf(pdu, proto_version, "d", count);
if (!errcode) {
*count =
min_t(uint32_t, *count,
pdu->size - pdu->offset);
*data = &pdu->sdata[pdu->offset];
}
}
break;
case 'T':{
uint16_t *nwname = va_arg(ap, uint16_t *);
char ***wnames = va_arg(ap, char ***);
errcode = p9pdu_readf(pdu, proto_version,
"w", nwname);
if (!errcode) {
*wnames =
kmalloc(sizeof(char *) * *nwname,
GFP_NOFS);
if (!*wnames)
errcode = -ENOMEM;
}
if (!errcode) {
int i;
for (i = 0; i < *nwname; i++) {
errcode =
p9pdu_readf(pdu,
proto_version,
"s",
&(*wnames)[i]);
if (errcode)
break;
}
}
if (errcode) {
if (*wnames) {
int i;
for (i = 0; i < *nwname; i++)
kfree((*wnames)[i]);
}
kfree(*wnames);
*wnames = NULL;
}
}
break;
case 'R':{
uint16_t *nwqid = va_arg(ap, uint16_t *);
struct p9_qid **wqids =
va_arg(ap, struct p9_qid **);
*wqids = NULL;
errcode =
p9pdu_readf(pdu, proto_version, "w", nwqid);
if (!errcode) {
*wqids =
kmalloc(*nwqid *
sizeof(struct p9_qid),
GFP_NOFS);
if (*wqids == NULL)
errcode = -ENOMEM;
}
if (!errcode) {
int i;
for (i = 0; i < *nwqid; i++) {
errcode =
p9pdu_readf(pdu,
proto_version,
"Q",
&(*wqids)[i]);
if (errcode)
break;
}
}
if (errcode) {
kfree(*wqids);
*wqids = NULL;
}
}
break;
case 'A': {
struct p9_stat_dotl *stbuf =
va_arg(ap, struct p9_stat_dotl *);
memset(stbuf, 0, sizeof(struct p9_stat_dotl));
errcode =
p9pdu_readf(pdu, proto_version,
"qQdugqqqqqqqqqqqqqqq",
&stbuf->st_result_mask,
&stbuf->qid,
&stbuf->st_mode,
&stbuf->st_uid, &stbuf->st_gid,
&stbuf->st_nlink,
&stbuf->st_rdev, &stbuf->st_size,
&stbuf->st_blksize, &stbuf->st_blocks,
&stbuf->st_atime_sec,
&stbuf->st_atime_nsec,
&stbuf->st_mtime_sec,
&stbuf->st_mtime_nsec,
&stbuf->st_ctime_sec,
&stbuf->st_ctime_nsec,
&stbuf->st_btime_sec,
&stbuf->st_btime_nsec,
&stbuf->st_gen,
&stbuf->st_data_version);
}
break;
case '?':
if ((proto_version != p9_proto_2000u) &&
(proto_version != p9_proto_2000L))
return 0;
break;
default:
BUG();
break;
}
if (errcode)
break;
}
return errcode;
}
int
p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
va_list ap)
{
const char *ptr;
int errcode = 0;
for (ptr = fmt; *ptr; ptr++) {
switch (*ptr) {
case 'b':{
int8_t val = va_arg(ap, int);
if (pdu_write(pdu, &val, sizeof(val)))
errcode = -EFAULT;
}
break;
case 'w':{
__le16 val = cpu_to_le16(va_arg(ap, int));
if (pdu_write(pdu, &val, sizeof(val)))
errcode = -EFAULT;
}
break;
case 'd':{
__le32 val = cpu_to_le32(va_arg(ap, int32_t));
if (pdu_write(pdu, &val, sizeof(val)))
errcode = -EFAULT;
}
break;
case 'q':{
__le64 val = cpu_to_le64(va_arg(ap, int64_t));
if (pdu_write(pdu, &val, sizeof(val)))
errcode = -EFAULT;
}
break;
case 's':{
const char *sptr = va_arg(ap, const char *);
uint16_t len = 0;
if (sptr)
len = min_t(size_t, strlen(sptr),
USHRT_MAX);
errcode = p9pdu_writef(pdu, proto_version,
"w", len);
if (!errcode && pdu_write(pdu, sptr, len))
errcode = -EFAULT;
}
break;
case 'u': {
kuid_t uid = va_arg(ap, kuid_t);
__le32 val = cpu_to_le32(
from_kuid(&init_user_ns, uid));
if (pdu_write(pdu, &val, sizeof(val)))
errcode = -EFAULT;
} break;
case 'g': {
kgid_t gid = va_arg(ap, kgid_t);
__le32 val = cpu_to_le32(
from_kgid(&init_user_ns, gid));
if (pdu_write(pdu, &val, sizeof(val)))
errcode = -EFAULT;
} break;
case 'Q':{
const struct p9_qid *qid =
va_arg(ap, const struct p9_qid *);
errcode =
p9pdu_writef(pdu, proto_version, "bdq",
qid->type, qid->version,
qid->path);
} break;
case 'S':{
const struct p9_wstat *stbuf =
va_arg(ap, const struct p9_wstat *);
errcode =
p9pdu_writef(pdu, proto_version,
"wwdQdddqssss?sugu",
stbuf->size, stbuf->type,
stbuf->dev, &stbuf->qid,
stbuf->mode, stbuf->atime,
stbuf->mtime, stbuf->length,
stbuf->name, stbuf->uid,
stbuf->gid, stbuf->muid,
stbuf->extension, stbuf->n_uid,
stbuf->n_gid, stbuf->n_muid);
} break;
case 'V':{
uint32_t count = va_arg(ap, uint32_t);
struct iov_iter *from =
va_arg(ap, struct iov_iter *);
errcode = p9pdu_writef(pdu, proto_version, "d",
count);
if (!errcode && pdu_write_u(pdu, from, count))
errcode = -EFAULT;
}
break;
case 'T':{
uint16_t nwname = va_arg(ap, int);
const char **wnames = va_arg(ap, const char **);
errcode = p9pdu_writef(pdu, proto_version, "w",
nwname);
if (!errcode) {
int i;
for (i = 0; i < nwname; i++) {
errcode =
p9pdu_writef(pdu,
proto_version,
"s",
wnames[i]);
if (errcode)
break;
}
}
}
break;
case 'R':{
uint16_t nwqid = va_arg(ap, int);
struct p9_qid *wqids =
va_arg(ap, struct p9_qid *);
errcode = p9pdu_writef(pdu, proto_version, "w",
nwqid);
if (!errcode) {
int i;
for (i = 0; i < nwqid; i++) {
errcode =
p9pdu_writef(pdu,
proto_version,
"Q",
&wqids[i]);
if (errcode)
break;
}
}
}
break;
case 'I':{
struct p9_iattr_dotl *p9attr = va_arg(ap,
struct p9_iattr_dotl *);
errcode = p9pdu_writef(pdu, proto_version,
"ddugqqqqq",
p9attr->valid,
p9attr->mode,
p9attr->uid,
p9attr->gid,
p9attr->size,
p9attr->atime_sec,
p9attr->atime_nsec,
p9attr->mtime_sec,
p9attr->mtime_nsec);
}
break;
case '?':
if ((proto_version != p9_proto_2000u) &&
(proto_version != p9_proto_2000L))
return 0;
break;
default:
BUG();
break;
}
if (errcode)
break;
}
return errcode;
}
int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = p9pdu_vreadf(pdu, proto_version, fmt, ap);
va_end(ap);
return ret;
}
static int
p9pdu_writef(struct p9_fcall *pdu, int proto_version, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = p9pdu_vwritef(pdu, proto_version, fmt, ap);
va_end(ap);
return ret;
}
int p9stat_read(struct p9_client *clnt, char *buf, int len, struct p9_wstat *st)
{
struct p9_fcall fake_pdu;
int ret;
fake_pdu.size = len;
fake_pdu.capacity = len;
fake_pdu.sdata = buf;
fake_pdu.offset = 0;
ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "S", st);
if (ret) {
p9_debug(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
trace_9p_protocol_dump(clnt, &fake_pdu);
return ret;
}
return fake_pdu.offset;
}
EXPORT_SYMBOL(p9stat_read);
int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type)
{
pdu->id = type;
return p9pdu_writef(pdu, 0, "dbw", 0, type, tag);
}
int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu)
{
int size = pdu->size;
int err;
pdu->size = 0;
err = p9pdu_writef(pdu, 0, "d", size);
pdu->size = size;
trace_9p_protocol_dump(clnt, pdu);
p9_debug(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n",
pdu->size, pdu->id, pdu->tag);
return err;
}
void p9pdu_reset(struct p9_fcall *pdu)
{
pdu->offset = 0;
pdu->size = 0;
}
int p9dirent_read(struct p9_client *clnt, char *buf, int len,
struct p9_dirent *dirent)
{
struct p9_fcall fake_pdu;
int ret;
char *nameptr;
fake_pdu.size = len;
fake_pdu.capacity = len;
fake_pdu.sdata = buf;
fake_pdu.offset = 0;
ret = p9pdu_readf(&fake_pdu, clnt->proto_version, "Qqbs", &dirent->qid,
&dirent->d_off, &dirent->d_type, &nameptr);
if (ret) {
p9_debug(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
trace_9p_protocol_dump(clnt, &fake_pdu);
goto out;
}
strcpy(dirent->d_name, nameptr);
kfree(nameptr);
out:
return fake_pdu.offset;
}
EXPORT_SYMBOL(p9dirent_read);

View File

@@ -1,34 +0,0 @@
/*
* net/9p/protocol.h
*
* 9P Protocol Support Code
*
* Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com>
*
* Base on code from Anthony Liguori <aliguori@us.ibm.com>
* Copyright (C) 2008 by IBM, Corp.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
int p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
va_list ap);
int p9pdu_readf(struct p9_fcall *pdu, int proto_version, const char *fmt, ...);
int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type);
int p9pdu_finalize(struct p9_client *clnt, struct p9_fcall *pdu);
void p9pdu_reset(struct p9_fcall *pdu);
size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size);

View File

@@ -1,29 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <linux/mm.h>
#include <linux/module.h>
/**
* p9_release_req_pages - Release pages after the transaction.
*/
void p9_release_pages(struct page **pages, int nr_pages)
{
int i;
for (i = 0; i < nr_pages; i++)
if (pages[i])
put_page(pages[i]);
}
EXPORT_SYMBOL(p9_release_pages);

View File

@@ -1,15 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
void p9_release_pages(struct page **, int);

File diff suppressed because it is too large Load Diff

View File

@@ -1,784 +0,0 @@
/*
* linux/fs/9p/trans_rdma.c
*
* RDMA transport layer based on the trans_fd.c implementation.
*
* Copyright (C) 2008 by Tom Tucker <tom@opengridcomputing.com>
* Copyright (C) 2006 by Russ Cox <rsc@swtch.com>
* Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
* Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/in.h>
#include <linux/module.h>
#include <linux/net.h>
#include <linux/ipv6.h>
#include <linux/kthread.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/un.h>
#include <linux/uaccess.h>
#include <linux/inet.h>
#include <linux/idr.h>
#include <linux/file.h>
#include <linux/parser.h>
#include <linux/semaphore.h>
#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
#include <rdma/ib_verbs.h>
#include <rdma/rdma_cm.h>
#define P9_PORT 5640
#define P9_RDMA_SQ_DEPTH 32
#define P9_RDMA_RQ_DEPTH 32
#define P9_RDMA_SEND_SGE 4
#define P9_RDMA_RECV_SGE 4
#define P9_RDMA_IRD 0
#define P9_RDMA_ORD 0
#define P9_RDMA_TIMEOUT 30000 /* 30 seconds */
#define P9_RDMA_MAXSIZE (1024*1024) /* 1MB */
/**
* struct p9_trans_rdma - RDMA transport instance
*
* @state: tracks the transport state machine for connection setup and tear down
* @cm_id: The RDMA CM ID
* @pd: Protection Domain pointer
* @qp: Queue Pair pointer
* @cq: Completion Queue pointer
* @dm_mr: DMA Memory Region pointer
* @lkey: The local access only memory region key
* @timeout: Number of uSecs to wait for connection management events
* @sq_depth: The depth of the Send Queue
* @sq_sem: Semaphore for the SQ
* @rq_depth: The depth of the Receive Queue.
* @rq_sem: Semaphore for the RQ
* @excess_rc : Amount of posted Receive Contexts without a pending request.
* See rdma_request()
* @addr: The remote peer's address
* @req_lock: Protects the active request list
* @cm_done: Completion event for connection management tracking
*/
struct p9_trans_rdma {
enum {
P9_RDMA_INIT,
P9_RDMA_ADDR_RESOLVED,
P9_RDMA_ROUTE_RESOLVED,
P9_RDMA_CONNECTED,
P9_RDMA_FLUSHING,
P9_RDMA_CLOSING,
P9_RDMA_CLOSED,
} state;
struct rdma_cm_id *cm_id;
struct ib_pd *pd;
struct ib_qp *qp;
struct ib_cq *cq;
long timeout;
int sq_depth;
struct semaphore sq_sem;
int rq_depth;
struct semaphore rq_sem;
atomic_t excess_rc;
struct sockaddr_in addr;
spinlock_t req_lock;
struct completion cm_done;
};
/**
* p9_rdma_context - Keeps track of in-process WR
*
* @wc_op: The original WR op for when the CQE completes in error.
* @busa: Bus address to unmap when the WR completes
* @req: Keeps track of requests (send)
* @rc: Keepts track of replies (receive)
*/
struct p9_rdma_req;
struct p9_rdma_context {
enum ib_wc_opcode wc_op;
dma_addr_t busa;
union {
struct p9_req_t *req;
struct p9_fcall *rc;
};
};
/**
* p9_rdma_opts - Collection of mount options
* @port: port of connection
* @sq_depth: The requested depth of the SQ. This really doesn't need
* to be any deeper than the number of threads used in the client
* @rq_depth: The depth of the RQ. Should be greater than or equal to SQ depth
* @timeout: Time to wait in msecs for CM events
*/
struct p9_rdma_opts {
short port;
int sq_depth;
int rq_depth;
long timeout;
int privport;
};
/*
* Option Parsing (code inspired by NFS code)
*/
enum {
/* Options that take integer arguments */
Opt_port, Opt_rq_depth, Opt_sq_depth, Opt_timeout,
/* Options that take no argument */
Opt_privport,
Opt_err,
};
static match_table_t tokens = {
{Opt_port, "port=%u"},
{Opt_sq_depth, "sq=%u"},
{Opt_rq_depth, "rq=%u"},
{Opt_timeout, "timeout=%u"},
{Opt_privport, "privport"},
{Opt_err, NULL},
};
/**
* parse_opts - parse mount options into rdma options structure
* @params: options string passed from mount
* @opts: rdma transport-specific structure to parse options into
*
* Returns 0 upon success, -ERRNO upon failure
*/
static int parse_opts(char *params, struct p9_rdma_opts *opts)
{
char *p;
substring_t args[MAX_OPT_ARGS];
int option;
char *options, *tmp_options;
opts->port = P9_PORT;
opts->sq_depth = P9_RDMA_SQ_DEPTH;
opts->rq_depth = P9_RDMA_RQ_DEPTH;
opts->timeout = P9_RDMA_TIMEOUT;
opts->privport = 0;
if (!params)
return 0;
tmp_options = kstrdup(params, GFP_KERNEL);
if (!tmp_options) {
p9_debug(P9_DEBUG_ERROR,
"failed to allocate copy of option string\n");
return -ENOMEM;
}
options = tmp_options;
while ((p = strsep(&options, ",")) != NULL) {
int token;
int r;
if (!*p)
continue;
token = match_token(p, tokens, args);
if ((token != Opt_err) && (token != Opt_privport)) {
r = match_int(&args[0], &option);
if (r < 0) {
p9_debug(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
continue;
}
}
switch (token) {
case Opt_port:
opts->port = option;
break;
case Opt_sq_depth:
opts->sq_depth = option;
break;
case Opt_rq_depth:
opts->rq_depth = option;
break;
case Opt_timeout:
opts->timeout = option;
break;
case Opt_privport:
opts->privport = 1;
break;
default:
continue;
}
}
/* RQ must be at least as large as the SQ */
opts->rq_depth = max(opts->rq_depth, opts->sq_depth);
kfree(tmp_options);
return 0;
}
static int
p9_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event)
{
struct p9_client *c = id->context;
struct p9_trans_rdma *rdma = c->trans;
switch (event->event) {
case RDMA_CM_EVENT_ADDR_RESOLVED:
BUG_ON(rdma->state != P9_RDMA_INIT);
rdma->state = P9_RDMA_ADDR_RESOLVED;
break;
case RDMA_CM_EVENT_ROUTE_RESOLVED:
BUG_ON(rdma->state != P9_RDMA_ADDR_RESOLVED);
rdma->state = P9_RDMA_ROUTE_RESOLVED;
break;
case RDMA_CM_EVENT_ESTABLISHED:
BUG_ON(rdma->state != P9_RDMA_ROUTE_RESOLVED);
rdma->state = P9_RDMA_CONNECTED;
break;
case RDMA_CM_EVENT_DISCONNECTED:
if (rdma)
rdma->state = P9_RDMA_CLOSED;
if (c)
c->status = Disconnected;
break;
case RDMA_CM_EVENT_TIMEWAIT_EXIT:
break;
case RDMA_CM_EVENT_ADDR_CHANGE:
case RDMA_CM_EVENT_ROUTE_ERROR:
case RDMA_CM_EVENT_DEVICE_REMOVAL:
case RDMA_CM_EVENT_MULTICAST_JOIN:
case RDMA_CM_EVENT_MULTICAST_ERROR:
case RDMA_CM_EVENT_REJECTED:
case RDMA_CM_EVENT_CONNECT_REQUEST:
case RDMA_CM_EVENT_CONNECT_RESPONSE:
case RDMA_CM_EVENT_CONNECT_ERROR:
case RDMA_CM_EVENT_ADDR_ERROR:
case RDMA_CM_EVENT_UNREACHABLE:
c->status = Disconnected;
rdma_disconnect(rdma->cm_id);
break;
default:
BUG();
}
complete(&rdma->cm_done);
return 0;
}
static void
handle_recv(struct p9_client *client, struct p9_trans_rdma *rdma,
struct p9_rdma_context *c, enum ib_wc_status status, u32 byte_len)
{
struct p9_req_t *req;
int err = 0;
int16_t tag;
req = NULL;
ib_dma_unmap_single(rdma->cm_id->device, c->busa, client->msize,
DMA_FROM_DEVICE);
if (status != IB_WC_SUCCESS)
goto err_out;
err = p9_parse_header(c->rc, NULL, NULL, &tag, 1);
if (err)
goto err_out;
req = p9_tag_lookup(client, tag);
if (!req)
goto err_out;
/* Check that we have not yet received a reply for this request.
*/
if (unlikely(req->rc)) {
pr_err("Duplicate reply for request %d", tag);
goto err_out;
}
req->rc = c->rc;
p9_client_cb(client, req, REQ_STATUS_RCVD);
return;
err_out:
p9_debug(P9_DEBUG_ERROR, "req %p err %d status %d\n", req, err, status);
rdma->state = P9_RDMA_FLUSHING;
client->status = Disconnected;
}
static void
handle_send(struct p9_client *client, struct p9_trans_rdma *rdma,
struct p9_rdma_context *c, enum ib_wc_status status, u32 byte_len)
{
ib_dma_unmap_single(rdma->cm_id->device,
c->busa, c->req->tc->size,
DMA_TO_DEVICE);
}
static void qp_event_handler(struct ib_event *event, void *context)
{
p9_debug(P9_DEBUG_ERROR, "QP event %d context %p\n",
event->event, context);
}
static void cq_comp_handler(struct ib_cq *cq, void *cq_context)
{
struct p9_client *client = cq_context;
struct p9_trans_rdma *rdma = client->trans;
int ret;
struct ib_wc wc;
ib_req_notify_cq(rdma->cq, IB_CQ_NEXT_COMP);
while ((ret = ib_poll_cq(cq, 1, &wc)) > 0) {
struct p9_rdma_context *c = (void *) (unsigned long) wc.wr_id;
switch (c->wc_op) {
case IB_WC_RECV:
handle_recv(client, rdma, c, wc.status, wc.byte_len);
up(&rdma->rq_sem);
break;
case IB_WC_SEND:
handle_send(client, rdma, c, wc.status, wc.byte_len);
up(&rdma->sq_sem);
break;
default:
pr_err("unexpected completion type, c->wc_op=%d, wc.opcode=%d, status=%d\n",
c->wc_op, wc.opcode, wc.status);
break;
}
kfree(c);
}
}
static void cq_event_handler(struct ib_event *e, void *v)
{
p9_debug(P9_DEBUG_ERROR, "CQ event %d context %p\n", e->event, v);
}
static void rdma_destroy_trans(struct p9_trans_rdma *rdma)
{
if (!rdma)
return;
if (rdma->qp && !IS_ERR(rdma->qp))
ib_destroy_qp(rdma->qp);
if (rdma->pd && !IS_ERR(rdma->pd))
ib_dealloc_pd(rdma->pd);
if (rdma->cq && !IS_ERR(rdma->cq))
ib_destroy_cq(rdma->cq);
if (rdma->cm_id && !IS_ERR(rdma->cm_id))
rdma_destroy_id(rdma->cm_id);
kfree(rdma);
}
static int
post_recv(struct p9_client *client, struct p9_rdma_context *c)
{
struct p9_trans_rdma *rdma = client->trans;
struct ib_recv_wr wr, *bad_wr;
struct ib_sge sge;
c->busa = ib_dma_map_single(rdma->cm_id->device,
c->rc->sdata, client->msize,
DMA_FROM_DEVICE);
if (ib_dma_mapping_error(rdma->cm_id->device, c->busa))
goto error;
sge.addr = c->busa;
sge.length = client->msize;
sge.lkey = rdma->pd->local_dma_lkey;
wr.next = NULL;
c->wc_op = IB_WC_RECV;
wr.wr_id = (unsigned long) c;
wr.sg_list = &sge;
wr.num_sge = 1;
return ib_post_recv(rdma->qp, &wr, &bad_wr);
error:
p9_debug(P9_DEBUG_ERROR, "EIO\n");
return -EIO;
}
static int rdma_request(struct p9_client *client, struct p9_req_t *req)
{
struct p9_trans_rdma *rdma = client->trans;
struct ib_send_wr wr, *bad_wr;
struct ib_sge sge;
int err = 0;
unsigned long flags;
struct p9_rdma_context *c = NULL;
struct p9_rdma_context *rpl_context = NULL;
/* When an error occurs between posting the recv and the send,
* there will be a receive context posted without a pending request.
* Since there is no way to "un-post" it, we remember it and skip
* post_recv() for the next request.
* So here,
* see if we are this `next request' and need to absorb an excess rc.
* If yes, then drop and free our own, and do not recv_post().
**/
if (unlikely(atomic_read(&rdma->excess_rc) > 0)) {
if ((atomic_sub_return(1, &rdma->excess_rc) >= 0)) {
/* Got one ! */
kfree(req->rc);
req->rc = NULL;
goto dont_need_post_recv;
} else {
/* We raced and lost. */
atomic_inc(&rdma->excess_rc);
}
}
/* Allocate an fcall for the reply */
rpl_context = kmalloc(sizeof *rpl_context, GFP_NOFS);
if (!rpl_context) {
err = -ENOMEM;
goto recv_error;
}
rpl_context->rc = req->rc;
/*
* Post a receive buffer for this request. We need to ensure
* there is a reply buffer available for every outstanding
* request. A flushed request can result in no reply for an
* outstanding request, so we must keep a count to avoid
* overflowing the RQ.
*/
if (down_interruptible(&rdma->rq_sem)) {
err = -EINTR;
goto recv_error;
}
err = post_recv(client, rpl_context);
if (err) {
p9_debug(P9_DEBUG_FCALL, "POST RECV failed\n");
goto recv_error;
}
/* remove posted receive buffer from request structure */
req->rc = NULL;
dont_need_post_recv:
/* Post the request */
c = kmalloc(sizeof *c, GFP_NOFS);
if (!c) {
err = -ENOMEM;
goto send_error;
}
c->req = req;
c->busa = ib_dma_map_single(rdma->cm_id->device,
c->req->tc->sdata, c->req->tc->size,
DMA_TO_DEVICE);
if (ib_dma_mapping_error(rdma->cm_id->device, c->busa)) {
err = -EIO;
goto send_error;
}
sge.addr = c->busa;
sge.length = c->req->tc->size;
sge.lkey = rdma->pd->local_dma_lkey;
wr.next = NULL;
c->wc_op = IB_WC_SEND;
wr.wr_id = (unsigned long) c;
wr.opcode = IB_WR_SEND;
wr.send_flags = IB_SEND_SIGNALED;
wr.sg_list = &sge;
wr.num_sge = 1;
if (down_interruptible(&rdma->sq_sem)) {
err = -EINTR;
goto send_error;
}
/* Mark request as `sent' *before* we actually send it,
* because doing if after could erase the REQ_STATUS_RCVD
* status in case of a very fast reply.
*/
req->status = REQ_STATUS_SENT;
err = ib_post_send(rdma->qp, &wr, &bad_wr);
if (err)
goto send_error;
/* Success */
return 0;
/* Handle errors that happened during or while preparing the send: */
send_error:
req->status = REQ_STATUS_ERROR;
kfree(c);
p9_debug(P9_DEBUG_ERROR, "Error %d in rdma_request()\n", err);
/* Ach.
* We did recv_post(), but not send. We have one recv_post in excess.
*/
atomic_inc(&rdma->excess_rc);
return err;
/* Handle errors that happened during or while preparing post_recv(): */
recv_error:
kfree(rpl_context);
spin_lock_irqsave(&rdma->req_lock, flags);
if (rdma->state < P9_RDMA_CLOSING) {
rdma->state = P9_RDMA_CLOSING;
spin_unlock_irqrestore(&rdma->req_lock, flags);
rdma_disconnect(rdma->cm_id);
} else
spin_unlock_irqrestore(&rdma->req_lock, flags);
return err;
}
static void rdma_close(struct p9_client *client)
{
struct p9_trans_rdma *rdma;
if (!client)
return;
rdma = client->trans;
if (!rdma)
return;
client->status = Disconnected;
rdma_disconnect(rdma->cm_id);
rdma_destroy_trans(rdma);
}
/**
* alloc_rdma - Allocate and initialize the rdma transport structure
* @opts: Mount options structure
*/
static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts)
{
struct p9_trans_rdma *rdma;
rdma = kzalloc(sizeof(struct p9_trans_rdma), GFP_KERNEL);
if (!rdma)
return NULL;
rdma->sq_depth = opts->sq_depth;
rdma->rq_depth = opts->rq_depth;
rdma->timeout = opts->timeout;
spin_lock_init(&rdma->req_lock);
init_completion(&rdma->cm_done);
sema_init(&rdma->sq_sem, rdma->sq_depth);
sema_init(&rdma->rq_sem, rdma->rq_depth);
atomic_set(&rdma->excess_rc, 0);
return rdma;
}
static int rdma_cancel(struct p9_client *client, struct p9_req_t *req)
{
/* Nothing to do here.
* We will take care of it (if we have to) in rdma_cancelled()
*/
return 1;
}
/* A request has been fully flushed without a reply.
* That means we have posted one buffer in excess.
*/
static int rdma_cancelled(struct p9_client *client, struct p9_req_t *req)
{
struct p9_trans_rdma *rdma = client->trans;
atomic_inc(&rdma->excess_rc);
return 0;
}
static int p9_rdma_bind_privport(struct p9_trans_rdma *rdma)
{
struct sockaddr_in cl = {
.sin_family = AF_INET,
.sin_addr.s_addr = htonl(INADDR_ANY),
};
int port, err = -EINVAL;
for (port = P9_DEF_MAX_RESVPORT; port >= P9_DEF_MIN_RESVPORT; port--) {
cl.sin_port = htons((ushort)port);
err = rdma_bind_addr(rdma->cm_id, (struct sockaddr *)&cl);
if (err != -EADDRINUSE)
break;
}
return err;
}
/**
* trans_create_rdma - Transport method for creating atransport instance
* @client: client instance
* @addr: IP address string
* @args: Mount options string
*/
static int
rdma_create_trans(struct p9_client *client, const char *addr, char *args)
{
int err;
struct p9_rdma_opts opts;
struct p9_trans_rdma *rdma;
struct rdma_conn_param conn_param;
struct ib_qp_init_attr qp_attr;
struct ib_cq_init_attr cq_attr = {};
if (addr == NULL)
return -EINVAL;
/* Parse the transport specific mount options */
err = parse_opts(args, &opts);
if (err < 0)
return err;
/* Create and initialize the RDMA transport structure */
rdma = alloc_rdma(&opts);
if (!rdma)
return -ENOMEM;
/* Create the RDMA CM ID */
rdma->cm_id = rdma_create_id(&init_net, p9_cm_event_handler, client,
RDMA_PS_TCP, IB_QPT_RC);
if (IS_ERR(rdma->cm_id))
goto error;
/* Associate the client with the transport */
client->trans = rdma;
/* Bind to a privileged port if we need to */
if (opts.privport) {
err = p9_rdma_bind_privport(rdma);
if (err < 0) {
pr_err("%s (%d): problem binding to privport: %d\n",
__func__, task_pid_nr(current), -err);
goto error;
}
}
/* Resolve the server's address */
rdma->addr.sin_family = AF_INET;
rdma->addr.sin_addr.s_addr = in_aton(addr);
rdma->addr.sin_port = htons(opts.port);
err = rdma_resolve_addr(rdma->cm_id, NULL,
(struct sockaddr *)&rdma->addr,
rdma->timeout);
if (err)
goto error;
err = wait_for_completion_interruptible(&rdma->cm_done);
if (err || (rdma->state != P9_RDMA_ADDR_RESOLVED))
goto error;
/* Resolve the route to the server */
err = rdma_resolve_route(rdma->cm_id, rdma->timeout);
if (err)
goto error;
err = wait_for_completion_interruptible(&rdma->cm_done);
if (err || (rdma->state != P9_RDMA_ROUTE_RESOLVED))
goto error;
/* Create the Completion Queue */
cq_attr.cqe = opts.sq_depth + opts.rq_depth + 1;
rdma->cq = ib_create_cq(rdma->cm_id->device, cq_comp_handler,
cq_event_handler, client,
&cq_attr);
if (IS_ERR(rdma->cq))
goto error;
ib_req_notify_cq(rdma->cq, IB_CQ_NEXT_COMP);
/* Create the Protection Domain */
rdma->pd = ib_alloc_pd(rdma->cm_id->device);
if (IS_ERR(rdma->pd))
goto error;
/* Create the Queue Pair */
memset(&qp_attr, 0, sizeof qp_attr);
qp_attr.event_handler = qp_event_handler;
qp_attr.qp_context = client;
qp_attr.cap.max_send_wr = opts.sq_depth;
qp_attr.cap.max_recv_wr = opts.rq_depth;
qp_attr.cap.max_send_sge = P9_RDMA_SEND_SGE;
qp_attr.cap.max_recv_sge = P9_RDMA_RECV_SGE;
qp_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
qp_attr.qp_type = IB_QPT_RC;
qp_attr.send_cq = rdma->cq;
qp_attr.recv_cq = rdma->cq;
err = rdma_create_qp(rdma->cm_id, rdma->pd, &qp_attr);
if (err)
goto error;
rdma->qp = rdma->cm_id->qp;
/* Request a connection */
memset(&conn_param, 0, sizeof(conn_param));
conn_param.private_data = NULL;
conn_param.private_data_len = 0;
conn_param.responder_resources = P9_RDMA_IRD;
conn_param.initiator_depth = P9_RDMA_ORD;
err = rdma_connect(rdma->cm_id, &conn_param);
if (err)
goto error;
err = wait_for_completion_interruptible(&rdma->cm_done);
if (err || (rdma->state != P9_RDMA_CONNECTED))
goto error;
client->status = Connected;
return 0;
error:
rdma_destroy_trans(rdma);
return -ENOTCONN;
}
static struct p9_trans_module p9_rdma_trans = {
.name = "rdma",
.maxsize = P9_RDMA_MAXSIZE,
.def = 0,
.owner = THIS_MODULE,
.create = rdma_create_trans,
.close = rdma_close,
.request = rdma_request,
.cancel = rdma_cancel,
.cancelled = rdma_cancelled,
};
/**
* p9_trans_rdma_init - Register the 9P RDMA transport driver
*/
static int __init p9_trans_rdma_init(void)
{
v9fs_register_trans(&p9_rdma_trans);
return 0;
}
static void __exit p9_trans_rdma_exit(void)
{
v9fs_unregister_trans(&p9_rdma_trans);
}
module_init(p9_trans_rdma_init);
module_exit(p9_trans_rdma_exit);
MODULE_AUTHOR("Tom Tucker <tom@opengridcomputing.com>");
MODULE_DESCRIPTION("RDMA Transport for 9P");
MODULE_LICENSE("Dual BSD/GPL");

View File

@@ -1,788 +0,0 @@
/*
* The Virtio 9p transport driver
*
* This is a block based transport driver based on the lguest block driver
* code.
*
* Copyright (C) 2007, 2008 Eric Van Hensbergen, IBM Corporation
*
* Based on virtio console driver
* Copyright (C) 2006, 2007 Rusty Russell, IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/in.h>
#include <linux/module.h>
#include <linux/net.h>
#include <linux/ipv6.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/un.h>
#include <linux/uaccess.h>
#include <linux/inet.h>
#include <linux/idr.h>
#include <linux/file.h>
#include <linux/highmem.h>
#include <linux/slab.h>
#include <net/9p/9p.h>
#include <linux/parser.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
#include <linux/scatterlist.h>
#include <linux/swap.h>
#include <linux/virtio.h>
#include <linux/virtio_9p.h>
#include "trans_common.h"
#define VIRTQUEUE_NUM 128
/* a single mutex to manage channel initialization and attachment */
static DEFINE_MUTEX(virtio_9p_lock);
static DECLARE_WAIT_QUEUE_HEAD(vp_wq);
static atomic_t vp_pinned = ATOMIC_INIT(0);
/**
* struct virtio_chan - per-instance transport information
* @initialized: whether the channel is initialized
* @inuse: whether the channel is in use
* @lock: protects multiple elements within this structure
* @client: client instance
* @vdev: virtio dev associated with this channel
* @vq: virtio queue associated with this channel
* @sg: scatter gather list which is used to pack a request (protected?)
*
* We keep all per-channel information in a structure.
* This structure is allocated within the devices dev->mem space.
* A pointer to the structure will get put in the transport private.
*
*/
struct virtio_chan {
bool inuse;
spinlock_t lock;
struct p9_client *client;
struct virtio_device *vdev;
struct virtqueue *vq;
int ring_bufs_avail;
wait_queue_head_t *vc_wq;
/* This is global limit. Since we don't have a global structure,
* will be placing it in each channel.
*/
unsigned long p9_max_pages;
/* Scatterlist: can be too big for stack. */
struct scatterlist sg[VIRTQUEUE_NUM];
int tag_len;
/*
* tag name to identify a mount Non-null terminated
*/
char *tag;
struct list_head chan_list;
};
static struct list_head virtio_chan_list;
/* How many bytes left in this page. */
static unsigned int rest_of_page(void *data)
{
return PAGE_SIZE - ((unsigned long)data % PAGE_SIZE);
}
/**
* p9_virtio_close - reclaim resources of a channel
* @client: client instance
*
* This reclaims a channel by freeing its resources and
* reseting its inuse flag.
*
*/
static void p9_virtio_close(struct p9_client *client)
{
struct virtio_chan *chan = client->trans;
mutex_lock(&virtio_9p_lock);
if (chan)
chan->inuse = false;
mutex_unlock(&virtio_9p_lock);
}
/**
* req_done - callback which signals activity from the server
* @vq: virtio queue activity was received on
*
* This notifies us that the server has triggered some activity
* on the virtio channel - most likely a response to request we
* sent. Figure out which requests now have responses and wake up
* those threads.
*
* Bugs: could do with some additional sanity checking, but appears to work.
*
*/
static void req_done(struct virtqueue *vq)
{
struct virtio_chan *chan = vq->vdev->priv;
struct p9_fcall *rc;
unsigned int len;
struct p9_req_t *req;
unsigned long flags;
p9_debug(P9_DEBUG_TRANS, ": request done\n");
while (1) {
spin_lock_irqsave(&chan->lock, flags);
rc = virtqueue_get_buf(chan->vq, &len);
if (rc == NULL) {
spin_unlock_irqrestore(&chan->lock, flags);
break;
}
chan->ring_bufs_avail = 1;
spin_unlock_irqrestore(&chan->lock, flags);
/* Wakeup if anyone waiting for VirtIO ring space. */
wake_up(chan->vc_wq);
p9_debug(P9_DEBUG_TRANS, ": rc %p\n", rc);
p9_debug(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag);
req = p9_tag_lookup(chan->client, rc->tag);
p9_client_cb(chan->client, req, REQ_STATUS_RCVD);
}
}
/**
* pack_sg_list - pack a scatter gather list from a linear buffer
* @sg: scatter/gather list to pack into
* @start: which segment of the sg_list to start at
* @limit: maximum segment to pack data to
* @data: data to pack into scatter/gather list
* @count: amount of data to pack into the scatter/gather list
*
* sg_lists have multiple segments of various sizes. This will pack
* arbitrary data into an existing scatter gather list, segmenting the
* data as necessary within constraints.
*
*/
static int pack_sg_list(struct scatterlist *sg, int start,
int limit, char *data, int count)
{
int s;
int index = start;
while (count) {
s = rest_of_page(data);
if (s > count)
s = count;
BUG_ON(index >= limit);
/* Make sure we don't terminate early. */
sg_unmark_end(&sg[index]);
sg_set_buf(&sg[index++], data, s);
count -= s;
data += s;
}
if (index-start)
sg_mark_end(&sg[index - 1]);
return index-start;
}
/* We don't currently allow canceling of virtio requests */
static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
{
return 1;
}
/**
* pack_sg_list_p - Just like pack_sg_list. Instead of taking a buffer,
* this takes a list of pages.
* @sg: scatter/gather list to pack into
* @start: which segment of the sg_list to start at
* @pdata: a list of pages to add into sg.
* @nr_pages: number of pages to pack into the scatter/gather list
* @offs: amount of data in the beginning of first page _not_ to pack
* @count: amount of data to pack into the scatter/gather list
*/
static int
pack_sg_list_p(struct scatterlist *sg, int start, int limit,
struct page **pdata, int nr_pages, size_t offs, int count)
{
int i = 0, s;
int data_off = offs;
int index = start;
BUG_ON(nr_pages > (limit - start));
/*
* if the first page doesn't start at
* page boundary find the offset
*/
while (nr_pages) {
s = PAGE_SIZE - data_off;
if (s > count)
s = count;
BUG_ON(index >= limit);
/* Make sure we don't terminate early. */
sg_unmark_end(&sg[index]);
sg_set_page(&sg[index++], pdata[i++], s, data_off);
data_off = 0;
count -= s;
nr_pages--;
}
if (index-start)
sg_mark_end(&sg[index - 1]);
return index - start;
}
/**
* p9_virtio_request - issue a request
* @client: client instance issuing the request
* @req: request to be issued
*
*/
static int
p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
{
int err;
int in, out, out_sgs, in_sgs;
unsigned long flags;
struct virtio_chan *chan = client->trans;
struct scatterlist *sgs[2];
p9_debug(P9_DEBUG_TRANS, "9p debug: virtio request\n");
req->status = REQ_STATUS_SENT;
req_retry:
spin_lock_irqsave(&chan->lock, flags);
out_sgs = in_sgs = 0;
/* Handle out VirtIO ring buffers */
out = pack_sg_list(chan->sg, 0,
VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
if (out)
sgs[out_sgs++] = chan->sg;
in = pack_sg_list(chan->sg, out,
VIRTQUEUE_NUM, req->rc->sdata, req->rc->capacity);
if (in)
sgs[out_sgs + in_sgs++] = chan->sg + out;
err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req->tc,
GFP_ATOMIC);
if (err < 0) {
if (err == -ENOSPC) {
chan->ring_bufs_avail = 0;
spin_unlock_irqrestore(&chan->lock, flags);
err = wait_event_killable(*chan->vc_wq,
chan->ring_bufs_avail);
if (err == -ERESTARTSYS)
return err;
p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n");
goto req_retry;
} else {
spin_unlock_irqrestore(&chan->lock, flags);
p9_debug(P9_DEBUG_TRANS,
"virtio rpc add_sgs returned failure\n");
return -EIO;
}
}
virtqueue_kick(chan->vq);
spin_unlock_irqrestore(&chan->lock, flags);
p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
return 0;
}
static int p9_get_mapped_pages(struct virtio_chan *chan,
struct page ***pages,
struct iov_iter *data,
int count,
size_t *offs,
int *need_drop)
{
int nr_pages;
int err;
if (!iov_iter_count(data))
return 0;
if (!(data->type & ITER_KVEC)) {
int n;
/*
* We allow only p9_max_pages pinned. We wait for the
* Other zc request to finish here
*/
if (atomic_read(&vp_pinned) >= chan->p9_max_pages) {
err = wait_event_killable(vp_wq,
(atomic_read(&vp_pinned) < chan->p9_max_pages));
if (err == -ERESTARTSYS)
return err;
}
n = iov_iter_get_pages_alloc(data, pages, count, offs);
if (n < 0)
return n;
*need_drop = 1;
nr_pages = DIV_ROUND_UP(n + *offs, PAGE_SIZE);
atomic_add(nr_pages, &vp_pinned);
return n;
} else {
/* kernel buffer, no need to pin pages */
int index;
size_t len;
void *p;
/* we'd already checked that it's non-empty */
while (1) {
len = iov_iter_single_seg_count(data);
if (likely(len)) {
p = data->kvec->iov_base + data->iov_offset;
break;
}
iov_iter_advance(data, 0);
}
if (len > count)
len = count;
nr_pages = DIV_ROUND_UP((unsigned long)p + len, PAGE_SIZE) -
(unsigned long)p / PAGE_SIZE;
*pages = kmalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
if (!*pages)
return -ENOMEM;
*need_drop = 0;
p -= (*offs = (unsigned long)p % PAGE_SIZE);
for (index = 0; index < nr_pages; index++) {
if (is_vmalloc_addr(p))
(*pages)[index] = vmalloc_to_page(p);
else
(*pages)[index] = kmap_to_page(p);
p += PAGE_SIZE;
}
return len;
}
}
/**
* p9_virtio_zc_request - issue a zero copy request
* @client: client instance issuing the request
* @req: request to be issued
* @uidata: user bffer that should be ued for zero copy read
* @uodata: user buffer that shoud be user for zero copy write
* @inlen: read buffer size
* @olen: write buffer size
* @hdrlen: reader header size, This is the size of response protocol data
*
*/
static int
p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req,
struct iov_iter *uidata, struct iov_iter *uodata,
int inlen, int outlen, int in_hdr_len)
{
int in, out, err, out_sgs, in_sgs;
unsigned long flags;
int in_nr_pages = 0, out_nr_pages = 0;
struct page **in_pages = NULL, **out_pages = NULL;
struct virtio_chan *chan = client->trans;
struct scatterlist *sgs[4];
size_t offs;
int need_drop = 0;
p9_debug(P9_DEBUG_TRANS, "virtio request\n");
if (uodata) {
__le32 sz;
int n = p9_get_mapped_pages(chan, &out_pages, uodata,
outlen, &offs, &need_drop);
if (n < 0)
return n;
out_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
if (n != outlen) {
__le32 v = cpu_to_le32(n);
memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4);
outlen = n;
}
/* The size field of the message must include the length of the
* header and the length of the data. We didn't actually know
* the length of the data until this point so add it in now.
*/
sz = cpu_to_le32(req->tc->size + outlen);
memcpy(&req->tc->sdata[0], &sz, sizeof(sz));
} else if (uidata) {
int n = p9_get_mapped_pages(chan, &in_pages, uidata,
inlen, &offs, &need_drop);
if (n < 0)
return n;
in_nr_pages = DIV_ROUND_UP(n + offs, PAGE_SIZE);
if (n != inlen) {
__le32 v = cpu_to_le32(n);
memcpy(&req->tc->sdata[req->tc->size - 4], &v, 4);
inlen = n;
}
}
req->status = REQ_STATUS_SENT;
req_retry_pinned:
spin_lock_irqsave(&chan->lock, flags);
out_sgs = in_sgs = 0;
/* out data */
out = pack_sg_list(chan->sg, 0,
VIRTQUEUE_NUM, req->tc->sdata, req->tc->size);
if (out)
sgs[out_sgs++] = chan->sg;
if (out_pages) {
sgs[out_sgs++] = chan->sg + out;
out += pack_sg_list_p(chan->sg, out, VIRTQUEUE_NUM,
out_pages, out_nr_pages, offs, outlen);
}
/*
* Take care of in data
* For example TREAD have 11.
* 11 is the read/write header = PDU Header(7) + IO Size (4).
* Arrange in such a way that server places header in the
* alloced memory and payload onto the user buffer.
*/
in = pack_sg_list(chan->sg, out,
VIRTQUEUE_NUM, req->rc->sdata, in_hdr_len);
if (in)
sgs[out_sgs + in_sgs++] = chan->sg + out;
if (in_pages) {
sgs[out_sgs + in_sgs++] = chan->sg + out + in;
in += pack_sg_list_p(chan->sg, out + in, VIRTQUEUE_NUM,
in_pages, in_nr_pages, offs, inlen);
}
BUG_ON(out_sgs + in_sgs > ARRAY_SIZE(sgs));
err = virtqueue_add_sgs(chan->vq, sgs, out_sgs, in_sgs, req->tc,
GFP_ATOMIC);
if (err < 0) {
if (err == -ENOSPC) {
chan->ring_bufs_avail = 0;
spin_unlock_irqrestore(&chan->lock, flags);
err = wait_event_killable(*chan->vc_wq,
chan->ring_bufs_avail);
if (err == -ERESTARTSYS)
goto err_out;
p9_debug(P9_DEBUG_TRANS, "Retry virtio request\n");
goto req_retry_pinned;
} else {
spin_unlock_irqrestore(&chan->lock, flags);
p9_debug(P9_DEBUG_TRANS,
"virtio rpc add_sgs returned failure\n");
err = -EIO;
goto err_out;
}
}
virtqueue_kick(chan->vq);
spin_unlock_irqrestore(&chan->lock, flags);
p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n");
err = wait_event_killable(*req->wq, req->status >= REQ_STATUS_RCVD);
/*
* Non kernel buffers are pinned, unpin them
*/
err_out:
if (need_drop) {
if (in_pages) {
p9_release_pages(in_pages, in_nr_pages);
atomic_sub(in_nr_pages, &vp_pinned);
}
if (out_pages) {
p9_release_pages(out_pages, out_nr_pages);
atomic_sub(out_nr_pages, &vp_pinned);
}
/* wakeup anybody waiting for slots to pin pages */
wake_up(&vp_wq);
}
kfree(in_pages);
kfree(out_pages);
return err;
}
static ssize_t p9_mount_tag_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct virtio_chan *chan;
struct virtio_device *vdev;
vdev = dev_to_virtio(dev);
chan = vdev->priv;
memcpy(buf, chan->tag, chan->tag_len);
buf[chan->tag_len] = 0;
return chan->tag_len + 1;
}
static DEVICE_ATTR(mount_tag, 0444, p9_mount_tag_show, NULL);
/**
* p9_virtio_probe - probe for existence of 9P virtio channels
* @vdev: virtio device to probe
*
* This probes for existing virtio channels.
*
*/
static int p9_virtio_probe(struct virtio_device *vdev)
{
__u16 tag_len;
char *tag;
int err;
struct virtio_chan *chan;
if (!vdev->config->get) {
dev_err(&vdev->dev, "%s failure: config access disabled\n",
__func__);
return -EINVAL;
}
chan = kmalloc(sizeof(struct virtio_chan), GFP_KERNEL);
if (!chan) {
pr_err("Failed to allocate virtio 9P channel\n");
err = -ENOMEM;
goto fail;
}
chan->vdev = vdev;
/* We expect one virtqueue, for requests. */
chan->vq = virtio_find_single_vq(vdev, req_done, "requests");
if (IS_ERR(chan->vq)) {
err = PTR_ERR(chan->vq);
goto out_free_chan;
}
chan->vq->vdev->priv = chan;
spin_lock_init(&chan->lock);
sg_init_table(chan->sg, VIRTQUEUE_NUM);
chan->inuse = false;
if (virtio_has_feature(vdev, VIRTIO_9P_MOUNT_TAG)) {
virtio_cread(vdev, struct virtio_9p_config, tag_len, &tag_len);
} else {
err = -EINVAL;
goto out_free_vq;
}
tag = kmalloc(tag_len, GFP_KERNEL);
if (!tag) {
err = -ENOMEM;
goto out_free_vq;
}
virtio_cread_bytes(vdev, offsetof(struct virtio_9p_config, tag),
tag, tag_len);
chan->tag = tag;
chan->tag_len = tag_len;
err = sysfs_create_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
if (err) {
goto out_free_tag;
}
chan->vc_wq = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL);
if (!chan->vc_wq) {
err = -ENOMEM;
goto out_free_tag;
}
init_waitqueue_head(chan->vc_wq);
chan->ring_bufs_avail = 1;
/* Ceiling limit to avoid denial of service attacks */
chan->p9_max_pages = nr_free_buffer_pages()/4;
virtio_device_ready(vdev);
mutex_lock(&virtio_9p_lock);
list_add_tail(&chan->chan_list, &virtio_chan_list);
mutex_unlock(&virtio_9p_lock);
/* Let udev rules use the new mount_tag attribute. */
kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE);
return 0;
out_free_tag:
kfree(tag);
out_free_vq:
vdev->config->del_vqs(vdev);
out_free_chan:
kfree(chan);
fail:
return err;
}
/**
* p9_virtio_create - allocate a new virtio channel
* @client: client instance invoking this transport
* @devname: string identifying the channel to connect to (unused)
* @args: args passed from sys_mount() for per-transport options (unused)
*
* This sets up a transport channel for 9p communication. Right now
* we only match the first available channel, but eventually we couldlook up
* alternate channels by matching devname versus a virtio_config entry.
* We use a simple reference count mechanism to ensure that only a single
* mount has a channel open at a time.
*
*/
static int
p9_virtio_create(struct p9_client *client, const char *devname, char *args)
{
struct virtio_chan *chan;
int ret = -ENOENT;
int found = 0;
if (devname == NULL)
return -EINVAL;
mutex_lock(&virtio_9p_lock);
list_for_each_entry(chan, &virtio_chan_list, chan_list) {
if (!strncmp(devname, chan->tag, chan->tag_len) &&
strlen(devname) == chan->tag_len) {
if (!chan->inuse) {
chan->inuse = true;
found = 1;
break;
}
ret = -EBUSY;
}
}
mutex_unlock(&virtio_9p_lock);
if (!found) {
pr_err("no channels available\n");
return ret;
}
client->trans = (void *)chan;
client->status = Connected;
chan->client = client;
return 0;
}
/**
* p9_virtio_remove - clean up resources associated with a virtio device
* @vdev: virtio device to remove
*
*/
static void p9_virtio_remove(struct virtio_device *vdev)
{
struct virtio_chan *chan = vdev->priv;
unsigned long warning_time;
mutex_lock(&virtio_9p_lock);
/* Remove self from list so we don't get new users. */
list_del(&chan->chan_list);
warning_time = jiffies;
/* Wait for existing users to close. */
while (chan->inuse) {
mutex_unlock(&virtio_9p_lock);
msleep(250);
if (time_after(jiffies, warning_time + 10 * HZ)) {
dev_emerg(&vdev->dev,
"p9_virtio_remove: waiting for device in use.\n");
warning_time = jiffies;
}
mutex_lock(&virtio_9p_lock);
}
mutex_unlock(&virtio_9p_lock);
vdev->config->reset(vdev);
vdev->config->del_vqs(vdev);
sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr);
kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE);
kfree(chan->tag);
kfree(chan->vc_wq);
kfree(chan);
}
static struct virtio_device_id id_table[] = {
{ VIRTIO_ID_9P, VIRTIO_DEV_ANY_ID },
{ 0 },
};
static unsigned int features[] = {
VIRTIO_9P_MOUNT_TAG,
};
/* The standard "struct lguest_driver": */
static struct virtio_driver p9_virtio_drv = {
.feature_table = features,
.feature_table_size = ARRAY_SIZE(features),
.driver.name = KBUILD_MODNAME,
.driver.owner = THIS_MODULE,
.id_table = id_table,
.probe = p9_virtio_probe,
.remove = p9_virtio_remove,
};
static struct p9_trans_module p9_virtio_trans = {
.name = "virtio",
.create = p9_virtio_create,
.close = p9_virtio_close,
.request = p9_virtio_request,
.zc_request = p9_virtio_zc_request,
.cancel = p9_virtio_cancel,
/*
* We leave one entry for input and one entry for response
* headers. We also skip one more entry to accomodate, address
* that are not at page boundary, that can result in an extra
* page in zero copy.
*/
.maxsize = PAGE_SIZE * (VIRTQUEUE_NUM - 3),
.def = 1,
.owner = THIS_MODULE,
};
/* The standard init function */
static int __init p9_virtio_init(void)
{
INIT_LIST_HEAD(&virtio_chan_list);
v9fs_register_trans(&p9_virtio_trans);
return register_virtio_driver(&p9_virtio_drv);
}
static void __exit p9_virtio_cleanup(void)
{
unregister_virtio_driver(&p9_virtio_drv);
v9fs_unregister_trans(&p9_virtio_trans);
}
module_init(p9_virtio_init);
module_exit(p9_virtio_cleanup);
MODULE_DEVICE_TABLE(virtio, id_table);
MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
MODULE_DESCRIPTION("Virtio 9p Transport");
MODULE_LICENSE("GPL");

View File

@@ -1,141 +0,0 @@
/*
* net/9p/util.c
*
* This file contains some helper functions
*
* Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/parser.h>
#include <linux/idr.h>
#include <linux/slab.h>
#include <net/9p/9p.h>
/**
* struct p9_idpool - per-connection accounting for tag idpool
* @lock: protects the pool
* @pool: idr to allocate tag id from
*
*/
struct p9_idpool {
spinlock_t lock;
struct idr pool;
};
/**
* p9_idpool_create - create a new per-connection id pool
*
*/
struct p9_idpool *p9_idpool_create(void)
{
struct p9_idpool *p;
p = kmalloc(sizeof(struct p9_idpool), GFP_KERNEL);
if (!p)
return ERR_PTR(-ENOMEM);
spin_lock_init(&p->lock);
idr_init(&p->pool);
return p;
}
EXPORT_SYMBOL(p9_idpool_create);
/**
* p9_idpool_destroy - create a new per-connection id pool
* @p: idpool to destroy
*/
void p9_idpool_destroy(struct p9_idpool *p)
{
idr_destroy(&p->pool);
kfree(p);
}
EXPORT_SYMBOL(p9_idpool_destroy);
/**
* p9_idpool_get - allocate numeric id from pool
* @p: pool to allocate from
*
* Bugs: This seems to be an awful generic function, should it be in idr.c with
* the lock included in struct idr?
*/
int p9_idpool_get(struct p9_idpool *p)
{
int i;
unsigned long flags;
idr_preload(GFP_NOFS);
spin_lock_irqsave(&p->lock, flags);
/* no need to store exactly p, we just need something non-null */
i = idr_alloc(&p->pool, p, 0, 0, GFP_NOWAIT);
spin_unlock_irqrestore(&p->lock, flags);
idr_preload_end();
if (i < 0)
return -1;
p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", i, p);
return i;
}
EXPORT_SYMBOL(p9_idpool_get);
/**
* p9_idpool_put - release numeric id from pool
* @id: numeric id which is being released
* @p: pool to release id into
*
* Bugs: This seems to be an awful generic function, should it be in idr.c with
* the lock included in struct idr?
*/
void p9_idpool_put(int id, struct p9_idpool *p)
{
unsigned long flags;
p9_debug(P9_DEBUG_MUX, " id %d pool %p\n", id, p);
spin_lock_irqsave(&p->lock, flags);
idr_remove(&p->pool, id);
spin_unlock_irqrestore(&p->lock, flags);
}
EXPORT_SYMBOL(p9_idpool_put);
/**
* p9_idpool_check - check if the specified id is available
* @id: id to check
* @p: pool to check
*/
int p9_idpool_check(int id, struct p9_idpool *p)
{
return idr_find(&p->pool, id) != NULL;
}
EXPORT_SYMBOL(p9_idpool_check);

View File

@@ -1,700 +0,0 @@
/*
* linux/fs/9p/v9fs.c
*
* This file contains functions assisting in mapping VFS to 9P2000
*
* Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/parser.h>
#include <linux/idr.h>
#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "cache.h"
static DEFINE_SPINLOCK(v9fs_sessionlist_lock);
static LIST_HEAD(v9fs_sessionlist);
struct kmem_cache *v9fs_inode_cache;
/*
* Option Parsing (code inspired by NFS code)
* NOTE: each transport will parse its own options
*/
enum {
/* Options that take integer arguments */
Opt_debug, Opt_dfltuid, Opt_dfltgid, Opt_afid,
/* String options */
Opt_uname, Opt_remotename, Opt_cache, Opt_cachetag,
/* Options that take no arguments */
Opt_nodevmap,
/* Cache options */
Opt_cache_loose, Opt_fscache, Opt_mmap,
/* Access options */
Opt_access, Opt_posixacl,
/* Lock timeout option */
Opt_locktimeout,
/* Error token */
Opt_err
};
static const match_table_t tokens = {
{Opt_debug, "debug=%x"},
{Opt_dfltuid, "dfltuid=%u"},
{Opt_dfltgid, "dfltgid=%u"},
{Opt_afid, "afid=%u"},
{Opt_uname, "uname=%s"},
{Opt_remotename, "aname=%s"},
{Opt_nodevmap, "nodevmap"},
{Opt_cache, "cache=%s"},
{Opt_cache_loose, "loose"},
{Opt_fscache, "fscache"},
{Opt_mmap, "mmap"},
{Opt_cachetag, "cachetag=%s"},
{Opt_access, "access=%s"},
{Opt_posixacl, "posixacl"},
{Opt_locktimeout, "locktimeout=%u"},
{Opt_err, NULL}
};
/* Interpret mount options for cache mode */
static int get_cache_mode(char *s)
{
int version = -EINVAL;
if (!strcmp(s, "loose")) {
version = CACHE_LOOSE;
p9_debug(P9_DEBUG_9P, "Cache mode: loose\n");
} else if (!strcmp(s, "fscache")) {
version = CACHE_FSCACHE;
p9_debug(P9_DEBUG_9P, "Cache mode: fscache\n");
} else if (!strcmp(s, "mmap")) {
version = CACHE_MMAP;
p9_debug(P9_DEBUG_9P, "Cache mode: mmap\n");
} else if (!strcmp(s, "none")) {
version = CACHE_NONE;
p9_debug(P9_DEBUG_9P, "Cache mode: none\n");
} else
pr_info("Unknown Cache mode %s\n", s);
return version;
}
/**
* v9fs_parse_options - parse mount options into session structure
* @v9ses: existing v9fs session information
*
* Return 0 upon success, -ERRNO upon failure.
*/
static int v9fs_parse_options(struct v9fs_session_info *v9ses, char *opts)
{
char *options, *tmp_options;
substring_t args[MAX_OPT_ARGS];
char *p;
int option = 0;
char *s, *e;
int ret = 0;
/* setup defaults */
v9ses->afid = ~0;
v9ses->debug = 0;
v9ses->cache = CACHE_NONE;
#ifdef CONFIG_9P_FSCACHE
v9ses->cachetag = NULL;
#endif
v9ses->session_lock_timeout = P9_LOCK_TIMEOUT;
if (!opts)
return 0;
tmp_options = kstrdup(opts, GFP_KERNEL);
if (!tmp_options) {
ret = -ENOMEM;
goto fail_option_alloc;
}
options = tmp_options;
while ((p = strsep(&options, ",")) != NULL) {
int token, r;
if (!*p)
continue;
token = match_token(p, tokens, args);
switch (token) {
case Opt_debug:
r = match_int(&args[0], &option);
if (r < 0) {
p9_debug(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
ret = r;
continue;
}
v9ses->debug = option;
#ifdef CONFIG_NET_9P_DEBUG
p9_debug_level = option;
#endif
break;
case Opt_dfltuid:
r = match_int(&args[0], &option);
if (r < 0) {
p9_debug(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
ret = r;
continue;
}
v9ses->dfltuid = make_kuid(current_user_ns(), option);
if (!uid_valid(v9ses->dfltuid)) {
p9_debug(P9_DEBUG_ERROR,
"uid field, but not a uid?\n");
ret = -EINVAL;
continue;
}
break;
case Opt_dfltgid:
r = match_int(&args[0], &option);
if (r < 0) {
p9_debug(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
ret = r;
continue;
}
v9ses->dfltgid = make_kgid(current_user_ns(), option);
if (!gid_valid(v9ses->dfltgid)) {
p9_debug(P9_DEBUG_ERROR,
"gid field, but not a gid?\n");
ret = -EINVAL;
continue;
}
break;
case Opt_afid:
r = match_int(&args[0], &option);
if (r < 0) {
p9_debug(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
ret = r;
continue;
}
v9ses->afid = option;
break;
case Opt_uname:
kfree(v9ses->uname);
v9ses->uname = match_strdup(&args[0]);
if (!v9ses->uname) {
ret = -ENOMEM;
goto free_and_return;
}
break;
case Opt_remotename:
kfree(v9ses->aname);
v9ses->aname = match_strdup(&args[0]);
if (!v9ses->aname) {
ret = -ENOMEM;
goto free_and_return;
}
break;
case Opt_nodevmap:
v9ses->nodev = 1;
break;
case Opt_cache_loose:
v9ses->cache = CACHE_LOOSE;
break;
case Opt_fscache:
v9ses->cache = CACHE_FSCACHE;
break;
case Opt_mmap:
v9ses->cache = CACHE_MMAP;
break;
case Opt_cachetag:
#ifdef CONFIG_9P_FSCACHE
v9ses->cachetag = match_strdup(&args[0]);
#endif
break;
case Opt_cache:
s = match_strdup(&args[0]);
if (!s) {
ret = -ENOMEM;
p9_debug(P9_DEBUG_ERROR,
"problem allocating copy of cache arg\n");
goto free_and_return;
}
ret = get_cache_mode(s);
if (ret == -EINVAL) {
kfree(s);
goto free_and_return;
}
v9ses->cache = ret;
kfree(s);
break;
case Opt_access:
s = match_strdup(&args[0]);
if (!s) {
ret = -ENOMEM;
p9_debug(P9_DEBUG_ERROR,
"problem allocating copy of access arg\n");
goto free_and_return;
}
v9ses->flags &= ~V9FS_ACCESS_MASK;
if (strcmp(s, "user") == 0)
v9ses->flags |= V9FS_ACCESS_USER;
else if (strcmp(s, "any") == 0)
v9ses->flags |= V9FS_ACCESS_ANY;
else if (strcmp(s, "client") == 0) {
v9ses->flags |= V9FS_ACCESS_CLIENT;
} else {
uid_t uid;
v9ses->flags |= V9FS_ACCESS_SINGLE;
uid = simple_strtoul(s, &e, 10);
if (*e != '\0') {
ret = -EINVAL;
pr_info("Unknown access argument %s\n",
s);
kfree(s);
goto free_and_return;
}
v9ses->uid = make_kuid(current_user_ns(), uid);
if (!uid_valid(v9ses->uid)) {
ret = -EINVAL;
pr_info("Uknown uid %s\n", s);
kfree(s);
goto free_and_return;
}
}
kfree(s);
break;
case Opt_posixacl:
#ifdef CONFIG_9P_FS_POSIX_ACL
v9ses->flags |= V9FS_POSIX_ACL;
#else
p9_debug(P9_DEBUG_ERROR,
"Not defined CONFIG_9P_FS_POSIX_ACL. Ignoring posixacl option\n");
#endif
break;
case Opt_locktimeout:
r = match_int(&args[0], &option);
if (r < 0) {
p9_debug(P9_DEBUG_ERROR,
"integer field, but no integer?\n");
ret = r;
continue;
}
if (option < 1) {
p9_debug(P9_DEBUG_ERROR,
"locktimeout must be a greater than zero integer.\n");
ret = -EINVAL;
continue;
}
v9ses->session_lock_timeout = (long)option * HZ;
break;
default:
continue;
}
}
free_and_return:
kfree(tmp_options);
fail_option_alloc:
return ret;
}
/**
* v9fs_session_init - initialize session
* @v9ses: session information structure
* @dev_name: device being mounted
* @data: options
*
*/
struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
const char *dev_name, char *data)
{
struct p9_fid *fid;
int rc = -ENOMEM;
v9ses->uname = kstrdup(V9FS_DEFUSER, GFP_KERNEL);
if (!v9ses->uname)
goto err_names;
v9ses->aname = kstrdup(V9FS_DEFANAME, GFP_KERNEL);
if (!v9ses->aname)
goto err_names;
init_rwsem(&v9ses->rename_sem);
rc = bdi_setup_and_register(&v9ses->bdi, "9p");
if (rc)
goto err_names;
v9ses->uid = INVALID_UID;
v9ses->dfltuid = V9FS_DEFUID;
v9ses->dfltgid = V9FS_DEFGID;
v9ses->clnt = p9_client_create(dev_name, data);
if (IS_ERR(v9ses->clnt)) {
rc = PTR_ERR(v9ses->clnt);
p9_debug(P9_DEBUG_ERROR, "problem initializing 9p client\n");
goto err_bdi;
}
v9ses->flags = V9FS_ACCESS_USER;
if (p9_is_proto_dotl(v9ses->clnt)) {
v9ses->flags = V9FS_ACCESS_CLIENT;
v9ses->flags |= V9FS_PROTO_2000L;
} else if (p9_is_proto_dotu(v9ses->clnt)) {
v9ses->flags |= V9FS_PROTO_2000U;
}
rc = v9fs_parse_options(v9ses, data);
if (rc < 0)
goto err_clnt;
v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;
if (!v9fs_proto_dotl(v9ses) &&
((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
/*
* We support ACCESS_CLIENT only for dotl.
* Fall back to ACCESS_USER
*/
v9ses->flags &= ~V9FS_ACCESS_MASK;
v9ses->flags |= V9FS_ACCESS_USER;
}
/*FIXME !! */
/* for legacy mode, fall back to V9FS_ACCESS_ANY */
if (!(v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses)) &&
((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {
v9ses->flags &= ~V9FS_ACCESS_MASK;
v9ses->flags |= V9FS_ACCESS_ANY;
v9ses->uid = INVALID_UID;
}
if (!v9fs_proto_dotl(v9ses) ||
!((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_CLIENT)) {
/*
* We support ACL checks on clinet only if the protocol is
* 9P2000.L and access is V9FS_ACCESS_CLIENT.
*/
v9ses->flags &= ~V9FS_ACL_MASK;
}
fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, INVALID_UID,
v9ses->aname);
if (IS_ERR(fid)) {
rc = PTR_ERR(fid);
p9_debug(P9_DEBUG_ERROR, "cannot attach\n");
goto err_clnt;
}
if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE)
fid->uid = v9ses->uid;
else
fid->uid = INVALID_UID;
#ifdef CONFIG_9P_FSCACHE
/* register the session for caching */
v9fs_cache_session_get_cookie(v9ses);
#endif
spin_lock(&v9fs_sessionlist_lock);
list_add(&v9ses->slist, &v9fs_sessionlist);
spin_unlock(&v9fs_sessionlist_lock);
return fid;
err_clnt:
p9_client_destroy(v9ses->clnt);
err_bdi:
bdi_destroy(&v9ses->bdi);
err_names:
kfree(v9ses->uname);
kfree(v9ses->aname);
return ERR_PTR(rc);
}
/**
* v9fs_session_close - shutdown a session
* @v9ses: session information structure
*
*/
void v9fs_session_close(struct v9fs_session_info *v9ses)
{
if (v9ses->clnt) {
p9_client_destroy(v9ses->clnt);
v9ses->clnt = NULL;
}
#ifdef CONFIG_9P_FSCACHE
if (v9ses->fscache) {
v9fs_cache_session_put_cookie(v9ses);
kfree(v9ses->cachetag);
}
#endif
kfree(v9ses->uname);
kfree(v9ses->aname);
bdi_destroy(&v9ses->bdi);
spin_lock(&v9fs_sessionlist_lock);
list_del(&v9ses->slist);
spin_unlock(&v9fs_sessionlist_lock);
}
/**
* v9fs_session_cancel - terminate a session
* @v9ses: session to terminate
*
* mark transport as disconnected and cancel all pending requests.
*/
void v9fs_session_cancel(struct v9fs_session_info *v9ses) {
p9_debug(P9_DEBUG_ERROR, "cancel session %p\n", v9ses);
p9_client_disconnect(v9ses->clnt);
}
/**
* v9fs_session_begin_cancel - Begin terminate of a session
* @v9ses: session to terminate
*
* After this call we don't allow any request other than clunk.
*/
void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses)
{
p9_debug(P9_DEBUG_ERROR, "begin cancel session %p\n", v9ses);
p9_client_begin_disconnect(v9ses->clnt);
}
extern int v9fs_error_init(void);
static struct kobject *v9fs_kobj;
#ifdef CONFIG_9P_FSCACHE
/**
* caches_show - list caches associated with a session
*
* Returns the size of buffer written.
*/
static ssize_t caches_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
{
ssize_t n = 0, count = 0, limit = PAGE_SIZE;
struct v9fs_session_info *v9ses;
spin_lock(&v9fs_sessionlist_lock);
list_for_each_entry(v9ses, &v9fs_sessionlist, slist) {
if (v9ses->cachetag) {
n = snprintf(buf, limit, "%s\n", v9ses->cachetag);
if (n < 0) {
count = n;
break;
}
count += n;
limit -= n;
}
}
spin_unlock(&v9fs_sessionlist_lock);
return count;
}
static struct kobj_attribute v9fs_attr_cache = __ATTR_RO(caches);
#endif /* CONFIG_9P_FSCACHE */
static struct attribute *v9fs_attrs[] = {
#ifdef CONFIG_9P_FSCACHE
&v9fs_attr_cache.attr,
#endif
NULL,
};
static struct attribute_group v9fs_attr_group = {
.attrs = v9fs_attrs,
};
/**
* v9fs_sysfs_init - Initialize the v9fs sysfs interface
*
*/
static int __init v9fs_sysfs_init(void)
{
v9fs_kobj = kobject_create_and_add("9p", fs_kobj);
if (!v9fs_kobj)
return -ENOMEM;
if (sysfs_create_group(v9fs_kobj, &v9fs_attr_group)) {
kobject_put(v9fs_kobj);
return -ENOMEM;
}
return 0;
}
/**
* v9fs_sysfs_cleanup - Unregister the v9fs sysfs interface
*
*/
static void v9fs_sysfs_cleanup(void)
{
sysfs_remove_group(v9fs_kobj, &v9fs_attr_group);
kobject_put(v9fs_kobj);
}
static void v9fs_inode_init_once(void *foo)
{
struct v9fs_inode *v9inode = (struct v9fs_inode *)foo;
#ifdef CONFIG_9P_FSCACHE
v9inode->fscache = NULL;
#endif
memset(&v9inode->qid, 0, sizeof(v9inode->qid));
inode_init_once(&v9inode->vfs_inode);
}
/**
* v9fs_init_inode_cache - initialize a cache for 9P
* Returns 0 on success.
*/
static int v9fs_init_inode_cache(void)
{
v9fs_inode_cache = kmem_cache_create("v9fs_inode_cache",
sizeof(struct v9fs_inode),
0, (SLAB_RECLAIM_ACCOUNT|
SLAB_MEM_SPREAD),
v9fs_inode_init_once);
if (!v9fs_inode_cache)
return -ENOMEM;
return 0;
}
/**
* v9fs_destroy_inode_cache - destroy the cache of 9P inode
*
*/
static void v9fs_destroy_inode_cache(void)
{
/*
* Make sure all delayed rcu free inodes are flushed before we
* destroy cache.
*/
rcu_barrier();
kmem_cache_destroy(v9fs_inode_cache);
}
static int v9fs_cache_register(void)
{
int ret;
ret = v9fs_init_inode_cache();
if (ret < 0)
return ret;
#ifdef CONFIG_9P_FSCACHE
ret = fscache_register_netfs(&v9fs_cache_netfs);
if (ret < 0)
v9fs_destroy_inode_cache();
#endif
return ret;
}
static void v9fs_cache_unregister(void)
{
v9fs_destroy_inode_cache();
#ifdef CONFIG_9P_FSCACHE
fscache_unregister_netfs(&v9fs_cache_netfs);
#endif
}
/**
* init_v9fs - Initialize module
*
*/
static int __init init_v9fs(void)
{
int err;
pr_info("Installing v9fs 9p2000 file system support\n");
/* TODO: Setup list of registered trasnport modules */
err = v9fs_cache_register();
if (err < 0) {
pr_err("Failed to register v9fs for caching\n");
return err;
}
err = v9fs_sysfs_init();
if (err < 0) {
pr_err("Failed to register with sysfs\n");
goto out_cache;
}
err = register_filesystem(&v9fs_fs_type);
if (err < 0) {
pr_err("Failed to register filesystem\n");
goto out_sysfs_cleanup;
}
return 0;
out_sysfs_cleanup:
v9fs_sysfs_cleanup();
out_cache:
v9fs_cache_unregister();
return err;
}
/**
* exit_v9fs - shutdown module
*
*/
static void __exit exit_v9fs(void)
{
v9fs_sysfs_cleanup();
v9fs_cache_unregister();
unregister_filesystem(&v9fs_fs_type);
}
module_init(init_v9fs)
module_exit(exit_v9fs)
MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>");
MODULE_LICENSE("GPL");

View File

@@ -1,226 +0,0 @@
/*
* V9FS definitions.
*
* Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#ifndef FS_9P_V9FS_H
#define FS_9P_V9FS_H
#include <linux/backing-dev.h>
/**
* enum p9_session_flags - option flags for each 9P session
* @V9FS_PROTO_2000U: whether or not to use 9P2000.u extensions
* @V9FS_PROTO_2000L: whether or not to use 9P2000.l extensions
* @V9FS_ACCESS_SINGLE: only the mounting user can access the hierarchy
* @V9FS_ACCESS_USER: a new attach will be issued for every user (default)
* @V9FS_ACCESS_CLIENT: Just like user, but access check is performed on client.
* @V9FS_ACCESS_ANY: use a single attach for all users
* @V9FS_ACCESS_MASK: bit mask of different ACCESS options
* @V9FS_POSIX_ACL: POSIX ACLs are enforced
*
* Session flags reflect options selected by users at mount time
*/
#define V9FS_ACCESS_ANY (V9FS_ACCESS_SINGLE | \
V9FS_ACCESS_USER | \
V9FS_ACCESS_CLIENT)
#define V9FS_ACCESS_MASK V9FS_ACCESS_ANY
#define V9FS_ACL_MASK V9FS_POSIX_ACL
enum p9_session_flags {
V9FS_PROTO_2000U = 0x01,
V9FS_PROTO_2000L = 0x02,
V9FS_ACCESS_SINGLE = 0x04,
V9FS_ACCESS_USER = 0x08,
V9FS_ACCESS_CLIENT = 0x10,
V9FS_POSIX_ACL = 0x20
};
/* possible values of ->cache */
/**
* enum p9_cache_modes - user specified cache preferences
* @CACHE_NONE: do not cache data, dentries, or directory contents (default)
* @CACHE_LOOSE: cache data, dentries, and directory contents w/no consistency
*
* eventually support loose, tight, time, session, default always none
*/
enum p9_cache_modes {
CACHE_NONE,
CACHE_MMAP,
CACHE_LOOSE,
CACHE_FSCACHE,
};
/**
* struct v9fs_session_info - per-instance session information
* @flags: session options of type &p9_session_flags
* @nodev: set to 1 to disable device mapping
* @debug: debug level
* @afid: authentication handle
* @cache: cache mode of type &p9_cache_modes
* @cachetag: the tag of the cache associated with this session
* @fscache: session cookie associated with FS-Cache
* @uname: string user name to mount hierarchy as
* @aname: mount specifier for remote hierarchy
* @maxdata: maximum data to be sent/recvd per protocol message
* @dfltuid: default numeric userid to mount hierarchy as
* @dfltgid: default numeric groupid to mount hierarchy as
* @uid: if %V9FS_ACCESS_SINGLE, the numeric uid which mounted the hierarchy
* @clnt: reference to 9P network client instantiated for this session
* @slist: reference to list of registered 9p sessions
*
* This structure holds state for each session instance established during
* a sys_mount() .
*
* Bugs: there seems to be a lot of state which could be condensed and/or
* removed.
*/
struct v9fs_session_info {
/* options */
unsigned char flags;
unsigned char nodev;
unsigned short debug;
unsigned int afid;
unsigned int cache;
#ifdef CONFIG_9P_FSCACHE
char *cachetag;
struct fscache_cookie *fscache;
#endif
char *uname; /* user name to mount as */
char *aname; /* name of remote hierarchy being mounted */
unsigned int maxdata; /* max data for client interface */
kuid_t dfltuid; /* default uid/muid for legacy support */
kgid_t dfltgid; /* default gid for legacy support */
kuid_t uid; /* if ACCESS_SINGLE, the uid that has access */
struct p9_client *clnt; /* 9p client */
struct list_head slist; /* list of sessions registered with v9fs */
struct backing_dev_info bdi;
struct rw_semaphore rename_sem;
long session_lock_timeout; /* retry interval for blocking locks */
};
/* cache_validity flags */
#define V9FS_INO_INVALID_ATTR 0x01
struct v9fs_inode {
#ifdef CONFIG_9P_FSCACHE
struct mutex fscache_lock;
struct fscache_cookie *fscache;
#endif
struct p9_qid qid;
unsigned int cache_validity;
struct p9_fid *writeback_fid;
struct mutex v_mutex;
struct inode vfs_inode;
};
static inline struct v9fs_inode *V9FS_I(const struct inode *inode)
{
return container_of(inode, struct v9fs_inode, vfs_inode);
}
struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
char *);
extern void v9fs_session_close(struct v9fs_session_info *v9ses);
extern void v9fs_session_cancel(struct v9fs_session_info *v9ses);
extern void v9fs_session_begin_cancel(struct v9fs_session_info *v9ses);
extern struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
unsigned int flags);
extern int v9fs_vfs_unlink(struct inode *i, struct dentry *d);
extern int v9fs_vfs_rmdir(struct inode *i, struct dentry *d);
extern int v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry);
extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
struct p9_fid *fid,
struct super_block *sb, int new);
extern const struct inode_operations v9fs_dir_inode_operations_dotl;
extern const struct inode_operations v9fs_file_inode_operations_dotl;
extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
struct p9_fid *fid,
struct super_block *sb, int new);
/* other default globals */
#define V9FS_PORT 564
#define V9FS_DEFUSER "nobody"
#define V9FS_DEFANAME ""
#define V9FS_DEFUID KUIDT_INIT(-2)
#define V9FS_DEFGID KGIDT_INIT(-2)
static inline struct v9fs_session_info *v9fs_inode2v9ses(struct inode *inode)
{
return (inode->i_sb->s_fs_info);
}
static inline struct v9fs_session_info *v9fs_dentry2v9ses(struct dentry *dentry)
{
return dentry->d_sb->s_fs_info;
}
static inline int v9fs_proto_dotu(struct v9fs_session_info *v9ses)
{
return v9ses->flags & V9FS_PROTO_2000U;
}
static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
{
return v9ses->flags & V9FS_PROTO_2000L;
}
/**
* v9fs_get_inode_from_fid - Helper routine to populate an inode by
* issuing a attribute request
* @v9ses: session information
* @fid: fid to issue attribute request for
* @sb: superblock on which to create inode
*
*/
static inline struct inode *
v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb)
{
if (v9fs_proto_dotl(v9ses))
return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 0);
else
return v9fs_inode_from_fid(v9ses, fid, sb, 0);
}
/**
* v9fs_get_new_inode_from_fid - Helper routine to populate an inode by
* issuing a attribute request
* @v9ses: session information
* @fid: fid to issue attribute request for
* @sb: superblock on which to create inode
*
*/
static inline struct inode *
v9fs_get_new_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb)
{
if (v9fs_proto_dotl(v9ses))
return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 1);
else
return v9fs_inode_from_fid(v9ses, fid, sb, 1);
}
#endif

View File

@@ -1,105 +0,0 @@
/*
* V9FS VFS extensions.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#ifndef FS_9P_V9FS_VFS_H
#define FS_9P_V9FS_VFS_H
/* plan9 semantics are that created files are implicitly opened.
* But linux semantics are that you call create, then open.
* the plan9 approach is superior as it provides an atomic
* open.
* we track the create fid here. When the file is opened, if fidopen is
* non-zero, we use the fid and can skip some steps.
* there may be a better way to do this, but I don't know it.
* one BAD way is to clunk the fid on create, then open it again:
* you lose the atomicity of file open
*/
/* special case:
* unlink calls remove, which is an implicit clunk. So we have to track
* that kind of thing so that we don't try to clunk a dead fid.
*/
#define P9_LOCK_TIMEOUT (30*HZ)
/* flags for v9fs_stat2inode() & v9fs_stat2inode_dotl() */
#define V9FS_STAT2INODE_KEEP_ISIZE 1
extern struct file_system_type v9fs_fs_type;
extern const struct address_space_operations v9fs_addr_operations;
extern const struct file_operations v9fs_file_operations;
extern const struct file_operations v9fs_file_operations_dotl;
extern const struct file_operations v9fs_dir_operations;
extern const struct file_operations v9fs_dir_operations_dotl;
extern const struct dentry_operations v9fs_dentry_operations;
extern const struct dentry_operations v9fs_cached_dentry_operations;
extern const struct file_operations v9fs_cached_file_operations;
extern const struct file_operations v9fs_cached_file_operations_dotl;
extern const struct file_operations v9fs_mmap_file_operations;
extern const struct file_operations v9fs_mmap_file_operations_dotl;
extern struct kmem_cache *v9fs_inode_cache;
struct inode *v9fs_alloc_inode(struct super_block *sb);
void v9fs_destroy_inode(struct inode *inode);
struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t);
int v9fs_init_inode(struct v9fs_session_info *v9ses,
struct inode *inode, umode_t mode, dev_t);
void v9fs_evict_inode(struct inode *inode);
ino_t v9fs_qid2ino(struct p9_qid *qid);
void v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
struct super_block *sb, unsigned int flags);
void v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode,
unsigned int flags);
int v9fs_dir_release(struct inode *inode, struct file *filp);
int v9fs_file_open(struct inode *inode, struct file *file);
void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
int v9fs_uflags2omode(int uflags, int extended);
void v9fs_blank_wstat(struct p9_wstat *wstat);
int v9fs_vfs_setattr_dotl(struct dentry *, struct iattr *);
int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
int datasync);
int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode);
int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode);
static inline void v9fs_invalidate_inode_attr(struct inode *inode)
{
struct v9fs_inode *v9inode;
v9inode = V9FS_I(inode);
v9inode->cache_validity |= V9FS_INO_INVALID_ATTR;
return;
}
int v9fs_open_to_dotl_flags(int flags);
static inline void v9fs_i_size_write(struct inode *inode, loff_t i_size)
{
/*
* 32-bit need the lock, concurrent updates could break the
* sequences and make i_size_read() loop forever.
* 64-bit updates are atomic and can skip the locking.
*/
if (sizeof(i_size) > sizeof(long))
spin_lock(&inode->i_lock);
i_size_write(inode, i_size);
if (sizeof(i_size) > sizeof(long))
spin_unlock(&inode->i_lock);
}
#endif

View File

@@ -1,351 +0,0 @@
/*
* linux/fs/9p/vfs_addr.c
*
* This file contians vfs address (mmap) ops for 9P2000.
*
* Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/inet.h>
#include <linux/pagemap.h>
#include <linux/idr.h>
#include <linux/sched.h>
#include <linux/uio.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "cache.h"
#include "fid.h"
/**
* v9fs_fid_readpage - read an entire page in from 9P
*
* @fid: fid being read
* @page: structure to page
*
*/
static int v9fs_fid_readpage(struct p9_fid *fid, struct page *page)
{
struct inode *inode = page->mapping->host;
struct bio_vec bvec = {.bv_page = page, .bv_len = PAGE_SIZE};
struct iov_iter to;
int retval, err;
p9_debug(P9_DEBUG_VFS, "\n");
BUG_ON(!PageLocked(page));
retval = v9fs_readpage_from_fscache(inode, page);
if (retval == 0)
return retval;
iov_iter_bvec(&to, ITER_BVEC | READ, &bvec, 1, PAGE_SIZE);
retval = p9_client_read(fid, page_offset(page), &to, &err);
if (err) {
v9fs_uncache_page(inode, page);
retval = err;
goto done;
}
zero_user(page, retval, PAGE_SIZE - retval);
flush_dcache_page(page);
SetPageUptodate(page);
v9fs_readpage_to_fscache(inode, page);
retval = 0;
done:
unlock_page(page);
return retval;
}
/**
* v9fs_vfs_readpage - read an entire page in from 9P
*
* @filp: file being read
* @page: structure to page
*
*/
static int v9fs_vfs_readpage(struct file *filp, struct page *page)
{
return v9fs_fid_readpage(filp->private_data, page);
}
/**
* v9fs_vfs_readpages - read a set of pages from 9P
*
* @filp: file being read
* @mapping: the address space
* @pages: list of pages to read
* @nr_pages: count of pages to read
*
*/
static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping,
struct list_head *pages, unsigned nr_pages)
{
int ret = 0;
struct inode *inode;
inode = mapping->host;
p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, filp);
ret = v9fs_readpages_from_fscache(inode, mapping, pages, &nr_pages);
if (ret == 0)
return ret;
ret = read_cache_pages(mapping, pages, (void *)v9fs_vfs_readpage, filp);
p9_debug(P9_DEBUG_VFS, " = %d\n", ret);
return ret;
}
/**
* v9fs_release_page - release the private state associated with a page
*
* Returns 1 if the page can be released, false otherwise.
*/
static int v9fs_release_page(struct page *page, gfp_t gfp)
{
if (PagePrivate(page))
return 0;
return v9fs_fscache_release_page(page, gfp);
}
/**
* v9fs_invalidate_page - Invalidate a page completely or partially
*
* @page: structure to page
* @offset: offset in the page
*/
static void v9fs_invalidate_page(struct page *page, unsigned int offset,
unsigned int length)
{
/*
* If called with zero offset, we should release
* the private state assocated with the page
*/
if (offset == 0 && length == PAGE_CACHE_SIZE)
v9fs_fscache_invalidate_page(page);
}
static int v9fs_vfs_writepage_locked(struct page *page)
{
struct inode *inode = page->mapping->host;
struct v9fs_inode *v9inode = V9FS_I(inode);
loff_t size = i_size_read(inode);
struct iov_iter from;
struct bio_vec bvec;
int err, len;
if (page->index == size >> PAGE_CACHE_SHIFT)
len = size & ~PAGE_CACHE_MASK;
else
len = PAGE_CACHE_SIZE;
bvec.bv_page = page;
bvec.bv_offset = 0;
bvec.bv_len = len;
iov_iter_bvec(&from, ITER_BVEC | WRITE, &bvec, 1, len);
/* We should have writeback_fid always set */
BUG_ON(!v9inode->writeback_fid);
set_page_writeback(page);
p9_client_write(v9inode->writeback_fid, page_offset(page), &from, &err);
end_page_writeback(page);
return err;
}
static int v9fs_vfs_writepage(struct page *page, struct writeback_control *wbc)
{
int retval;
p9_debug(P9_DEBUG_VFS, "page %p\n", page);
retval = v9fs_vfs_writepage_locked(page);
if (retval < 0) {
if (retval == -EAGAIN) {
redirty_page_for_writepage(wbc, page);
retval = 0;
} else {
SetPageError(page);
mapping_set_error(page->mapping, retval);
}
} else
retval = 0;
unlock_page(page);
return retval;
}
/**
* v9fs_launder_page - Writeback a dirty page
* Returns 0 on success.
*/
static int v9fs_launder_page(struct page *page)
{
int retval;
struct inode *inode = page->mapping->host;
v9fs_fscache_wait_on_page_write(inode, page);
if (clear_page_dirty_for_io(page)) {
retval = v9fs_vfs_writepage_locked(page);
if (retval)
return retval;
}
return 0;
}
/**
* v9fs_direct_IO - 9P address space operation for direct I/O
* @iocb: target I/O control block
* @pos: offset in file to begin the operation
*
* The presence of v9fs_direct_IO() in the address space ops vector
* allowes open() O_DIRECT flags which would have failed otherwise.
*
* In the non-cached mode, we shunt off direct read and write requests before
* the VFS gets them, so this method should never be called.
*
* Direct IO is not 'yet' supported in the cached mode. Hence when
* this routine is called through generic_file_aio_read(), the read/write fails
* with an error.
*
*/
static ssize_t
v9fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter, loff_t pos)
{
struct file *file = iocb->ki_filp;
ssize_t n;
int err = 0;
if (iov_iter_rw(iter) == WRITE) {
n = p9_client_write(file->private_data, pos, iter, &err);
if (n) {
struct inode *inode = file_inode(file);
loff_t i_size = i_size_read(inode);
if (pos + n > i_size)
inode_add_bytes(inode, pos + n - i_size);
}
} else {
n = p9_client_read(file->private_data, pos, iter, &err);
}
return n ? n : err;
}
static int v9fs_write_begin(struct file *filp, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
int retval = 0;
struct page *page;
struct v9fs_inode *v9inode;
pgoff_t index = pos >> PAGE_CACHE_SHIFT;
struct inode *inode = mapping->host;
p9_debug(P9_DEBUG_VFS, "filp %p, mapping %p\n", filp, mapping);
v9inode = V9FS_I(inode);
start:
page = grab_cache_page_write_begin(mapping, index, flags);
if (!page) {
retval = -ENOMEM;
goto out;
}
BUG_ON(!v9inode->writeback_fid);
if (PageUptodate(page))
goto out;
if (len == PAGE_CACHE_SIZE)
goto out;
retval = v9fs_fid_readpage(v9inode->writeback_fid, page);
page_cache_release(page);
if (!retval)
goto start;
out:
*pagep = page;
return retval;
}
static int v9fs_write_end(struct file *filp, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata)
{
loff_t last_pos = pos + copied;
struct inode *inode = page->mapping->host;
p9_debug(P9_DEBUG_VFS, "filp %p, mapping %p\n", filp, mapping);
if (unlikely(copied < len)) {
/*
* zero out the rest of the area
*/
unsigned from = pos & (PAGE_CACHE_SIZE - 1);
zero_user(page, from + copied, len - copied);
flush_dcache_page(page);
}
if (!PageUptodate(page))
SetPageUptodate(page);
/*
* No need to use i_size_read() here, the i_size
* cannot change under us because we hold the i_mutex.
*/
if (last_pos > inode->i_size) {
inode_add_bytes(inode, last_pos - inode->i_size);
i_size_write(inode, last_pos);
}
set_page_dirty(page);
unlock_page(page);
page_cache_release(page);
return copied;
}
const struct address_space_operations v9fs_addr_operations = {
.readpage = v9fs_vfs_readpage,
.readpages = v9fs_vfs_readpages,
.set_page_dirty = __set_page_dirty_nobuffers,
.writepage = v9fs_vfs_writepage,
.write_begin = v9fs_write_begin,
.write_end = v9fs_write_end,
.releasepage = v9fs_release_page,
.invalidatepage = v9fs_invalidate_page,
.launder_page = v9fs_launder_page,
.direct_IO = v9fs_direct_IO,
};

View File

@@ -1,122 +0,0 @@
/*
* linux/fs/9p/vfs_dentry.c
*
* This file contians vfs dentry ops for the 9P2000 protocol.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/pagemap.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/inet.h>
#include <linux/namei.h>
#include <linux/idr.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
/**
* v9fs_cached_dentry_delete - called when dentry refcount equals 0
* @dentry: dentry in question
*
*/
static int v9fs_cached_dentry_delete(const struct dentry *dentry)
{
p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n",
dentry, dentry);
/* Don't cache negative dentries */
if (d_really_is_negative(dentry))
return 1;
return 0;
}
/**
* v9fs_dentry_release - called when dentry is going to be freed
* @dentry: dentry that is being release
*
*/
static void v9fs_dentry_release(struct dentry *dentry)
{
struct hlist_node *p, *n;
p9_debug(P9_DEBUG_VFS, " dentry: %pd (%p)\n",
dentry, dentry);
hlist_for_each_safe(p, n, (struct hlist_head *)&dentry->d_fsdata)
p9_client_clunk(hlist_entry(p, struct p9_fid, dlist));
dentry->d_fsdata = NULL;
}
static int v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
{
struct p9_fid *fid;
struct inode *inode;
struct v9fs_inode *v9inode;
if (flags & LOOKUP_RCU)
return -ECHILD;
inode = d_inode(dentry);
if (!inode)
goto out_valid;
v9inode = V9FS_I(inode);
if (v9inode->cache_validity & V9FS_INO_INVALID_ATTR) {
int retval;
struct v9fs_session_info *v9ses;
fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid))
return PTR_ERR(fid);
v9ses = v9fs_inode2v9ses(inode);
if (v9fs_proto_dotl(v9ses))
retval = v9fs_refresh_inode_dotl(fid, inode);
else
retval = v9fs_refresh_inode(fid, inode);
if (retval == -ENOENT)
return 0;
if (retval < 0)
return retval;
}
out_valid:
return 1;
}
const struct dentry_operations v9fs_cached_dentry_operations = {
.d_revalidate = v9fs_lookup_revalidate,
.d_weak_revalidate = v9fs_lookup_revalidate,
.d_delete = v9fs_cached_dentry_delete,
.d_release = v9fs_dentry_release,
};
const struct dentry_operations v9fs_dentry_operations = {
.d_delete = always_delete_dentry,
.d_release = v9fs_dentry_release,
};

View File

@@ -1,248 +0,0 @@
/*
* linux/fs/9p/vfs_dir.c
*
* This file contains vfs directory ops for the 9P2000 protocol.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/inet.h>
#include <linux/idr.h>
#include <linux/slab.h>
#include <linux/uio.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
/**
* struct p9_rdir - readdir accounting
* @head: start offset of current dirread buffer
* @tail: end offset of current dirread buffer
* @buf: dirread buffer
*
* private structure for keeping track of readdir
* allocated on demand
*/
struct p9_rdir {
int head;
int tail;
uint8_t buf[];
};
/**
* dt_type - return file type
* @mistat: mistat structure
*
*/
static inline int dt_type(struct p9_wstat *mistat)
{
unsigned long perm = mistat->mode;
int rettype = DT_REG;
if (perm & P9_DMDIR)
rettype = DT_DIR;
if (perm & P9_DMSYMLINK)
rettype = DT_LNK;
return rettype;
}
/**
* v9fs_alloc_rdir_buf - Allocate buffer used for read and readdir
* @filp: opened file structure
* @buflen: Length in bytes of buffer to allocate
*
*/
static struct p9_rdir *v9fs_alloc_rdir_buf(struct file *filp, int buflen)
{
struct p9_fid *fid = filp->private_data;
if (!fid->rdir)
fid->rdir = kzalloc(sizeof(struct p9_rdir) + buflen, GFP_KERNEL);
return fid->rdir;
}
/**
* v9fs_dir_readdir - iterate through a directory
* @file: opened file structure
* @ctx: actor we feed the entries to
*
*/
static int v9fs_dir_readdir(struct file *file, struct dir_context *ctx)
{
bool over;
struct p9_wstat st;
int err = 0;
struct p9_fid *fid;
int buflen;
struct p9_rdir *rdir;
struct kvec kvec;
p9_debug(P9_DEBUG_VFS, "name %pD\n", file);
fid = file->private_data;
buflen = fid->clnt->msize - P9_IOHDRSZ;
rdir = v9fs_alloc_rdir_buf(file, buflen);
if (!rdir)
return -ENOMEM;
kvec.iov_base = rdir->buf;
kvec.iov_len = buflen;
while (1) {
if (rdir->tail == rdir->head) {
struct iov_iter to;
int n;
iov_iter_kvec(&to, READ | ITER_KVEC, &kvec, 1, buflen);
n = p9_client_read(file->private_data, ctx->pos, &to,
&err);
if (err)
return err;
if (n == 0)
return 0;
rdir->head = 0;
rdir->tail = n;
}
while (rdir->head < rdir->tail) {
err = p9stat_read(fid->clnt, rdir->buf + rdir->head,
rdir->tail - rdir->head, &st);
if (err <= 0) {
p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
return -EIO;
}
over = !dir_emit(ctx, st.name, strlen(st.name),
v9fs_qid2ino(&st.qid), dt_type(&st));
p9stat_free(&st);
if (over)
return 0;
rdir->head += err;
ctx->pos += err;
}
}
}
/**
* v9fs_dir_readdir_dotl - iterate through a directory
* @file: opened file structure
* @ctx: actor we feed the entries to
*
*/
static int v9fs_dir_readdir_dotl(struct file *file, struct dir_context *ctx)
{
int err = 0;
struct p9_fid *fid;
int buflen;
struct p9_rdir *rdir;
struct p9_dirent curdirent;
p9_debug(P9_DEBUG_VFS, "name %pD\n", file);
fid = file->private_data;
buflen = fid->clnt->msize - P9_READDIRHDRSZ;
rdir = v9fs_alloc_rdir_buf(file, buflen);
if (!rdir)
return -ENOMEM;
while (1) {
if (rdir->tail == rdir->head) {
err = p9_client_readdir(fid, rdir->buf, buflen,
ctx->pos);
if (err <= 0)
return err;
rdir->head = 0;
rdir->tail = err;
}
while (rdir->head < rdir->tail) {
err = p9dirent_read(fid->clnt, rdir->buf + rdir->head,
rdir->tail - rdir->head,
&curdirent);
if (err < 0) {
p9_debug(P9_DEBUG_VFS, "returned %d\n", err);
return -EIO;
}
if (!dir_emit(ctx, curdirent.d_name,
strlen(curdirent.d_name),
v9fs_qid2ino(&curdirent.qid),
curdirent.d_type))
return 0;
ctx->pos = curdirent.d_off;
rdir->head += err;
}
}
}
/**
* v9fs_dir_release - close a directory
* @inode: inode of the directory
* @filp: file pointer to a directory
*
*/
int v9fs_dir_release(struct inode *inode, struct file *filp)
{
struct p9_fid *fid;
fid = filp->private_data;
p9_debug(P9_DEBUG_VFS, "inode: %p filp: %p fid: %d\n",
inode, filp, fid ? fid->fid : -1);
if (fid)
p9_client_clunk(fid);
return 0;
}
const struct file_operations v9fs_dir_operations = {
.read = generic_read_dir,
.llseek = generic_file_llseek,
.iterate = v9fs_dir_readdir,
.open = v9fs_file_open,
.release = v9fs_dir_release,
};
const struct file_operations v9fs_dir_operations_dotl = {
.read = generic_read_dir,
.llseek = generic_file_llseek,
.iterate = v9fs_dir_readdir_dotl,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.fsync = v9fs_file_fsync_dotl,
};

View File

@@ -1,726 +0,0 @@
/*
* linux/fs/9p/vfs_file.c
*
* This file contians vfs file ops for 9P2000.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/inet.h>
#include <linux/list.h>
#include <linux/pagemap.h>
#include <linux/utsname.h>
#include <asm/uaccess.h>
#include <linux/idr.h>
#include <linux/uio.h>
#include <linux/slab.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
#include "cache.h"
static const struct vm_operations_struct v9fs_file_vm_ops;
static const struct vm_operations_struct v9fs_mmap_file_vm_ops;
/**
* v9fs_file_open - open a file (or directory)
* @inode: inode to be opened
* @file: file being opened
*
*/
int v9fs_file_open(struct inode *inode, struct file *file)
{
int err;
struct v9fs_inode *v9inode;
struct v9fs_session_info *v9ses;
struct p9_fid *fid;
int omode;
p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file);
v9inode = V9FS_I(inode);
v9ses = v9fs_inode2v9ses(inode);
if (v9fs_proto_dotl(v9ses))
omode = v9fs_open_to_dotl_flags(file->f_flags);
else
omode = v9fs_uflags2omode(file->f_flags,
v9fs_proto_dotu(v9ses));
fid = file->private_data;
if (!fid) {
fid = v9fs_fid_clone(file_dentry(file));
if (IS_ERR(fid))
return PTR_ERR(fid);
err = p9_client_open(fid, omode);
if (err < 0) {
p9_client_clunk(fid);
return err;
}
if ((file->f_flags & O_APPEND) &&
(!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)))
generic_file_llseek(file, 0, SEEK_END);
}
file->private_data = fid;
mutex_lock(&v9inode->v_mutex);
if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
!v9inode->writeback_fid &&
((file->f_flags & O_ACCMODE) != O_RDONLY)) {
/*
* clone a fid and add it to writeback_fid
* we do it during open time instead of
* page dirty time via write_begin/page_mkwrite
* because we want write after unlink usecase
* to work.
*/
fid = v9fs_writeback_fid(file_dentry(file));
if (IS_ERR(fid)) {
err = PTR_ERR(fid);
mutex_unlock(&v9inode->v_mutex);
goto out_error;
}
v9inode->writeback_fid = (void *) fid;
}
mutex_unlock(&v9inode->v_mutex);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
v9fs_cache_inode_set_cookie(inode, file);
return 0;
out_error:
p9_client_clunk(file->private_data);
file->private_data = NULL;
return err;
}
/**
* v9fs_file_lock - lock a file (or directory)
* @filp: file to be locked
* @cmd: lock command
* @fl: file lock structure
*
* Bugs: this looks like a local only lock, we should extend into 9P
* by using open exclusive
*/
static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
{
int res = 0;
struct inode *inode = file_inode(filp);
p9_debug(P9_DEBUG_VFS, "filp: %p lock: %p\n", filp, fl);
/* No mandatory locks */
if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
return -ENOLCK;
if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
filemap_write_and_wait(inode->i_mapping);
invalidate_mapping_pages(&inode->i_data, 0, -1);
}
return res;
}
static int v9fs_file_do_lock(struct file *filp, int cmd, struct file_lock *fl)
{
struct p9_flock flock;
struct p9_fid *fid;
uint8_t status = P9_LOCK_ERROR;
int res = 0;
unsigned char fl_type;
struct v9fs_session_info *v9ses;
fid = filp->private_data;
BUG_ON(fid == NULL);
if ((fl->fl_flags & FL_POSIX) != FL_POSIX)
BUG();
res = locks_lock_file_wait(filp, fl);
if (res < 0)
goto out;
/* convert posix lock to p9 tlock args */
memset(&flock, 0, sizeof(flock));
/* map the lock type */
switch (fl->fl_type) {
case F_RDLCK:
flock.type = P9_LOCK_TYPE_RDLCK;
break;
case F_WRLCK:
flock.type = P9_LOCK_TYPE_WRLCK;
break;
case F_UNLCK:
flock.type = P9_LOCK_TYPE_UNLCK;
break;
}
flock.start = fl->fl_start;
if (fl->fl_end == OFFSET_MAX)
flock.length = 0;
else
flock.length = fl->fl_end - fl->fl_start + 1;
flock.proc_id = fl->fl_pid;
flock.client_id = fid->clnt->name;
if (IS_SETLKW(cmd))
flock.flags = P9_LOCK_FLAGS_BLOCK;
v9ses = v9fs_inode2v9ses(file_inode(filp));
/*
* if its a blocked request and we get P9_LOCK_BLOCKED as the status
* for lock request, keep on trying
*/
for (;;) {
res = p9_client_lock_dotl(fid, &flock, &status);
if (res < 0)
goto out_unlock;
if (status != P9_LOCK_BLOCKED)
break;
if (status == P9_LOCK_BLOCKED && !IS_SETLKW(cmd))
break;
if (schedule_timeout_interruptible(v9ses->session_lock_timeout)
!= 0)
break;
/*
* p9_client_lock_dotl overwrites flock.client_id with the
* server message, free and reuse the client name
*/
if (flock.client_id != fid->clnt->name) {
kfree(flock.client_id);
flock.client_id = fid->clnt->name;
}
}
/* map 9p status to VFS status */
switch (status) {
case P9_LOCK_SUCCESS:
res = 0;
break;
case P9_LOCK_BLOCKED:
res = -EAGAIN;
break;
default:
WARN_ONCE(1, "unknown lock status code: %d\n", status);
/* fallthough */
case P9_LOCK_ERROR:
case P9_LOCK_GRACE:
res = -ENOLCK;
break;
}
out_unlock:
/*
* incase server returned error for lock request, revert
* it locally
*/
if (res < 0 && fl->fl_type != F_UNLCK) {
fl_type = fl->fl_type;
fl->fl_type = F_UNLCK;
/* Even if this fails we want to return the remote error */
locks_lock_file_wait(filp, fl);
fl->fl_type = fl_type;
}
if (flock.client_id != fid->clnt->name)
kfree(flock.client_id);
out:
return res;
}
static int v9fs_file_getlock(struct file *filp, struct file_lock *fl)
{
struct p9_getlock glock;
struct p9_fid *fid;
int res = 0;
fid = filp->private_data;
BUG_ON(fid == NULL);
posix_test_lock(filp, fl);
/*
* if we have a conflicting lock locally, no need to validate
* with server
*/
if (fl->fl_type != F_UNLCK)
return res;
/* convert posix lock to p9 tgetlock args */
memset(&glock, 0, sizeof(glock));
glock.type = P9_LOCK_TYPE_UNLCK;
glock.start = fl->fl_start;
if (fl->fl_end == OFFSET_MAX)
glock.length = 0;
else
glock.length = fl->fl_end - fl->fl_start + 1;
glock.proc_id = fl->fl_pid;
glock.client_id = fid->clnt->name;
res = p9_client_getlock_dotl(fid, &glock);
if (res < 0)
goto out;
/* map 9p lock type to os lock type */
switch (glock.type) {
case P9_LOCK_TYPE_RDLCK:
fl->fl_type = F_RDLCK;
break;
case P9_LOCK_TYPE_WRLCK:
fl->fl_type = F_WRLCK;
break;
case P9_LOCK_TYPE_UNLCK:
fl->fl_type = F_UNLCK;
break;
}
if (glock.type != P9_LOCK_TYPE_UNLCK) {
fl->fl_start = glock.start;
if (glock.length == 0)
fl->fl_end = OFFSET_MAX;
else
fl->fl_end = glock.start + glock.length - 1;
fl->fl_pid = glock.proc_id;
}
out:
if (glock.client_id != fid->clnt->name)
kfree(glock.client_id);
return res;
}
/**
* v9fs_file_lock_dotl - lock a file (or directory)
* @filp: file to be locked
* @cmd: lock command
* @fl: file lock structure
*
*/
static int v9fs_file_lock_dotl(struct file *filp, int cmd, struct file_lock *fl)
{
struct inode *inode = file_inode(filp);
int ret = -ENOLCK;
p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n",
filp, cmd, fl, filp);
/* No mandatory locks */
if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
goto out_err;
if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
filemap_write_and_wait(inode->i_mapping);
invalidate_mapping_pages(&inode->i_data, 0, -1);
}
if (IS_SETLK(cmd) || IS_SETLKW(cmd))
ret = v9fs_file_do_lock(filp, cmd, fl);
else if (IS_GETLK(cmd))
ret = v9fs_file_getlock(filp, fl);
else
ret = -EINVAL;
out_err:
return ret;
}
/**
* v9fs_file_flock_dotl - lock a file
* @filp: file to be locked
* @cmd: lock command
* @fl: file lock structure
*
*/
static int v9fs_file_flock_dotl(struct file *filp, int cmd,
struct file_lock *fl)
{
struct inode *inode = file_inode(filp);
int ret = -ENOLCK;
p9_debug(P9_DEBUG_VFS, "filp: %p cmd:%d lock: %p name: %pD\n",
filp, cmd, fl, filp);
/* No mandatory locks */
if (__mandatory_lock(inode) && fl->fl_type != F_UNLCK)
goto out_err;
if (!(fl->fl_flags & FL_FLOCK))
goto out_err;
if ((IS_SETLK(cmd) || IS_SETLKW(cmd)) && fl->fl_type != F_UNLCK) {
filemap_write_and_wait(inode->i_mapping);
invalidate_mapping_pages(&inode->i_data, 0, -1);
}
/* Convert flock to posix lock */
fl->fl_flags |= FL_POSIX;
fl->fl_flags ^= FL_FLOCK;
if (IS_SETLK(cmd) | IS_SETLKW(cmd))
ret = v9fs_file_do_lock(filp, cmd, fl);
else
ret = -EINVAL;
out_err:
return ret;
}
/**
* v9fs_file_read - read from a file
* @filp: file pointer to read
* @udata: user data buffer to read data into
* @count: size of buffer
* @offset: offset at which to read data
*
*/
static ssize_t
v9fs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
struct p9_fid *fid = iocb->ki_filp->private_data;
int ret, err = 0;
p9_debug(P9_DEBUG_VFS, "count %zu offset %lld\n",
iov_iter_count(to), iocb->ki_pos);
ret = p9_client_read(fid, iocb->ki_pos, to, &err);
if (!ret)
return err;
iocb->ki_pos += ret;
return ret;
}
/**
* v9fs_file_write - write to a file
* @filp: file pointer to write
* @data: data buffer to write data from
* @count: size of buffer
* @offset: offset at which to write data
*
*/
static ssize_t
v9fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
struct file *file = iocb->ki_filp;
ssize_t retval;
loff_t origin;
int err = 0;
retval = generic_write_checks(iocb, from);
if (retval <= 0)
return retval;
origin = iocb->ki_pos;
retval = p9_client_write(file->private_data, iocb->ki_pos, from, &err);
if (retval > 0) {
struct inode *inode = file_inode(file);
loff_t i_size;
unsigned long pg_start, pg_end;
pg_start = origin >> PAGE_CACHE_SHIFT;
pg_end = (origin + retval - 1) >> PAGE_CACHE_SHIFT;
if (inode->i_mapping && inode->i_mapping->nrpages)
invalidate_inode_pages2_range(inode->i_mapping,
pg_start, pg_end);
iocb->ki_pos += retval;
i_size = i_size_read(inode);
if (iocb->ki_pos > i_size) {
inode_add_bytes(inode, iocb->ki_pos - i_size);
/*
* Need to serialize against i_size_write() in
* v9fs_stat2inode()
*/
v9fs_i_size_write(inode, iocb->ki_pos);
}
return retval;
}
return err;
}
static int v9fs_file_fsync(struct file *filp, loff_t start, loff_t end,
int datasync)
{
struct p9_fid *fid;
struct inode *inode = filp->f_mapping->host;
struct p9_wstat wstat;
int retval;
retval = filemap_write_and_wait_range(inode->i_mapping, start, end);
if (retval)
return retval;
mutex_lock(&inode->i_mutex);
p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
fid = filp->private_data;
v9fs_blank_wstat(&wstat);
retval = p9_client_wstat(fid, &wstat);
mutex_unlock(&inode->i_mutex);
return retval;
}
int v9fs_file_fsync_dotl(struct file *filp, loff_t start, loff_t end,
int datasync)
{
struct p9_fid *fid;
struct inode *inode = filp->f_mapping->host;
int retval;
retval = filemap_write_and_wait_range(inode->i_mapping, start, end);
if (retval)
return retval;
mutex_lock(&inode->i_mutex);
p9_debug(P9_DEBUG_VFS, "filp %p datasync %x\n", filp, datasync);
fid = filp->private_data;
retval = p9_client_fsync(fid, datasync);
mutex_unlock(&inode->i_mutex);
return retval;
}
static int
v9fs_file_mmap(struct file *filp, struct vm_area_struct *vma)
{
int retval;
retval = generic_file_mmap(filp, vma);
if (!retval)
vma->vm_ops = &v9fs_file_vm_ops;
return retval;
}
static int
v9fs_mmap_file_mmap(struct file *filp, struct vm_area_struct *vma)
{
int retval;
struct inode *inode;
struct v9fs_inode *v9inode;
struct p9_fid *fid;
inode = file_inode(filp);
v9inode = V9FS_I(inode);
mutex_lock(&v9inode->v_mutex);
if (!v9inode->writeback_fid &&
(vma->vm_flags & VM_WRITE)) {
/*
* clone a fid and add it to writeback_fid
* we do it during mmap instead of
* page dirty time via write_begin/page_mkwrite
* because we want write after unlink usecase
* to work.
*/
fid = v9fs_writeback_fid(file_dentry(filp));
if (IS_ERR(fid)) {
retval = PTR_ERR(fid);
mutex_unlock(&v9inode->v_mutex);
return retval;
}
v9inode->writeback_fid = (void *) fid;
}
mutex_unlock(&v9inode->v_mutex);
retval = generic_file_mmap(filp, vma);
if (!retval)
vma->vm_ops = &v9fs_mmap_file_vm_ops;
return retval;
}
static int
v9fs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct v9fs_inode *v9inode;
struct page *page = vmf->page;
struct file *filp = vma->vm_file;
struct inode *inode = file_inode(filp);
p9_debug(P9_DEBUG_VFS, "page %p fid %lx\n",
page, (unsigned long)filp->private_data);
/* Update file times before taking page lock */
file_update_time(filp);
v9inode = V9FS_I(inode);
/* make sure the cache has finished storing the page */
v9fs_fscache_wait_on_page_write(inode, page);
BUG_ON(!v9inode->writeback_fid);
lock_page(page);
if (page->mapping != inode->i_mapping)
goto out_unlock;
wait_for_stable_page(page);
return VM_FAULT_LOCKED;
out_unlock:
unlock_page(page);
return VM_FAULT_NOPAGE;
}
/**
* v9fs_mmap_file_read - read from a file
* @filp: file pointer to read
* @data: user data buffer to read data into
* @count: size of buffer
* @offset: offset at which to read data
*
*/
static ssize_t
v9fs_mmap_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
{
/* TODO: Check if there are dirty pages */
return v9fs_file_read_iter(iocb, to);
}
/**
* v9fs_mmap_file_write - write to a file
* @filp: file pointer to write
* @data: data buffer to write data from
* @count: size of buffer
* @offset: offset at which to write data
*
*/
static ssize_t
v9fs_mmap_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
{
/*
* TODO: invalidate mmaps on filp's inode between
* offset and offset+count
*/
return v9fs_file_write_iter(iocb, from);
}
static void v9fs_mmap_vm_close(struct vm_area_struct *vma)
{
struct inode *inode;
struct writeback_control wbc = {
.nr_to_write = LONG_MAX,
.sync_mode = WB_SYNC_ALL,
.range_start = vma->vm_pgoff * PAGE_SIZE,
/* absolute end, byte at end included */
.range_end = vma->vm_pgoff * PAGE_SIZE +
(vma->vm_end - vma->vm_start - 1),
};
p9_debug(P9_DEBUG_VFS, "9p VMA close, %p, flushing", vma);
inode = file_inode(vma->vm_file);
if (!mapping_cap_writeback_dirty(inode->i_mapping))
wbc.nr_to_write = 0;
might_sleep();
sync_inode(inode, &wbc);
}
static const struct vm_operations_struct v9fs_file_vm_ops = {
.fault = filemap_fault,
.map_pages = filemap_map_pages,
.page_mkwrite = v9fs_vm_page_mkwrite,
};
static const struct vm_operations_struct v9fs_mmap_file_vm_ops = {
.close = v9fs_mmap_vm_close,
.fault = filemap_fault,
.map_pages = filemap_map_pages,
.page_mkwrite = v9fs_vm_page_mkwrite,
};
const struct file_operations v9fs_cached_file_operations = {
.llseek = generic_file_llseek,
.read_iter = generic_file_read_iter,
.write_iter = generic_file_write_iter,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.lock = v9fs_file_lock,
.mmap = v9fs_file_mmap,
.fsync = v9fs_file_fsync,
};
const struct file_operations v9fs_cached_file_operations_dotl = {
.llseek = generic_file_llseek,
.read_iter = generic_file_read_iter,
.write_iter = generic_file_write_iter,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.lock = v9fs_file_lock_dotl,
.flock = v9fs_file_flock_dotl,
.mmap = v9fs_file_mmap,
.fsync = v9fs_file_fsync_dotl,
};
const struct file_operations v9fs_file_operations = {
.llseek = generic_file_llseek,
.read_iter = v9fs_file_read_iter,
.write_iter = v9fs_file_write_iter,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.lock = v9fs_file_lock,
.mmap = generic_file_readonly_mmap,
.fsync = v9fs_file_fsync,
};
const struct file_operations v9fs_file_operations_dotl = {
.llseek = generic_file_llseek,
.read_iter = v9fs_file_read_iter,
.write_iter = v9fs_file_write_iter,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.lock = v9fs_file_lock_dotl,
.flock = v9fs_file_flock_dotl,
.mmap = generic_file_readonly_mmap,
.fsync = v9fs_file_fsync_dotl,
};
const struct file_operations v9fs_mmap_file_operations = {
.llseek = generic_file_llseek,
.read_iter = v9fs_mmap_file_read_iter,
.write_iter = v9fs_mmap_file_write_iter,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.lock = v9fs_file_lock,
.mmap = v9fs_mmap_file_mmap,
.fsync = v9fs_file_fsync,
};
const struct file_operations v9fs_mmap_file_operations_dotl = {
.llseek = generic_file_llseek,
.read_iter = v9fs_mmap_file_read_iter,
.write_iter = v9fs_mmap_file_write_iter,
.open = v9fs_file_open,
.release = v9fs_dir_release,
.lock = v9fs_file_lock_dotl,
.flock = v9fs_file_flock_dotl,
.mmap = v9fs_mmap_file_mmap,
.fsync = v9fs_file_fsync_dotl,
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,999 +0,0 @@
/*
* linux/fs/9p/vfs_inode_dotl.c
*
* This file contains vfs inode ops for the 9P2000.L protocol.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/pagemap.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/inet.h>
#include <linux/namei.h>
#include <linux/idr.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/xattr.h>
#include <linux/posix_acl.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
#include "cache.h"
#include "xattr.h"
#include "acl.h"
static int
v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
dev_t rdev);
/**
* v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
* new file system object. This checks the S_ISGID to determine the owning
* group of the new file system object.
*/
static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
{
BUG_ON(dir_inode == NULL);
if (dir_inode->i_mode & S_ISGID) {
/* set_gid bit is set.*/
return dir_inode->i_gid;
}
return current_fsgid();
}
static int v9fs_test_inode_dotl(struct inode *inode, void *data)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
/* don't match inode of different type */
if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
return 0;
if (inode->i_generation != st->st_gen)
return 0;
/* compare qid details */
if (memcmp(&v9inode->qid.version,
&st->qid.version, sizeof(v9inode->qid.version)))
return 0;
if (v9inode->qid.type != st->qid.type)
return 0;
if (v9inode->qid.path != st->qid.path)
return 0;
return 1;
}
/* Always get a new inode */
static int v9fs_test_new_inode_dotl(struct inode *inode, void *data)
{
return 0;
}
static int v9fs_set_inode_dotl(struct inode *inode, void *data)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
inode->i_generation = st->st_gen;
return 0;
}
static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
struct p9_qid *qid,
struct p9_fid *fid,
struct p9_stat_dotl *st,
int new)
{
int retval;
unsigned long i_ino;
struct inode *inode;
struct v9fs_session_info *v9ses = sb->s_fs_info;
int (*test)(struct inode *, void *);
if (new)
test = v9fs_test_new_inode_dotl;
else
test = v9fs_test_inode_dotl;
i_ino = v9fs_qid2ino(qid);
inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st);
if (!inode)
return ERR_PTR(-ENOMEM);
if (!(inode->i_state & I_NEW))
return inode;
/*
* initialize the inode with the stat info
* FIXME!! we may need support for stale inodes
* later.
*/
inode->i_ino = i_ino;
retval = v9fs_init_inode(v9ses, inode,
st->st_mode, new_decode_dev(st->st_rdev));
if (retval)
goto error;
v9fs_stat2inode_dotl(st, inode, 0);
v9fs_cache_inode_get_cookie(inode);
retval = v9fs_get_acl(inode, fid);
if (retval)
goto error;
unlock_new_inode(inode);
return inode;
error:
iget_failed(inode);
return ERR_PTR(retval);
}
struct inode *
v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb, int new)
{
struct p9_stat_dotl *st;
struct inode *inode = NULL;
st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
if (IS_ERR(st))
return ERR_CAST(st);
inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new);
kfree(st);
return inode;
}
struct dotl_openflag_map {
int open_flag;
int dotl_flag;
};
static int v9fs_mapped_dotl_flags(int flags)
{
int i;
int rflags = 0;
struct dotl_openflag_map dotl_oflag_map[] = {
{ O_CREAT, P9_DOTL_CREATE },
{ O_EXCL, P9_DOTL_EXCL },
{ O_NOCTTY, P9_DOTL_NOCTTY },
{ O_APPEND, P9_DOTL_APPEND },
{ O_NONBLOCK, P9_DOTL_NONBLOCK },
{ O_DSYNC, P9_DOTL_DSYNC },
{ FASYNC, P9_DOTL_FASYNC },
{ O_DIRECT, P9_DOTL_DIRECT },
{ O_LARGEFILE, P9_DOTL_LARGEFILE },
{ O_DIRECTORY, P9_DOTL_DIRECTORY },
{ O_NOFOLLOW, P9_DOTL_NOFOLLOW },
{ O_NOATIME, P9_DOTL_NOATIME },
{ O_CLOEXEC, P9_DOTL_CLOEXEC },
{ O_SYNC, P9_DOTL_SYNC},
};
for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) {
if (flags & dotl_oflag_map[i].open_flag)
rflags |= dotl_oflag_map[i].dotl_flag;
}
return rflags;
}
/**
* v9fs_open_to_dotl_flags- convert Linux specific open flags to
* plan 9 open flag.
* @flags: flags to convert
*/
int v9fs_open_to_dotl_flags(int flags)
{
int rflags = 0;
/*
* We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY
* and P9_DOTL_NOACCESS
*/
rflags |= flags & O_ACCMODE;
rflags |= v9fs_mapped_dotl_flags(flags);
return rflags;
}
/**
* v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
* @dir: directory inode that is being created
* @dentry: dentry that is being deleted
* @omode: create permissions
*
*/
static int
v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
bool excl)
{
return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
}
static int
v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
struct file *file, unsigned flags, umode_t omode,
int *opened)
{
int err = 0;
kgid_t gid;
umode_t mode;
char *name = NULL;
struct p9_qid qid;
struct inode *inode;
struct p9_fid *fid = NULL;
struct v9fs_inode *v9inode;
struct p9_fid *dfid, *ofid, *inode_fid;
struct v9fs_session_info *v9ses;
struct posix_acl *pacl = NULL, *dacl = NULL;
struct dentry *res = NULL;
if (d_unhashed(dentry)) {
res = v9fs_vfs_lookup(dir, dentry, 0);
if (IS_ERR(res))
return PTR_ERR(res);
if (res)
dentry = res;
}
/* Only creates */
if (!(flags & O_CREAT) || d_really_is_positive(dentry))
return finish_no_open(file, res);
v9ses = v9fs_inode2v9ses(dir);
name = (char *) dentry->d_name.name;
p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%hx\n",
name, flags, omode);
dfid = v9fs_fid_lookup(dentry->d_parent);
if (IS_ERR(dfid)) {
err = PTR_ERR(dfid);
p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
goto out;
}
/* clone a fid to use for creation */
ofid = p9_client_walk(dfid, 0, NULL, 1);
if (IS_ERR(ofid)) {
err = PTR_ERR(ofid);
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
goto out;
}
gid = v9fs_get_fsgid_for_create(dir);
mode = omode;
/* Update mode based on ACL value */
err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
if (err) {
p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d\n",
err);
goto error;
}
err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags),
mode, gid, &qid);
if (err < 0) {
p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d\n",
err);
goto error;
}
v9fs_invalidate_inode_attr(dir);
/* instantiate inode and assign the unopened fid to the dentry */
fid = p9_client_walk(dfid, 1, &name, 1);
if (IS_ERR(fid)) {
err = PTR_ERR(fid);
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
fid = NULL;
goto error;
}
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err);
goto error;
}
/* Now set the ACL based on the default value */
v9fs_set_create_acl(inode, fid, dacl, pacl);
v9fs_fid_add(dentry, fid);
d_instantiate(dentry, inode);
v9inode = V9FS_I(inode);
mutex_lock(&v9inode->v_mutex);
if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
!v9inode->writeback_fid &&
((flags & O_ACCMODE) != O_RDONLY)) {
/*
* clone a fid and add it to writeback_fid
* we do it during open time instead of
* page dirty time via write_begin/page_mkwrite
* because we want write after unlink usecase
* to work.
*/
inode_fid = v9fs_writeback_fid(dentry);
if (IS_ERR(inode_fid)) {
err = PTR_ERR(inode_fid);
mutex_unlock(&v9inode->v_mutex);
goto err_clunk_old_fid;
}
v9inode->writeback_fid = (void *) inode_fid;
}
mutex_unlock(&v9inode->v_mutex);
/* Since we are opening a file, assign the open fid to the file */
err = finish_open(file, dentry, generic_file_open, opened);
if (err)
goto err_clunk_old_fid;
file->private_data = ofid;
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
v9fs_cache_inode_set_cookie(inode, file);
*opened |= FILE_CREATED;
out:
v9fs_put_acl(dacl, pacl);
dput(res);
return err;
error:
if (fid)
p9_client_clunk(fid);
err_clunk_old_fid:
if (ofid)
p9_client_clunk(ofid);
goto out;
}
/**
* v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
* @dir: inode that is being unlinked
* @dentry: dentry that is being unlinked
* @omode: mode for new directory
*
*/
static int v9fs_vfs_mkdir_dotl(struct inode *dir,
struct dentry *dentry, umode_t omode)
{
int err;
struct v9fs_session_info *v9ses;
struct p9_fid *fid = NULL, *dfid = NULL;
kgid_t gid;
char *name;
umode_t mode;
struct inode *inode;
struct p9_qid qid;
struct dentry *dir_dentry;
struct posix_acl *dacl = NULL, *pacl = NULL;
p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry);
err = 0;
v9ses = v9fs_inode2v9ses(dir);
omode |= S_IFDIR;
if (dir->i_mode & S_ISGID)
omode |= S_ISGID;
dir_dentry = dentry->d_parent;
dfid = v9fs_fid_lookup(dir_dentry);
if (IS_ERR(dfid)) {
err = PTR_ERR(dfid);
p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
dfid = NULL;
goto error;
}
gid = v9fs_get_fsgid_for_create(dir);
mode = omode;
/* Update mode based on ACL value */
err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
if (err) {
p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mkdir %d\n",
err);
goto error;
}
name = (char *) dentry->d_name.name;
err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
if (err < 0)
goto error;
fid = p9_client_walk(dfid, 1, &name, 1);
if (IS_ERR(fid)) {
err = PTR_ERR(fid);
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
err);
fid = NULL;
goto error;
}
/* instantiate inode and assign the unopened fid to the dentry */
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
err);
goto error;
}
v9fs_fid_add(dentry, fid);
v9fs_set_create_acl(inode, fid, dacl, pacl);
d_instantiate(dentry, inode);
fid = NULL;
err = 0;
} else {
/*
* Not in cached mode. No need to populate
* inode with stat. We need to get an inode
* so that we can set the acl with dentry
*/
inode = v9fs_get_inode(dir->i_sb, mode, 0);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
goto error;
}
v9fs_set_create_acl(inode, fid, dacl, pacl);
d_instantiate(dentry, inode);
}
inc_nlink(dir);
v9fs_invalidate_inode_attr(dir);
error:
if (fid)
p9_client_clunk(fid);
v9fs_put_acl(dacl, pacl);
return err;
}
static int
v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
struct v9fs_session_info *v9ses;
struct p9_fid *fid;
struct p9_stat_dotl *st;
p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
v9ses = v9fs_dentry2v9ses(dentry);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
generic_fillattr(d_inode(dentry), stat);
return 0;
}
fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid))
return PTR_ERR(fid);
/* Ask for all the fields in stat structure. Server will return
* whatever it supports
*/
st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
if (IS_ERR(st))
return PTR_ERR(st);
v9fs_stat2inode_dotl(st, d_inode(dentry), 0);
generic_fillattr(d_inode(dentry), stat);
/* Change block size to what the server returned */
stat->blksize = st->st_blksize;
kfree(st);
return 0;
}
/*
* Attribute flags.
*/
#define P9_ATTR_MODE (1 << 0)
#define P9_ATTR_UID (1 << 1)
#define P9_ATTR_GID (1 << 2)
#define P9_ATTR_SIZE (1 << 3)
#define P9_ATTR_ATIME (1 << 4)
#define P9_ATTR_MTIME (1 << 5)
#define P9_ATTR_CTIME (1 << 6)
#define P9_ATTR_ATIME_SET (1 << 7)
#define P9_ATTR_MTIME_SET (1 << 8)
struct dotl_iattr_map {
int iattr_valid;
int p9_iattr_valid;
};
static int v9fs_mapped_iattr_valid(int iattr_valid)
{
int i;
int p9_iattr_valid = 0;
struct dotl_iattr_map dotl_iattr_map[] = {
{ ATTR_MODE, P9_ATTR_MODE },
{ ATTR_UID, P9_ATTR_UID },
{ ATTR_GID, P9_ATTR_GID },
{ ATTR_SIZE, P9_ATTR_SIZE },
{ ATTR_ATIME, P9_ATTR_ATIME },
{ ATTR_MTIME, P9_ATTR_MTIME },
{ ATTR_CTIME, P9_ATTR_CTIME },
{ ATTR_ATIME_SET, P9_ATTR_ATIME_SET },
{ ATTR_MTIME_SET, P9_ATTR_MTIME_SET },
};
for (i = 0; i < ARRAY_SIZE(dotl_iattr_map); i++) {
if (iattr_valid & dotl_iattr_map[i].iattr_valid)
p9_iattr_valid |= dotl_iattr_map[i].p9_iattr_valid;
}
return p9_iattr_valid;
}
/**
* v9fs_vfs_setattr_dotl - set file metadata
* @dentry: file whose metadata to set
* @iattr: metadata assignment structure
*
*/
int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
{
int retval;
struct p9_fid *fid;
struct p9_iattr_dotl p9attr;
struct inode *inode = d_inode(dentry);
p9_debug(P9_DEBUG_VFS, "\n");
retval = inode_change_ok(inode, iattr);
if (retval)
return retval;
p9attr.valid = v9fs_mapped_iattr_valid(iattr->ia_valid);
p9attr.mode = iattr->ia_mode;
p9attr.uid = iattr->ia_uid;
p9attr.gid = iattr->ia_gid;
p9attr.size = iattr->ia_size;
p9attr.atime_sec = iattr->ia_atime.tv_sec;
p9attr.atime_nsec = iattr->ia_atime.tv_nsec;
p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid))
return PTR_ERR(fid);
/* Write all dirty data */
if (S_ISREG(inode->i_mode))
filemap_write_and_wait(inode->i_mapping);
retval = p9_client_setattr(fid, &p9attr);
if (retval < 0)
return retval;
if ((iattr->ia_valid & ATTR_SIZE) &&
iattr->ia_size != i_size_read(inode))
truncate_setsize(inode, iattr->ia_size);
v9fs_invalidate_inode_attr(inode);
setattr_copy(inode, iattr);
mark_inode_dirty(inode);
if (iattr->ia_valid & ATTR_MODE) {
/* We also want to update ACL when we update mode bits */
retval = v9fs_acl_chmod(inode, fid);
if (retval < 0)
return retval;
}
return 0;
}
/**
* v9fs_stat2inode_dotl - populate an inode structure with stat info
* @stat: stat structure
* @inode: inode to populate
* @flags: ctrl flags (e.g. V9FS_STAT2INODE_KEEP_ISIZE)
*
*/
void
v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode,
unsigned int flags)
{
umode_t mode;
struct v9fs_inode *v9inode = V9FS_I(inode);
if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
inode->i_atime.tv_sec = stat->st_atime_sec;
inode->i_atime.tv_nsec = stat->st_atime_nsec;
inode->i_mtime.tv_sec = stat->st_mtime_sec;
inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
inode->i_ctime.tv_sec = stat->st_ctime_sec;
inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
inode->i_uid = stat->st_uid;
inode->i_gid = stat->st_gid;
set_nlink(inode, stat->st_nlink);
mode = stat->st_mode & S_IALLUGO;
mode |= inode->i_mode & ~S_IALLUGO;
inode->i_mode = mode;
if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE))
v9fs_i_size_write(inode, stat->st_size);
inode->i_blocks = stat->st_blocks;
} else {
if (stat->st_result_mask & P9_STATS_ATIME) {
inode->i_atime.tv_sec = stat->st_atime_sec;
inode->i_atime.tv_nsec = stat->st_atime_nsec;
}
if (stat->st_result_mask & P9_STATS_MTIME) {
inode->i_mtime.tv_sec = stat->st_mtime_sec;
inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
}
if (stat->st_result_mask & P9_STATS_CTIME) {
inode->i_ctime.tv_sec = stat->st_ctime_sec;
inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
}
if (stat->st_result_mask & P9_STATS_UID)
inode->i_uid = stat->st_uid;
if (stat->st_result_mask & P9_STATS_GID)
inode->i_gid = stat->st_gid;
if (stat->st_result_mask & P9_STATS_NLINK)
set_nlink(inode, stat->st_nlink);
if (stat->st_result_mask & P9_STATS_MODE) {
inode->i_mode = stat->st_mode;
if ((S_ISBLK(inode->i_mode)) ||
(S_ISCHR(inode->i_mode)))
init_special_inode(inode, inode->i_mode,
inode->i_rdev);
}
if (stat->st_result_mask & P9_STATS_RDEV)
inode->i_rdev = new_decode_dev(stat->st_rdev);
if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE) &&
stat->st_result_mask & P9_STATS_SIZE)
v9fs_i_size_write(inode, stat->st_size);
if (stat->st_result_mask & P9_STATS_BLOCKS)
inode->i_blocks = stat->st_blocks;
}
if (stat->st_result_mask & P9_STATS_GEN)
inode->i_generation = stat->st_gen;
/* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
* because the inode structure does not have fields for them.
*/
v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
}
static int
v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
const char *symname)
{
int err;
kgid_t gid;
char *name;
struct p9_qid qid;
struct inode *inode;
struct p9_fid *dfid;
struct p9_fid *fid = NULL;
struct v9fs_session_info *v9ses;
name = (char *) dentry->d_name.name;
p9_debug(P9_DEBUG_VFS, "%lu,%s,%s\n", dir->i_ino, name, symname);
v9ses = v9fs_inode2v9ses(dir);
dfid = v9fs_fid_lookup(dentry->d_parent);
if (IS_ERR(dfid)) {
err = PTR_ERR(dfid);
p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
return err;
}
gid = v9fs_get_fsgid_for_create(dir);
/* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
err = p9_client_symlink(dfid, name, (char *)symname, gid, &qid);
if (err < 0) {
p9_debug(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err);
goto error;
}
v9fs_invalidate_inode_attr(dir);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
/* Now walk from the parent so we can get an unopened fid. */
fid = p9_client_walk(dfid, 1, &name, 1);
if (IS_ERR(fid)) {
err = PTR_ERR(fid);
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
err);
fid = NULL;
goto error;
}
/* instantiate inode and assign the unopened fid to dentry */
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
err);
goto error;
}
v9fs_fid_add(dentry, fid);
d_instantiate(dentry, inode);
fid = NULL;
err = 0;
} else {
/* Not in cached mode. No need to populate inode with stat */
inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
goto error;
}
d_instantiate(dentry, inode);
}
error:
if (fid)
p9_client_clunk(fid);
return err;
}
/**
* v9fs_vfs_link_dotl - create a hardlink for dotl
* @old_dentry: dentry for file to link to
* @dir: inode destination for new link
* @dentry: dentry for link
*
*/
static int
v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
struct dentry *dentry)
{
int err;
struct dentry *dir_dentry;
struct p9_fid *dfid, *oldfid;
struct v9fs_session_info *v9ses;
p9_debug(P9_DEBUG_VFS, "dir ino: %lu, old_name: %pd, new_name: %pd\n",
dir->i_ino, old_dentry, dentry);
v9ses = v9fs_inode2v9ses(dir);
dir_dentry = dentry->d_parent;
dfid = v9fs_fid_lookup(dir_dentry);
if (IS_ERR(dfid))
return PTR_ERR(dfid);
oldfid = v9fs_fid_lookup(old_dentry);
if (IS_ERR(oldfid))
return PTR_ERR(oldfid);
err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name);
if (err < 0) {
p9_debug(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
return err;
}
v9fs_invalidate_inode_attr(dir);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
/* Get the latest stat info from server. */
struct p9_fid *fid;
fid = v9fs_fid_lookup(old_dentry);
if (IS_ERR(fid))
return PTR_ERR(fid);
v9fs_refresh_inode_dotl(fid, d_inode(old_dentry));
}
ihold(d_inode(old_dentry));
d_instantiate(dentry, d_inode(old_dentry));
return err;
}
/**
* v9fs_vfs_mknod_dotl - create a special file
* @dir: inode destination for new link
* @dentry: dentry for file
* @omode: mode for creation
* @rdev: device associated with special file
*
*/
static int
v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
dev_t rdev)
{
int err;
kgid_t gid;
char *name;
umode_t mode;
struct v9fs_session_info *v9ses;
struct p9_fid *fid = NULL, *dfid = NULL;
struct inode *inode;
struct p9_qid qid;
struct dentry *dir_dentry;
struct posix_acl *dacl = NULL, *pacl = NULL;
p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %hx MAJOR: %u MINOR: %u\n",
dir->i_ino, dentry, omode,
MAJOR(rdev), MINOR(rdev));
v9ses = v9fs_inode2v9ses(dir);
dir_dentry = dentry->d_parent;
dfid = v9fs_fid_lookup(dir_dentry);
if (IS_ERR(dfid)) {
err = PTR_ERR(dfid);
p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
dfid = NULL;
goto error;
}
gid = v9fs_get_fsgid_for_create(dir);
mode = omode;
/* Update mode based on ACL value */
err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
if (err) {
p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mknod %d\n",
err);
goto error;
}
name = (char *) dentry->d_name.name;
err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
if (err < 0)
goto error;
v9fs_invalidate_inode_attr(dir);
fid = p9_client_walk(dfid, 1, &name, 1);
if (IS_ERR(fid)) {
err = PTR_ERR(fid);
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
err);
fid = NULL;
goto error;
}
/* instantiate inode and assign the unopened fid to the dentry */
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
err);
goto error;
}
v9fs_set_create_acl(inode, fid, dacl, pacl);
v9fs_fid_add(dentry, fid);
d_instantiate(dentry, inode);
fid = NULL;
err = 0;
} else {
/*
* Not in cached mode. No need to populate inode with stat.
* socket syscall returns a fd, so we need instantiate
*/
inode = v9fs_get_inode(dir->i_sb, mode, rdev);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
goto error;
}
v9fs_set_create_acl(inode, fid, dacl, pacl);
d_instantiate(dentry, inode);
}
error:
if (fid)
p9_client_clunk(fid);
v9fs_put_acl(dacl, pacl);
return err;
}
/**
* v9fs_vfs_follow_link_dotl - follow a symlink path
* @dentry: dentry for symlink
* @cookie: place to pass the data to put_link()
*/
static const char *
v9fs_vfs_follow_link_dotl(struct dentry *dentry, void **cookie)
{
struct p9_fid *fid = v9fs_fid_lookup(dentry);
char *target;
int retval;
p9_debug(P9_DEBUG_VFS, "%pd\n", dentry);
if (IS_ERR(fid))
return ERR_CAST(fid);
retval = p9_client_readlink(fid, &target);
if (retval)
return ERR_PTR(retval);
return *cookie = target;
}
int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
{
struct p9_stat_dotl *st;
struct v9fs_session_info *v9ses;
unsigned int flags;
v9ses = v9fs_inode2v9ses(inode);
st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
if (IS_ERR(st))
return PTR_ERR(st);
/*
* Don't update inode if the file type is different
*/
if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
goto out;
/*
* We don't want to refresh inode->i_size,
* because we may have cached data
*/
flags = (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) ?
V9FS_STAT2INODE_KEEP_ISIZE : 0;
v9fs_stat2inode_dotl(st, inode, flags);
out:
kfree(st);
return 0;
}
const struct inode_operations v9fs_dir_inode_operations_dotl = {
.create = v9fs_vfs_create_dotl,
.atomic_open = v9fs_vfs_atomic_open_dotl,
.lookup = v9fs_vfs_lookup,
.link = v9fs_vfs_link_dotl,
.symlink = v9fs_vfs_symlink_dotl,
.unlink = v9fs_vfs_unlink,
.mkdir = v9fs_vfs_mkdir_dotl,
.rmdir = v9fs_vfs_rmdir,
.mknod = v9fs_vfs_mknod_dotl,
.rename = v9fs_vfs_rename,
.getattr = v9fs_vfs_getattr_dotl,
.setattr = v9fs_vfs_setattr_dotl,
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,
.removexattr = generic_removexattr,
.listxattr = v9fs_listxattr,
.get_acl = v9fs_iop_get_acl,
};
const struct inode_operations v9fs_file_inode_operations_dotl = {
.getattr = v9fs_vfs_getattr_dotl,
.setattr = v9fs_vfs_setattr_dotl,
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,
.removexattr = generic_removexattr,
.listxattr = v9fs_listxattr,
.get_acl = v9fs_iop_get_acl,
};
const struct inode_operations v9fs_symlink_inode_operations_dotl = {
.readlink = generic_readlink,
.follow_link = v9fs_vfs_follow_link_dotl,
.put_link = kfree_put_link,
.getattr = v9fs_vfs_getattr_dotl,
.setattr = v9fs_vfs_setattr_dotl,
.setxattr = generic_setxattr,
.getxattr = generic_getxattr,
.removexattr = generic_removexattr,
.listxattr = v9fs_listxattr,
};

View File

@@ -1,366 +0,0 @@
/*
* linux/fs/9p/vfs_super.c
*
* This file contians superblock ops for 9P2000. It is intended that
* you mount this file system on directories.
*
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/inet.h>
#include <linux/pagemap.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
#include <linux/idr.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/statfs.h>
#include <linux/magic.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
#include "fid.h"
#include "xattr.h"
#include "acl.h"
static const struct super_operations v9fs_super_ops, v9fs_super_ops_dotl;
/**
* v9fs_set_super - set the superblock
* @s: super block
* @data: file system specific data
*
*/
static int v9fs_set_super(struct super_block *s, void *data)
{
s->s_fs_info = data;
return set_anon_super(s, data);
}
/**
* v9fs_fill_super - populate superblock with info
* @sb: superblock
* @v9ses: session information
* @flags: flags propagated from v9fs_mount()
*
*/
static void
v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
int flags, void *data)
{
sb->s_maxbytes = MAX_LFS_FILESIZE;
sb->s_blocksize_bits = fls(v9ses->maxdata - 1);
sb->s_blocksize = 1 << sb->s_blocksize_bits;
sb->s_magic = V9FS_MAGIC;
if (v9fs_proto_dotl(v9ses)) {
sb->s_op = &v9fs_super_ops_dotl;
sb->s_xattr = v9fs_xattr_handlers;
} else
sb->s_op = &v9fs_super_ops;
sb->s_bdi = &v9ses->bdi;
if (v9ses->cache)
sb->s_bdi->ra_pages = (VM_MAX_READAHEAD * 1024)/PAGE_CACHE_SIZE;
sb->s_flags |= MS_ACTIVE | MS_DIRSYNC | MS_NOATIME;
if (!v9ses->cache)
sb->s_flags |= MS_SYNCHRONOUS;
#ifdef CONFIG_9P_FS_POSIX_ACL
if ((v9ses->flags & V9FS_ACL_MASK) == V9FS_POSIX_ACL)
sb->s_flags |= MS_POSIXACL;
#endif
save_mount_options(sb, data);
}
/**
* v9fs_mount - mount a superblock
* @fs_type: file system type
* @flags: mount flags
* @dev_name: device name that was mounted
* @data: mount options
*
*/
static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data)
{
struct super_block *sb = NULL;
struct inode *inode = NULL;
struct dentry *root = NULL;
struct v9fs_session_info *v9ses = NULL;
umode_t mode = S_IRWXUGO | S_ISVTX;
struct p9_fid *fid;
int retval = 0;
p9_debug(P9_DEBUG_VFS, "\n");
v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL);
if (!v9ses)
return ERR_PTR(-ENOMEM);
fid = v9fs_session_init(v9ses, dev_name, data);
if (IS_ERR(fid)) {
retval = PTR_ERR(fid);
goto free_session;
}
sb = sget(fs_type, NULL, v9fs_set_super, flags, v9ses);
if (IS_ERR(sb)) {
retval = PTR_ERR(sb);
goto clunk_fid;
}
v9fs_fill_super(sb, v9ses, flags, data);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
sb->s_d_op = &v9fs_cached_dentry_operations;
else
sb->s_d_op = &v9fs_dentry_operations;
inode = v9fs_get_inode(sb, S_IFDIR | mode, 0);
if (IS_ERR(inode)) {
retval = PTR_ERR(inode);
goto release_sb;
}
root = d_make_root(inode);
if (!root) {
retval = -ENOMEM;
goto release_sb;
}
sb->s_root = root;
if (v9fs_proto_dotl(v9ses)) {
struct p9_stat_dotl *st = NULL;
st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
if (IS_ERR(st)) {
retval = PTR_ERR(st);
goto release_sb;
}
d_inode(root)->i_ino = v9fs_qid2ino(&st->qid);
v9fs_stat2inode_dotl(st, d_inode(root), 0);
kfree(st);
} else {
struct p9_wstat *st = NULL;
st = p9_client_stat(fid);
if (IS_ERR(st)) {
retval = PTR_ERR(st);
goto release_sb;
}
d_inode(root)->i_ino = v9fs_qid2ino(&st->qid);
v9fs_stat2inode(st, d_inode(root), sb, 0);
p9stat_free(st);
kfree(st);
}
retval = v9fs_get_acl(inode, fid);
if (retval)
goto release_sb;
v9fs_fid_add(root, fid);
p9_debug(P9_DEBUG_VFS, " simple set mount, return 0\n");
return dget(sb->s_root);
clunk_fid:
p9_client_clunk(fid);
v9fs_session_close(v9ses);
free_session:
kfree(v9ses);
return ERR_PTR(retval);
release_sb:
/*
* we will do the session_close and root dentry release
* in the below call. But we need to clunk fid, because we haven't
* attached the fid to dentry so it won't get clunked
* automatically.
*/
p9_client_clunk(fid);
deactivate_locked_super(sb);
return ERR_PTR(retval);
}
/**
* v9fs_kill_super - Kill Superblock
* @s: superblock
*
*/
static void v9fs_kill_super(struct super_block *s)
{
struct v9fs_session_info *v9ses = s->s_fs_info;
p9_debug(P9_DEBUG_VFS, " %p\n", s);
kill_anon_super(s);
v9fs_session_cancel(v9ses);
v9fs_session_close(v9ses);
kfree(v9ses);
s->s_fs_info = NULL;
p9_debug(P9_DEBUG_VFS, "exiting kill_super\n");
}
static void
v9fs_umount_begin(struct super_block *sb)
{
struct v9fs_session_info *v9ses;
v9ses = sb->s_fs_info;
v9fs_session_begin_cancel(v9ses);
}
static int v9fs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
struct v9fs_session_info *v9ses;
struct p9_fid *fid;
struct p9_rstatfs rs;
int res;
fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid)) {
res = PTR_ERR(fid);
goto done;
}
v9ses = v9fs_dentry2v9ses(dentry);
if (v9fs_proto_dotl(v9ses)) {
res = p9_client_statfs(fid, &rs);
if (res == 0) {
buf->f_type = rs.type;
buf->f_bsize = rs.bsize;
buf->f_blocks = rs.blocks;
buf->f_bfree = rs.bfree;
buf->f_bavail = rs.bavail;
buf->f_files = rs.files;
buf->f_ffree = rs.ffree;
buf->f_fsid.val[0] = rs.fsid & 0xFFFFFFFFUL;
buf->f_fsid.val[1] = (rs.fsid >> 32) & 0xFFFFFFFFUL;
buf->f_namelen = rs.namelen;
}
if (res != -ENOSYS)
goto done;
}
res = simple_statfs(dentry, buf);
done:
return res;
}
static int v9fs_drop_inode(struct inode *inode)
{
struct v9fs_session_info *v9ses;
v9ses = v9fs_inode2v9ses(inode);
if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
return generic_drop_inode(inode);
/*
* in case of non cached mode always drop the
* the inode because we want the inode attribute
* to always match that on the server.
*/
return 1;
}
static int v9fs_write_inode(struct inode *inode,
struct writeback_control *wbc)
{
int ret;
struct p9_wstat wstat;
struct v9fs_inode *v9inode;
/*
* send an fsync request to server irrespective of
* wbc->sync_mode.
*/
p9_debug(P9_DEBUG_VFS, "%s: inode %p\n", __func__, inode);
v9inode = V9FS_I(inode);
if (!v9inode->writeback_fid)
return 0;
v9fs_blank_wstat(&wstat);
ret = p9_client_wstat(v9inode->writeback_fid, &wstat);
if (ret < 0) {
__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
return ret;
}
return 0;
}
static int v9fs_write_inode_dotl(struct inode *inode,
struct writeback_control *wbc)
{
int ret;
struct v9fs_inode *v9inode;
/*
* send an fsync request to server irrespective of
* wbc->sync_mode.
*/
v9inode = V9FS_I(inode);
p9_debug(P9_DEBUG_VFS, "%s: inode %p, writeback_fid %p\n",
__func__, inode, v9inode->writeback_fid);
if (!v9inode->writeback_fid)
return 0;
ret = p9_client_fsync(v9inode->writeback_fid, 0);
if (ret < 0) {
__mark_inode_dirty(inode, I_DIRTY_DATASYNC);
return ret;
}
return 0;
}
static const struct super_operations v9fs_super_ops = {
.alloc_inode = v9fs_alloc_inode,
.destroy_inode = v9fs_destroy_inode,
.statfs = simple_statfs,
.evict_inode = v9fs_evict_inode,
.show_options = generic_show_options,
.umount_begin = v9fs_umount_begin,
.write_inode = v9fs_write_inode,
};
static const struct super_operations v9fs_super_ops_dotl = {
.alloc_inode = v9fs_alloc_inode,
.destroy_inode = v9fs_destroy_inode,
.statfs = v9fs_statfs,
.drop_inode = v9fs_drop_inode,
.evict_inode = v9fs_evict_inode,
.show_options = generic_show_options,
.umount_begin = v9fs_umount_begin,
.write_inode = v9fs_write_inode_dotl,
};
struct file_system_type v9fs_fs_type = {
.name = "9p",
.mount = v9fs_mount,
.kill_sb = v9fs_kill_super,
.owner = THIS_MODULE,
.fs_flags = FS_RENAME_DOES_D_MOVE,
};
MODULE_ALIAS_FS("9p");

View File

@@ -1,195 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/uio.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include "fid.h"
#include "xattr.h"
ssize_t v9fs_fid_xattr_get(struct p9_fid *fid, const char *name,
void *buffer, size_t buffer_size)
{
ssize_t retval;
u64 attr_size;
struct p9_fid *attr_fid;
struct kvec kvec = {.iov_base = buffer, .iov_len = buffer_size};
struct iov_iter to;
int err;
iov_iter_kvec(&to, READ | ITER_KVEC, &kvec, 1, buffer_size);
attr_fid = p9_client_xattrwalk(fid, name, &attr_size);
if (IS_ERR(attr_fid)) {
retval = PTR_ERR(attr_fid);
p9_debug(P9_DEBUG_VFS, "p9_client_attrwalk failed %zd\n",
retval);
return retval;
}
if (attr_size > buffer_size) {
if (!buffer_size) /* request to get the attr_size */
retval = attr_size;
else
retval = -ERANGE;
} else {
iov_iter_truncate(&to, attr_size);
retval = p9_client_read(attr_fid, 0, &to, &err);
if (err)
retval = err;
}
p9_client_clunk(attr_fid);
return retval;
}
/*
* v9fs_xattr_get()
*
* Copy an extended attribute into the buffer
* provided, or compute the buffer size required.
* Buffer is NULL to compute the size of the buffer required.
*
* Returns a negative error number on failure, or the number of bytes
* used / required on success.
*/
ssize_t v9fs_xattr_get(struct dentry *dentry, const char *name,
void *buffer, size_t buffer_size)
{
struct p9_fid *fid;
p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu\n",
name, buffer_size);
fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid))
return PTR_ERR(fid);
return v9fs_fid_xattr_get(fid, name, buffer, buffer_size);
}
/*
* v9fs_xattr_set()
*
* Create, replace or remove an extended attribute for this inode. Buffer
* is NULL to remove an existing extended attribute, and non-NULL to
* either replace an existing extended attribute, or create a new extended
* attribute. The flags XATTR_REPLACE and XATTR_CREATE
* specify that an extended attribute must exist and must not exist
* previous to the call, respectively.
*
* Returns 0, or a negative error number on failure.
*/
int v9fs_xattr_set(struct dentry *dentry, const char *name,
const void *value, size_t value_len, int flags)
{
struct p9_fid *fid = v9fs_fid_lookup(dentry);
if (IS_ERR(fid))
return PTR_ERR(fid);
return v9fs_fid_xattr_set(fid, name, value, value_len, flags);
}
int v9fs_fid_xattr_set(struct p9_fid *fid, const char *name,
const void *value, size_t value_len, int flags)
{
struct kvec kvec = {.iov_base = (void *)value, .iov_len = value_len};
struct iov_iter from;
int retval, err;
iov_iter_kvec(&from, WRITE | ITER_KVEC, &kvec, 1, value_len);
p9_debug(P9_DEBUG_VFS, "name = %s value_len = %zu flags = %d\n",
name, value_len, flags);
/* Clone it */
fid = p9_client_walk(fid, 0, NULL, 1);
if (IS_ERR(fid))
return PTR_ERR(fid);
/*
* On success fid points to xattr
*/
retval = p9_client_xattrcreate(fid, name, value_len, flags);
if (retval < 0)
p9_debug(P9_DEBUG_VFS, "p9_client_xattrcreate failed %d\n",
retval);
else
p9_client_write(fid, 0, &from, &retval);
err = p9_client_clunk(fid);
if (!retval && err)
retval = err;
return retval;
}
ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
{
return v9fs_xattr_get(dentry, NULL, buffer, buffer_size);
}
static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
struct dentry *dentry, const char *name,
void *buffer, size_t size)
{
const char *full_name = xattr_full_name(handler, name);
if (strcmp(name, "") == 0)
return -EINVAL;
return v9fs_xattr_get(dentry, full_name, buffer, size);
}
static int v9fs_xattr_handler_set(const struct xattr_handler *handler,
struct dentry *dentry, const char *name,
const void *value, size_t size, int flags)
{
const char *full_name = xattr_full_name(handler, name);
if (strcmp(name, "") == 0)
return -EINVAL;
return v9fs_xattr_set(dentry, full_name, value, size, flags);
}
static struct xattr_handler v9fs_xattr_user_handler = {
.prefix = XATTR_USER_PREFIX,
.get = v9fs_xattr_handler_get,
.set = v9fs_xattr_handler_set,
};
static struct xattr_handler v9fs_xattr_trusted_handler = {
.prefix = XATTR_TRUSTED_PREFIX,
.get = v9fs_xattr_handler_get,
.set = v9fs_xattr_handler_set,
};
#ifdef CONFIG_9P_FS_SECURITY
static struct xattr_handler v9fs_xattr_security_handler = {
.prefix = XATTR_SECURITY_PREFIX,
.get = v9fs_xattr_handler_get,
.set = v9fs_xattr_handler_set,
};
#endif
const struct xattr_handler *v9fs_xattr_handlers[] = {
&v9fs_xattr_user_handler,
&v9fs_xattr_trusted_handler,
#ifdef CONFIG_9P_FS_POSIX_ACL
&v9fs_xattr_acl_access_handler,
&v9fs_xattr_acl_default_handler,
#endif
#ifdef CONFIG_9P_FS_SECURITY
&v9fs_xattr_security_handler,
#endif
NULL
};

View File

@@ -1,34 +0,0 @@
/*
* Copyright IBM Corporation, 2010
* Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef FS_9P_XATTR_H
#define FS_9P_XATTR_H
#include <linux/xattr.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
extern const struct xattr_handler *v9fs_xattr_handlers[];
extern const struct xattr_handler v9fs_xattr_acl_access_handler;
extern const struct xattr_handler v9fs_xattr_acl_default_handler;
extern ssize_t v9fs_fid_xattr_get(struct p9_fid *, const char *,
void *, size_t);
extern ssize_t v9fs_xattr_get(struct dentry *, const char *,
void *, size_t);
extern int v9fs_fid_xattr_set(struct p9_fid *, const char *,
const void *, size_t, int);
extern int v9fs_xattr_set(struct dentry *, const char *,
const void *, size_t, int);
extern ssize_t v9fs_listxattr(struct dentry *, char *, size_t);
#endif /* FS_9P_XATTR_H */

Binary file not shown.

View File

@@ -1,12 +0,0 @@
if [ "${1}" = "sys" ]; then
echo "Installing module and daemon for ACPI button"
if [ ! -f /tmpRoot/lib/modules/button.ko ]; then
cp /modules/button.ko /tmpRoot/lib/modules/
fi
tar -zxvf /addons/acpid.tgz -C /tmpRoot/
chmod 755 /tmpRoot/usr/sbin/acpid
chmod 644 /tmpRoot/etc/acpi/events/power
chmod 744 /tmpRoot/etc/acpi/power.sh
chmod 744 /tmpRoot/usr/lib/systemd/system/acpid.service
ln -sf /usr/lib/systemd/system/acpid.service /tmpRoot/etc/systemd/system/multi-user.target.wants/acpid.service
fi

View File

@@ -1,36 +0,0 @@
version: 1
name: acpid
description: "Flexible and extensible daemon for delivering ACPI events"
available-for:
bromolow-3.10.108:
install-script: "install.sh"
copy: "all"
modules: true
apollolake-4.4.180:
install-script: "install.sh"
copy: "all"
modules: true
broadwell-4.4.180:
install-script: "install.sh"
copy: "all"
modules: true
broadwellnk-4.4.180:
install-script: "install.sh"
copy: "all"
modules: true
denverton-4.4.180:
install-script: "install.sh"
copy: "all"
modules: true
geminilake-4.4.180:
install-script: "install.sh"
copy: "all"
modules: true
v1000-4.4.180:
install-script: "install.sh"
copy: "all"
modules: true
purley-4.4.180:
install-script: "install.sh"
copy: "all"
modules: false

View File

@@ -1,46 +0,0 @@
#
# Makefile for the Linux ACPI interpreter
#
#
# ACPI Boot-Time Table Parsing
#
#obj-$(CONFIG_X86) += blacklist.o
# Power management related files
#acpi-$(CONFIG_ACPI_SLEEP) += proc.o
#
# ACPI Bus and Device Drivers
#
#acpi-$(CONFIG_ACPI_DOCK) += dock.o
#acpi-$(CONFIG_X86_INTEL_LPSS) += acpi_lpss.o
#acpi-$(CONFIG_X86) += acpi_cmos_rtc.o
#acpi-$(CONFIG_DEBUG_FS) += debugfs.o
acpi-$(CONFIG_ACPI_NUMA) += numa.o
#acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
# These are (potentially) separate modules
# IPMI may be used by other drivers, so it has to initialise before them
#obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o
#obj-$(CONFIG_ACPI_AC) += ac.o
obj-$(CONFIG_ACPI_BUTTON) += button.o
#obj-$(CONFIG_ACPI_FAN) += fan.o
#obj-$(CONFIG_ACPI_VIDEO) += video.o
#obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
#obj-$(CONFIG_ACPI_CONTAINER) += container.o
#obj-$(CONFIG_ACPI_THERMAL) += thermal.o
#obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
#obj-$(CONFIG_ACPI_BATTERY) += battery.o
#obj-$(CONFIG_ACPI_SBS) += sbshc.o
#obj-$(CONFIG_ACPI_SBS) += sbs.o
#obj-$(CONFIG_ACPI_HED) += hed.o
#obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o
#obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
#obj-$(CONFIG_ACPI_BGRT) += bgrt.o
#obj-$(CONFIG_ACPI_I2C) += acpi_i2c.o
#obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o

View File

@@ -1,454 +0,0 @@
/*
* button.c - ACPI Button Driver
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <acpi/button.h>
#define PREFIX "ACPI: "
#define ACPI_BUTTON_CLASS "button"
#define ACPI_BUTTON_FILE_INFO "info"
#define ACPI_BUTTON_FILE_STATE "state"
#define ACPI_BUTTON_TYPE_UNKNOWN 0x00
#define ACPI_BUTTON_NOTIFY_STATUS 0x80
#define ACPI_BUTTON_SUBCLASS_POWER "power"
#define ACPI_BUTTON_HID_POWER "PNP0C0C"
#define ACPI_BUTTON_DEVICE_NAME_POWER "Power Button"
#define ACPI_BUTTON_TYPE_POWER 0x01
#define ACPI_BUTTON_SUBCLASS_SLEEP "sleep"
#define ACPI_BUTTON_HID_SLEEP "PNP0C0E"
#define ACPI_BUTTON_DEVICE_NAME_SLEEP "Sleep Button"
#define ACPI_BUTTON_TYPE_SLEEP 0x03
#define ACPI_BUTTON_SUBCLASS_LID "lid"
#define ACPI_BUTTON_HID_LID "PNP0C0D"
#define ACPI_BUTTON_DEVICE_NAME_LID "Lid Switch"
#define ACPI_BUTTON_TYPE_LID 0x05
#define _COMPONENT ACPI_BUTTON_COMPONENT
ACPI_MODULE_NAME("button");
MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION("ACPI Button Driver");
MODULE_LICENSE("GPL");
static const struct acpi_device_id button_device_ids[] = {
{ACPI_BUTTON_HID_LID, 0},
{ACPI_BUTTON_HID_SLEEP, 0},
{ACPI_BUTTON_HID_SLEEPF, 0},
{ACPI_BUTTON_HID_POWER, 0},
{ACPI_BUTTON_HID_POWERF, 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, button_device_ids);
static int acpi_button_add(struct acpi_device *device);
static int acpi_button_remove(struct acpi_device *device);
static void acpi_button_notify(struct acpi_device *device, u32 event);
#ifdef CONFIG_PM_SLEEP
static int acpi_button_resume(struct device *dev);
#endif
static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume);
static struct acpi_driver acpi_button_driver = {
.name = "button",
.class = ACPI_BUTTON_CLASS,
.ids = button_device_ids,
.ops = {
.add = acpi_button_add,
.remove = acpi_button_remove,
.notify = acpi_button_notify,
},
.drv.pm = &acpi_button_pm,
};
struct acpi_button {
unsigned int type;
struct input_dev *input;
char phys[32]; /* for input device */
unsigned long pushed;
bool wakeup_enabled;
};
static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
static struct acpi_device *lid_device;
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
static struct proc_dir_entry *acpi_button_dir;
static struct proc_dir_entry *acpi_lid_dir;
static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
{
struct acpi_device *device = seq->private;
acpi_status status;
unsigned long long state;
status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
seq_printf(seq, "state: %s\n",
ACPI_FAILURE(status) ? "unsupported" :
(state ? "open" : "closed"));
return 0;
}
static int acpi_button_state_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_button_state_seq_show, PDE_DATA(inode));
}
static const struct file_operations acpi_button_state_fops = {
.owner = THIS_MODULE,
.open = acpi_button_state_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_button_add_fs(struct acpi_device *device)
{
struct acpi_button *button = acpi_driver_data(device);
struct proc_dir_entry *entry = NULL;
int ret = 0;
/* procfs I/F for ACPI lid device only */
if (button->type != ACPI_BUTTON_TYPE_LID)
return 0;
if (acpi_button_dir || acpi_lid_dir) {
printk(KERN_ERR PREFIX "More than one Lid device found!\n");
return -EEXIST;
}
/* create /proc/acpi/button */
acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
if (!acpi_button_dir)
return -ENODEV;
/* create /proc/acpi/button/lid */
acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
if (!acpi_lid_dir) {
ret = -ENODEV;
goto remove_button_dir;
}
/* create /proc/acpi/button/lid/LID/ */
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_lid_dir);
if (!acpi_device_dir(device)) {
ret = -ENODEV;
goto remove_lid_dir;
}
/* create /proc/acpi/button/lid/LID/state */
entry = proc_create_data(ACPI_BUTTON_FILE_STATE,
S_IRUGO, acpi_device_dir(device),
&acpi_button_state_fops, device);
if (!entry) {
ret = -ENODEV;
goto remove_dev_dir;
}
done:
return ret;
remove_dev_dir:
remove_proc_entry(acpi_device_bid(device),
acpi_lid_dir);
acpi_device_dir(device) = NULL;
remove_lid_dir:
remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
remove_button_dir:
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
goto done;
}
static int acpi_button_remove_fs(struct acpi_device *device)
{
struct acpi_button *button = acpi_driver_data(device);
if (button->type != ACPI_BUTTON_TYPE_LID)
return 0;
remove_proc_entry(ACPI_BUTTON_FILE_STATE,
acpi_device_dir(device));
remove_proc_entry(acpi_device_bid(device),
acpi_lid_dir);
acpi_device_dir(device) = NULL;
remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
return 0;
}
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
int acpi_lid_notifier_register(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&acpi_lid_notifier, nb);
}
EXPORT_SYMBOL(acpi_lid_notifier_register);
int acpi_lid_notifier_unregister(struct notifier_block *nb)
{
return blocking_notifier_chain_unregister(&acpi_lid_notifier, nb);
}
EXPORT_SYMBOL(acpi_lid_notifier_unregister);
int acpi_lid_open(void)
{
acpi_status status;
unsigned long long state;
if (!lid_device)
return -ENODEV;
status = acpi_evaluate_integer(lid_device->handle, "_LID", NULL,
&state);
if (ACPI_FAILURE(status))
return -ENODEV;
return !!state;
}
EXPORT_SYMBOL(acpi_lid_open);
static int acpi_lid_send_state(struct acpi_device *device)
{
struct acpi_button *button = acpi_driver_data(device);
unsigned long long state;
acpi_status status;
int ret;
status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
if (ACPI_FAILURE(status))
return -ENODEV;
/* input layer checks if event is redundant */
input_report_switch(button->input, SW_LID, !state);
input_sync(button->input);
if (state)
pm_wakeup_event(&device->dev, 0);
ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
if (ret == NOTIFY_DONE)
ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
device);
if (ret == NOTIFY_DONE || ret == NOTIFY_OK) {
/*
* It is also regarded as success if the notifier_chain
* returns NOTIFY_OK or NOTIFY_DONE.
*/
ret = 0;
}
return ret;
}
static void acpi_button_notify(struct acpi_device *device, u32 event)
{
struct acpi_button *button = acpi_driver_data(device);
struct input_dev *input;
switch (event) {
case ACPI_FIXED_HARDWARE_EVENT:
event = ACPI_BUTTON_NOTIFY_STATUS;
/* fall through */
case ACPI_BUTTON_NOTIFY_STATUS:
input = button->input;
if (button->type == ACPI_BUTTON_TYPE_LID) {
acpi_lid_send_state(device);
} else {
int keycode = test_bit(KEY_SLEEP, input->keybit) ?
KEY_SLEEP : KEY_POWER;
input_report_key(input, keycode, 1);
input_sync(input);
input_report_key(input, keycode, 0);
input_sync(input);
pm_wakeup_event(&device->dev, 0);
}
acpi_bus_generate_proc_event(device, event, ++button->pushed);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
break;
}
}
#ifdef CONFIG_PM_SLEEP
static int acpi_button_resume(struct device *dev)
{
struct acpi_device *device = to_acpi_device(dev);
struct acpi_button *button = acpi_driver_data(device);
if (button->type == ACPI_BUTTON_TYPE_LID)
return acpi_lid_send_state(device);
return 0;
}
#endif
static int acpi_button_add(struct acpi_device *device)
{
struct acpi_button *button;
struct input_dev *input;
const char *hid = acpi_device_hid(device);
char *name, *class;
int error;
button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
if (!button)
return -ENOMEM;
device->driver_data = button;
button->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
goto err_free_button;
}
name = acpi_device_name(device);
class = acpi_device_class(device);
if (!strcmp(hid, ACPI_BUTTON_HID_POWER) ||
!strcmp(hid, ACPI_BUTTON_HID_POWERF)) {
button->type = ACPI_BUTTON_TYPE_POWER;
strcpy(name, ACPI_BUTTON_DEVICE_NAME_POWER);
sprintf(class, "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
} else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEP) ||
!strcmp(hid, ACPI_BUTTON_HID_SLEEPF)) {
button->type = ACPI_BUTTON_TYPE_SLEEP;
strcpy(name, ACPI_BUTTON_DEVICE_NAME_SLEEP);
sprintf(class, "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
} else if (!strcmp(hid, ACPI_BUTTON_HID_LID)) {
button->type = ACPI_BUTTON_TYPE_LID;
strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID);
sprintf(class, "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
} else {
printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
error = -ENODEV;
goto err_free_input;
}
error = acpi_button_add_fs(device);
if (error)
goto err_free_input;
snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);
input->name = name;
input->phys = button->phys;
input->id.bustype = BUS_HOST;
input->id.product = button->type;
input->dev.parent = &device->dev;
switch (button->type) {
case ACPI_BUTTON_TYPE_POWER:
input->evbit[0] = BIT_MASK(EV_KEY);
set_bit(KEY_POWER, input->keybit);
break;
case ACPI_BUTTON_TYPE_SLEEP:
input->evbit[0] = BIT_MASK(EV_KEY);
set_bit(KEY_SLEEP, input->keybit);
break;
case ACPI_BUTTON_TYPE_LID:
input->evbit[0] = BIT_MASK(EV_SW);
set_bit(SW_LID, input->swbit);
break;
}
error = input_register_device(input);
if (error)
goto err_remove_fs;
if (button->type == ACPI_BUTTON_TYPE_LID) {
acpi_lid_send_state(device);
/*
* This assumes there's only one lid device, or if there are
* more we only care about the last one...
*/
lid_device = device;
}
if (device->wakeup.flags.valid) {
/* Button's GPE is run-wake GPE */
acpi_enable_gpe(device->wakeup.gpe_device,
device->wakeup.gpe_number);
if (!device_may_wakeup(&device->dev)) {
device_set_wakeup_enable(&device->dev, true);
button->wakeup_enabled = true;
}
}
printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
return 0;
err_remove_fs:
acpi_button_remove_fs(device);
err_free_input:
input_free_device(input);
err_free_button:
kfree(button);
return error;
}
static int acpi_button_remove(struct acpi_device *device)
{
struct acpi_button *button = acpi_driver_data(device);
if (device->wakeup.flags.valid) {
acpi_disable_gpe(device->wakeup.gpe_device,
device->wakeup.gpe_number);
if (button->wakeup_enabled)
device_set_wakeup_enable(&device->dev, false);
}
acpi_button_remove_fs(device);
input_unregister_device(button->input);
kfree(button);
return 0;
}
module_acpi_driver(acpi_button_driver);

View File

@@ -1 +0,0 @@
obj-$(CONFIG_ACPI_BUTTON) += button.o

View File

@@ -1,449 +0,0 @@
/*
* button.c - ACPI Button Driver
*
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <acpi/button.h>
#define PREFIX "ACPI: "
#define ACPI_BUTTON_CLASS "button"
#define ACPI_BUTTON_FILE_INFO "info"
#define ACPI_BUTTON_FILE_STATE "state"
#define ACPI_BUTTON_TYPE_UNKNOWN 0x00
#define ACPI_BUTTON_NOTIFY_STATUS 0x80
#define ACPI_BUTTON_SUBCLASS_POWER "power"
#define ACPI_BUTTON_HID_POWER "PNP0C0C"
#define ACPI_BUTTON_DEVICE_NAME_POWER "Power Button"
#define ACPI_BUTTON_TYPE_POWER 0x01
#define ACPI_BUTTON_SUBCLASS_SLEEP "sleep"
#define ACPI_BUTTON_HID_SLEEP "PNP0C0E"
#define ACPI_BUTTON_DEVICE_NAME_SLEEP "Sleep Button"
#define ACPI_BUTTON_TYPE_SLEEP 0x03
#define ACPI_BUTTON_SUBCLASS_LID "lid"
#define ACPI_BUTTON_HID_LID "PNP0C0D"
#define ACPI_BUTTON_DEVICE_NAME_LID "Lid Switch"
#define ACPI_BUTTON_TYPE_LID 0x05
#define _COMPONENT ACPI_BUTTON_COMPONENT
ACPI_MODULE_NAME("button");
MODULE_AUTHOR("Paul Diefenbaugh");
MODULE_DESCRIPTION("ACPI Button Driver");
MODULE_LICENSE("GPL");
static const struct acpi_device_id button_device_ids[] = {
{ACPI_BUTTON_HID_LID, 0},
{ACPI_BUTTON_HID_SLEEP, 0},
{ACPI_BUTTON_HID_SLEEPF, 0},
{ACPI_BUTTON_HID_POWER, 0},
{ACPI_BUTTON_HID_POWERF, 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, button_device_ids);
static int acpi_button_add(struct acpi_device *device);
static int acpi_button_remove(struct acpi_device *device);
static void acpi_button_notify(struct acpi_device *device, u32 event);
#ifdef CONFIG_PM_SLEEP
static int acpi_button_suspend(struct device *dev);
static int acpi_button_resume(struct device *dev);
#else
#define acpi_button_suspend NULL
#define acpi_button_resume NULL
#endif
static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume);
static struct acpi_driver acpi_button_driver = {
.name = "button",
.class = ACPI_BUTTON_CLASS,
.ids = button_device_ids,
.ops = {
.add = acpi_button_add,
.remove = acpi_button_remove,
.notify = acpi_button_notify,
},
.drv.pm = &acpi_button_pm,
};
struct acpi_button {
unsigned int type;
struct input_dev *input;
char phys[32]; /* for input device */
unsigned long pushed;
bool suspended;
};
static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
static struct acpi_device *lid_device;
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
static struct proc_dir_entry *acpi_button_dir;
static struct proc_dir_entry *acpi_lid_dir;
static int acpi_button_state_seq_show(struct seq_file *seq, void *offset)
{
struct acpi_device *device = seq->private;
acpi_status status;
unsigned long long state;
status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
seq_printf(seq, "state: %s\n",
ACPI_FAILURE(status) ? "unsupported" :
(state ? "open" : "closed"));
return 0;
}
static int acpi_button_state_open_fs(struct inode *inode, struct file *file)
{
return single_open(file, acpi_button_state_seq_show, PDE_DATA(inode));
}
static const struct file_operations acpi_button_state_fops = {
.owner = THIS_MODULE,
.open = acpi_button_state_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_button_add_fs(struct acpi_device *device)
{
struct acpi_button *button = acpi_driver_data(device);
struct proc_dir_entry *entry = NULL;
int ret = 0;
/* procfs I/F for ACPI lid device only */
if (button->type != ACPI_BUTTON_TYPE_LID)
return 0;
if (acpi_button_dir || acpi_lid_dir) {
printk(KERN_ERR PREFIX "More than one Lid device found!\n");
return -EEXIST;
}
/* create /proc/acpi/button */
acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
if (!acpi_button_dir)
return -ENODEV;
/* create /proc/acpi/button/lid */
acpi_lid_dir = proc_mkdir(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
if (!acpi_lid_dir) {
ret = -ENODEV;
goto remove_button_dir;
}
/* create /proc/acpi/button/lid/LID/ */
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), acpi_lid_dir);
if (!acpi_device_dir(device)) {
ret = -ENODEV;
goto remove_lid_dir;
}
/* create /proc/acpi/button/lid/LID/state */
entry = proc_create_data(ACPI_BUTTON_FILE_STATE,
S_IRUGO, acpi_device_dir(device),
&acpi_button_state_fops, device);
if (!entry) {
ret = -ENODEV;
goto remove_dev_dir;
}
done:
return ret;
remove_dev_dir:
remove_proc_entry(acpi_device_bid(device),
acpi_lid_dir);
acpi_device_dir(device) = NULL;
remove_lid_dir:
remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
remove_button_dir:
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
goto done;
}
static int acpi_button_remove_fs(struct acpi_device *device)
{
struct acpi_button *button = acpi_driver_data(device);
if (button->type != ACPI_BUTTON_TYPE_LID)
return 0;
remove_proc_entry(ACPI_BUTTON_FILE_STATE,
acpi_device_dir(device));
remove_proc_entry(acpi_device_bid(device),
acpi_lid_dir);
acpi_device_dir(device) = NULL;
remove_proc_entry(ACPI_BUTTON_SUBCLASS_LID, acpi_button_dir);
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
return 0;
}
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
int acpi_lid_notifier_register(struct notifier_block *nb)
{
return blocking_notifier_chain_register(&acpi_lid_notifier, nb);
}
EXPORT_SYMBOL(acpi_lid_notifier_register);
int acpi_lid_notifier_unregister(struct notifier_block *nb)
{
return blocking_notifier_chain_unregister(&acpi_lid_notifier, nb);
}
EXPORT_SYMBOL(acpi_lid_notifier_unregister);
int acpi_lid_open(void)
{
acpi_status status;
unsigned long long state;
if (!lid_device)
return -ENODEV;
status = acpi_evaluate_integer(lid_device->handle, "_LID", NULL,
&state);
if (ACPI_FAILURE(status))
return -ENODEV;
return !!state;
}
EXPORT_SYMBOL(acpi_lid_open);
static int acpi_lid_send_state(struct acpi_device *device)
{
struct acpi_button *button = acpi_driver_data(device);
unsigned long long state;
acpi_status status;
int ret;
status = acpi_evaluate_integer(device->handle, "_LID", NULL, &state);
if (ACPI_FAILURE(status))
return -ENODEV;
/* input layer checks if event is redundant */
input_report_switch(button->input, SW_LID, !state);
input_sync(button->input);
if (state)
pm_wakeup_event(&device->dev, 0);
ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device);
if (ret == NOTIFY_DONE)
ret = blocking_notifier_call_chain(&acpi_lid_notifier, state,
device);
if (ret == NOTIFY_DONE || ret == NOTIFY_OK) {
/*
* It is also regarded as success if the notifier_chain
* returns NOTIFY_OK or NOTIFY_DONE.
*/
ret = 0;
}
return ret;
}
static void acpi_button_notify(struct acpi_device *device, u32 event)
{
struct acpi_button *button = acpi_driver_data(device);
struct input_dev *input;
switch (event) {
case ACPI_FIXED_HARDWARE_EVENT:
event = ACPI_BUTTON_NOTIFY_STATUS;
/* fall through */
case ACPI_BUTTON_NOTIFY_STATUS:
input = button->input;
if (button->type == ACPI_BUTTON_TYPE_LID) {
acpi_lid_send_state(device);
} else {
int keycode;
pm_wakeup_event(&device->dev, 0);
if (button->suspended)
break;
keycode = test_bit(KEY_SLEEP, input->keybit) ?
KEY_SLEEP : KEY_POWER;
input_report_key(input, keycode, 1);
input_sync(input);
input_report_key(input, keycode, 0);
input_sync(input);
acpi_bus_generate_netlink_event(
device->pnp.device_class,
dev_name(&device->dev),
event, ++button->pushed);
}
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Unsupported event [0x%x]\n", event));
break;
}
}
#ifdef CONFIG_PM_SLEEP
static int acpi_button_suspend(struct device *dev)
{
struct acpi_device *device = to_acpi_device(dev);
struct acpi_button *button = acpi_driver_data(device);
button->suspended = true;
return 0;
}
static int acpi_button_resume(struct device *dev)
{
struct acpi_device *device = to_acpi_device(dev);
struct acpi_button *button = acpi_driver_data(device);
button->suspended = false;
if (button->type == ACPI_BUTTON_TYPE_LID)
return acpi_lid_send_state(device);
return 0;
}
#endif
static int acpi_button_add(struct acpi_device *device)
{
struct acpi_button *button;
struct input_dev *input;
const char *hid = acpi_device_hid(device);
char *name, *class;
int error;
button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL);
if (!button)
return -ENOMEM;
device->driver_data = button;
button->input = input = input_allocate_device();
if (!input) {
error = -ENOMEM;
goto err_free_button;
}
name = acpi_device_name(device);
class = acpi_device_class(device);
if (!strcmp(hid, ACPI_BUTTON_HID_POWER) ||
!strcmp(hid, ACPI_BUTTON_HID_POWERF)) {
button->type = ACPI_BUTTON_TYPE_POWER;
strcpy(name, ACPI_BUTTON_DEVICE_NAME_POWER);
sprintf(class, "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER);
} else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEP) ||
!strcmp(hid, ACPI_BUTTON_HID_SLEEPF)) {
button->type = ACPI_BUTTON_TYPE_SLEEP;
strcpy(name, ACPI_BUTTON_DEVICE_NAME_SLEEP);
sprintf(class, "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP);
} else if (!strcmp(hid, ACPI_BUTTON_HID_LID)) {
button->type = ACPI_BUTTON_TYPE_LID;
strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID);
sprintf(class, "%s/%s",
ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID);
} else {
printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
error = -ENODEV;
goto err_free_input;
}
error = acpi_button_add_fs(device);
if (error)
goto err_free_input;
snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);
input->name = name;
input->phys = button->phys;
input->id.bustype = BUS_HOST;
input->id.product = button->type;
input->dev.parent = &device->dev;
switch (button->type) {
case ACPI_BUTTON_TYPE_POWER:
input_set_capability(input, EV_KEY, KEY_POWER);
break;
case ACPI_BUTTON_TYPE_SLEEP:
input_set_capability(input, EV_KEY, KEY_SLEEP);
break;
case ACPI_BUTTON_TYPE_LID:
input_set_capability(input, EV_SW, SW_LID);
break;
}
error = input_register_device(input);
if (error)
goto err_remove_fs;
if (button->type == ACPI_BUTTON_TYPE_LID) {
acpi_lid_send_state(device);
/*
* This assumes there's only one lid device, or if there are
* more we only care about the last one...
*/
lid_device = device;
}
printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device));
return 0;
err_remove_fs:
acpi_button_remove_fs(device);
err_free_input:
input_free_device(input);
err_free_button:
kfree(button);
return error;
}
static int acpi_button_remove(struct acpi_device *device)
{
struct acpi_button *button = acpi_driver_data(device);
acpi_button_remove_fs(device);
input_unregister_device(button->input);
kfree(button);
return 0;
}
module_acpi_driver(acpi_button_driver);

View File

@@ -1,4 +0,0 @@
if [ "${1}" = "rd" ]; then
echo "Installing module for Atheros L1C Gigabit Ethernet adapter"
${INSMOD} "/modules/atl1c.ko" ${PARAMS}
fi

View File

@@ -1,28 +0,0 @@
version: 1
name: atl1c
description: "Driver for Atheros L1C Gigabit Ethernet adapters"
available-for:
bromolow-3.10.108:
install-script: &script "install.sh"
modules: true
apollolake-4.4.180:
install-script: *script
modules: true
broadwell-4.4.180:
install-script: *script
modules: true
broadwellnk-4.4.180:
install-script: *script
modules: true
denverton-4.4.180:
install-script: *script
modules: true
geminilake-4.4.180:
install-script: *script
modules: true
v1000-4.4.180:
install-script: *script
modules: true
purley-4.4.180:
install-script: *script
modules: true

View File

@@ -1,2 +0,0 @@
obj-m += atl1c.o
atl1c-objs := atl1c_main.o atl1c_hw.o atl1c_ethtool.o

View File

@@ -1,606 +0,0 @@
/*
* Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ATL1C_H_
#define _ATL1C_H_
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/udp.h>
#include <linux/mii.h>
#include <linux/io.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/tcp.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/workqueue.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
#include "atl1c_hw.h"
/* Wake Up Filter Control */
#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
#define AT_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
#define AT_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
#define AT_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */
#define AT_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
#define AT_VLAN_TO_TAG(_vlan, _tag) \
_tag = ((((_vlan) >> 8) & 0xFF) |\
(((_vlan) & 0xFF) << 8))
#define AT_TAG_TO_VLAN(_tag, _vlan) \
_vlan = ((((_tag) >> 8) & 0xFF) |\
(((_tag) & 0xFF) << 8))
#define SPEED_0 0xffff
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2
#define AT_RX_BUF_SIZE (ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN)
#define MAX_JUMBO_FRAME_SIZE (6*1024)
#define AT_MAX_RECEIVE_QUEUE 4
#define AT_DEF_RECEIVE_QUEUE 1
#define AT_MAX_TRANSMIT_QUEUE 2
#define AT_DMA_HI_ADDR_MASK 0xffffffff00000000ULL
#define AT_DMA_LO_ADDR_MASK 0x00000000ffffffffULL
#define AT_TX_WATCHDOG (5 * HZ)
#define AT_MAX_INT_WORK 5
#define AT_TWSI_EEPROM_TIMEOUT 100
#define AT_HW_MAX_IDLE_DELAY 10
#define AT_SUSPEND_LINK_TIMEOUT 100
#define AT_ASPM_L0S_TIMER 6
#define AT_ASPM_L1_TIMER 12
#define AT_LCKDET_TIMER 12
#define ATL1C_PCIE_L0S_L1_DISABLE 0x01
#define ATL1C_PCIE_PHY_RESET 0x02
#define ATL1C_ASPM_L0s_ENABLE 0x0001
#define ATL1C_ASPM_L1_ENABLE 0x0002
#define AT_REGS_LEN (74 * sizeof(u32))
#define AT_EEPROM_LEN 512
#define ATL1C_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i]))
#define ATL1C_RFD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_rx_free_desc)
#define ATL1C_TPD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_tpd_desc)
#define ATL1C_RRD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_recv_ret_status)
/* tpd word 1 bit 0:7 General Checksum task offload */
#define TPD_L4HDR_OFFSET_MASK 0x00FF
#define TPD_L4HDR_OFFSET_SHIFT 0
/* tpd word 1 bit 0:7 Large Send task offload (IPv4/IPV6) */
#define TPD_TCPHDR_OFFSET_MASK 0x00FF
#define TPD_TCPHDR_OFFSET_SHIFT 0
/* tpd word 1 bit 0:7 Custom Checksum task offload */
#define TPD_PLOADOFFSET_MASK 0x00FF
#define TPD_PLOADOFFSET_SHIFT 0
/* tpd word 1 bit 8:17 */
#define TPD_CCSUM_EN_MASK 0x0001
#define TPD_CCSUM_EN_SHIFT 8
#define TPD_IP_CSUM_MASK 0x0001
#define TPD_IP_CSUM_SHIFT 9
#define TPD_TCP_CSUM_MASK 0x0001
#define TPD_TCP_CSUM_SHIFT 10
#define TPD_UDP_CSUM_MASK 0x0001
#define TPD_UDP_CSUM_SHIFT 11
#define TPD_LSO_EN_MASK 0x0001 /* TCP Large Send Offload */
#define TPD_LSO_EN_SHIFT 12
#define TPD_LSO_VER_MASK 0x0001
#define TPD_LSO_VER_SHIFT 13 /* 0 : ipv4; 1 : ipv4/ipv6 */
#define TPD_CON_VTAG_MASK 0x0001
#define TPD_CON_VTAG_SHIFT 14
#define TPD_INS_VTAG_MASK 0x0001
#define TPD_INS_VTAG_SHIFT 15
#define TPD_IPV4_PACKET_MASK 0x0001 /* valid when LSO VER is 1 */
#define TPD_IPV4_PACKET_SHIFT 16
#define TPD_ETH_TYPE_MASK 0x0001
#define TPD_ETH_TYPE_SHIFT 17 /* 0 : 802.3 frame; 1 : Ethernet */
/* tpd word 18:25 Custom Checksum task offload */
#define TPD_CCSUM_OFFSET_MASK 0x00FF
#define TPD_CCSUM_OFFSET_SHIFT 18
#define TPD_CCSUM_EPAD_MASK 0x0001
#define TPD_CCSUM_EPAD_SHIFT 30
/* tpd word 18:30 Large Send task offload (IPv4/IPV6) */
#define TPD_MSS_MASK 0x1FFF
#define TPD_MSS_SHIFT 18
#define TPD_EOP_MASK 0x0001
#define TPD_EOP_SHIFT 31
struct atl1c_tpd_desc {
__le16 buffer_len; /* include 4-byte CRC */
__le16 vlan_tag;
__le32 word1;
__le64 buffer_addr;
};
struct atl1c_tpd_ext_desc {
u32 reservd_0;
__le32 word1;
__le32 pkt_len;
u32 reservd_1;
};
/* rrs word 0 bit 0:31 */
#define RRS_RX_CSUM_MASK 0xFFFF
#define RRS_RX_CSUM_SHIFT 0
#define RRS_RX_RFD_CNT_MASK 0x000F
#define RRS_RX_RFD_CNT_SHIFT 16
#define RRS_RX_RFD_INDEX_MASK 0x0FFF
#define RRS_RX_RFD_INDEX_SHIFT 20
/* rrs flag bit 0:16 */
#define RRS_HEAD_LEN_MASK 0x00FF
#define RRS_HEAD_LEN_SHIFT 0
#define RRS_HDS_TYPE_MASK 0x0003
#define RRS_HDS_TYPE_SHIFT 8
#define RRS_CPU_NUM_MASK 0x0003
#define RRS_CPU_NUM_SHIFT 10
#define RRS_HASH_FLG_MASK 0x000F
#define RRS_HASH_FLG_SHIFT 12
#define RRS_HDS_TYPE_HEAD 1
#define RRS_HDS_TYPE_DATA 2
#define RRS_IS_NO_HDS_TYPE(flag) \
((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == 0)
#define RRS_IS_HDS_HEAD(flag) \
((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
RRS_HDS_TYPE_HEAD)
#define RRS_IS_HDS_DATA(flag) \
((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
RRS_HDS_TYPE_DATA)
/* rrs word 3 bit 0:31 */
#define RRS_PKT_SIZE_MASK 0x3FFF
#define RRS_PKT_SIZE_SHIFT 0
#define RRS_ERR_L4_CSUM_MASK 0x0001
#define RRS_ERR_L4_CSUM_SHIFT 14
#define RRS_ERR_IP_CSUM_MASK 0x0001
#define RRS_ERR_IP_CSUM_SHIFT 15
#define RRS_VLAN_INS_MASK 0x0001
#define RRS_VLAN_INS_SHIFT 16
#define RRS_PROT_ID_MASK 0x0007
#define RRS_PROT_ID_SHIFT 17
#define RRS_RX_ERR_SUM_MASK 0x0001
#define RRS_RX_ERR_SUM_SHIFT 20
#define RRS_RX_ERR_CRC_MASK 0x0001
#define RRS_RX_ERR_CRC_SHIFT 21
#define RRS_RX_ERR_FAE_MASK 0x0001
#define RRS_RX_ERR_FAE_SHIFT 22
#define RRS_RX_ERR_TRUNC_MASK 0x0001
#define RRS_RX_ERR_TRUNC_SHIFT 23
#define RRS_RX_ERR_RUNC_MASK 0x0001
#define RRS_RX_ERR_RUNC_SHIFT 24
#define RRS_RX_ERR_ICMP_MASK 0x0001
#define RRS_RX_ERR_ICMP_SHIFT 25
#define RRS_PACKET_BCAST_MASK 0x0001
#define RRS_PACKET_BCAST_SHIFT 26
#define RRS_PACKET_MCAST_MASK 0x0001
#define RRS_PACKET_MCAST_SHIFT 27
#define RRS_PACKET_TYPE_MASK 0x0001
#define RRS_PACKET_TYPE_SHIFT 28
#define RRS_FIFO_FULL_MASK 0x0001
#define RRS_FIFO_FULL_SHIFT 29
#define RRS_802_3_LEN_ERR_MASK 0x0001
#define RRS_802_3_LEN_ERR_SHIFT 30
#define RRS_RXD_UPDATED_MASK 0x0001
#define RRS_RXD_UPDATED_SHIFT 31
#define RRS_ERR_L4_CSUM 0x00004000
#define RRS_ERR_IP_CSUM 0x00008000
#define RRS_VLAN_INS 0x00010000
#define RRS_RX_ERR_SUM 0x00100000
#define RRS_RX_ERR_CRC 0x00200000
#define RRS_802_3_LEN_ERR 0x40000000
#define RRS_RXD_UPDATED 0x80000000
#define RRS_PACKET_TYPE_802_3 1
#define RRS_PACKET_TYPE_ETH 0
#define RRS_PACKET_IS_ETH(word) \
((((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK) == \
RRS_PACKET_TYPE_ETH)
#define RRS_RXD_IS_VALID(word) \
((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1)
#define RRS_PACKET_PROT_IS_IPV4_ONLY(word) \
((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 1)
#define RRS_PACKET_PROT_IS_IPV6_ONLY(word) \
((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 6)
struct atl1c_recv_ret_status {
__le32 word0;
__le32 rss_hash;
__le16 vlan_tag;
__le16 flag;
__le32 word3;
};
/* RFD descriptor */
struct atl1c_rx_free_desc {
__le64 buffer_addr;
};
/* DMA Order Settings */
enum atl1c_dma_order {
atl1c_dma_ord_in = 1,
atl1c_dma_ord_enh = 2,
atl1c_dma_ord_out = 4
};
enum atl1c_dma_rcb {
atl1c_rcb_64 = 0,
atl1c_rcb_128 = 1
};
enum atl1c_mac_speed {
atl1c_mac_speed_0 = 0,
atl1c_mac_speed_10_100 = 1,
atl1c_mac_speed_1000 = 2
};
enum atl1c_dma_req_block {
atl1c_dma_req_128 = 0,
atl1c_dma_req_256 = 1,
atl1c_dma_req_512 = 2,
atl1c_dma_req_1024 = 3,
atl1c_dma_req_2048 = 4,
atl1c_dma_req_4096 = 5
};
enum atl1c_nic_type {
athr_l1c = 0,
athr_l2c = 1,
athr_l2c_b,
athr_l2c_b2,
athr_l1d,
athr_l1d_2,
};
enum atl1c_trans_queue {
atl1c_trans_normal = 0,
atl1c_trans_high = 1
};
struct atl1c_hw_stats {
/* rx */
unsigned long rx_ok; /* The number of good packet received. */
unsigned long rx_bcast; /* The number of good broadcast packet received. */
unsigned long rx_mcast; /* The number of good multicast packet received. */
unsigned long rx_pause; /* The number of Pause packet received. */
unsigned long rx_ctrl; /* The number of Control packet received other than Pause frame. */
unsigned long rx_fcs_err; /* The number of packets with bad FCS. */
unsigned long rx_len_err; /* The number of packets with mismatch of length field and actual size. */
unsigned long rx_byte_cnt; /* The number of bytes of good packet received. FCS is NOT included. */
unsigned long rx_runt; /* The number of packets received that are less than 64 byte long and with good FCS. */
unsigned long rx_frag; /* The number of packets received that are less than 64 byte long and with bad FCS. */
unsigned long rx_sz_64; /* The number of good and bad packets received that are 64 byte long. */
unsigned long rx_sz_65_127; /* The number of good and bad packets received that are between 65 and 127-byte long. */
unsigned long rx_sz_128_255; /* The number of good and bad packets received that are between 128 and 255-byte long. */
unsigned long rx_sz_256_511; /* The number of good and bad packets received that are between 256 and 511-byte long. */
unsigned long rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */
unsigned long rx_sz_1024_1518; /* The number of good and bad packets received that are between 1024 and 1518-byte long. */
unsigned long rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */
unsigned long rx_sz_ov; /* The number of good and bad packets received that are more than MTU size truncated by Selene. */
unsigned long rx_rxf_ov; /* The number of frame dropped due to occurrence of RX FIFO overflow. */
unsigned long rx_rrd_ov; /* The number of frame dropped due to occurrence of RRD overflow. */
unsigned long rx_align_err; /* Alignment Error */
unsigned long rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */
unsigned long rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */
unsigned long rx_err_addr; /* The number of packets dropped due to address filtering. */
/* tx */
unsigned long tx_ok; /* The number of good packet transmitted. */
unsigned long tx_bcast; /* The number of good broadcast packet transmitted. */
unsigned long tx_mcast; /* The number of good multicast packet transmitted. */
unsigned long tx_pause; /* The number of Pause packet transmitted. */
unsigned long tx_exc_defer; /* The number of packets transmitted with excessive deferral. */
unsigned long tx_ctrl; /* The number of packets transmitted is a control frame, excluding Pause frame. */
unsigned long tx_defer; /* The number of packets transmitted that is deferred. */
unsigned long tx_byte_cnt; /* The number of bytes of data transmitted. FCS is NOT included. */
unsigned long tx_sz_64; /* The number of good and bad packets transmitted that are 64 byte long. */
unsigned long tx_sz_65_127; /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */
unsigned long tx_sz_128_255; /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */
unsigned long tx_sz_256_511; /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */
unsigned long tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */
unsigned long tx_sz_1024_1518; /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */
unsigned long tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */
unsigned long tx_1_col; /* The number of packets subsequently transmitted successfully with a single prior collision. */
unsigned long tx_2_col; /* The number of packets subsequently transmitted successfully with multiple prior collisions. */
unsigned long tx_late_col; /* The number of packets transmitted with late collisions. */
unsigned long tx_abort_col; /* The number of transmit packets aborted due to excessive collisions. */
unsigned long tx_underrun; /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
unsigned long tx_rd_eop; /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */
unsigned long tx_len_err; /* The number of transmit packets with length field does NOT match the actual frame size. */
unsigned long tx_trunc; /* The number of transmit packets truncated due to size exceeding MTU. */
unsigned long tx_bcast_byte; /* The byte count of broadcast packet transmitted, excluding FCS. */
unsigned long tx_mcast_byte; /* The byte count of multicast packet transmitted, excluding FCS. */
};
struct atl1c_hw {
u8 __iomem *hw_addr; /* inner register address */
struct atl1c_adapter *adapter;
enum atl1c_nic_type nic_type;
enum atl1c_dma_order dma_order;
enum atl1c_dma_rcb rcb_value;
enum atl1c_dma_req_block dmar_block;
u16 device_id;
u16 vendor_id;
u16 subsystem_id;
u16 subsystem_vendor_id;
u8 revision_id;
u16 phy_id1;
u16 phy_id2;
u32 intr_mask;
u8 preamble_len;
u16 max_frame_size;
u16 min_frame_size;
enum atl1c_mac_speed mac_speed;
bool mac_duplex;
bool hibernate;
u16 media_type;
#define MEDIA_TYPE_AUTO_SENSOR 0
#define MEDIA_TYPE_100M_FULL 1
#define MEDIA_TYPE_100M_HALF 2
#define MEDIA_TYPE_10M_FULL 3
#define MEDIA_TYPE_10M_HALF 4
u16 autoneg_advertised;
u16 mii_autoneg_adv_reg;
u16 mii_1000t_ctrl_reg;
u16 tx_imt; /* TX Interrupt Moderator timer ( 2us resolution) */
u16 rx_imt; /* RX Interrupt Moderator timer ( 2us resolution) */
u16 ict; /* Interrupt Clear timer (2us resolution) */
u16 ctrl_flags;
#define ATL1C_INTR_CLEAR_ON_READ 0x0001
#define ATL1C_INTR_MODRT_ENABLE 0x0002
#define ATL1C_CMB_ENABLE 0x0004
#define ATL1C_SMB_ENABLE 0x0010
#define ATL1C_TXQ_MODE_ENHANCE 0x0020
#define ATL1C_RX_IPV6_CHKSUM 0x0040
#define ATL1C_ASPM_L0S_SUPPORT 0x0080
#define ATL1C_ASPM_L1_SUPPORT 0x0100
#define ATL1C_ASPM_CTRL_MON 0x0200
#define ATL1C_HIB_DISABLE 0x0400
#define ATL1C_APS_MODE_ENABLE 0x0800
#define ATL1C_LINK_EXT_SYNC 0x1000
#define ATL1C_CLK_GATING_EN 0x2000
#define ATL1C_FPGA_VERSION 0x8000
u16 link_cap_flags;
#define ATL1C_LINK_CAP_1000M 0x0001
u32 smb_timer;
u16 rrd_thresh; /* Threshold of number of RRD produced to trigger
interrupt request */
u16 tpd_thresh;
u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned burst. */
u8 rfd_burst;
u32 base_cpu;
u32 indirect_tab;
u8 mac_addr[ETH_ALEN];
u8 perm_mac_addr[ETH_ALEN];
bool phy_configured;
bool re_autoneg;
bool emi_ca;
bool msi_lnkpatch; /* link patch for specific platforms */
};
/*
* atl1c_ring_header represents a single, contiguous block of DMA space
* mapped for the three descriptor rings (tpd, rfd, rrd) described below
*/
struct atl1c_ring_header {
void *desc; /* virtual address */
dma_addr_t dma; /* physical address*/
unsigned int size; /* length in bytes */
};
/*
* atl1c_buffer is wrapper around a pointer to a socket buffer
* so a DMA handle can be stored along with the skb
*/
struct atl1c_buffer {
struct sk_buff *skb; /* socket buffer */
u16 length; /* rx buffer length */
u16 flags; /* information of buffer */
#define ATL1C_BUFFER_FREE 0x0001
#define ATL1C_BUFFER_BUSY 0x0002
#define ATL1C_BUFFER_STATE_MASK 0x0003
#define ATL1C_PCIMAP_SINGLE 0x0004
#define ATL1C_PCIMAP_PAGE 0x0008
#define ATL1C_PCIMAP_TYPE_MASK 0x000C
#define ATL1C_PCIMAP_TODEVICE 0x0010
#define ATL1C_PCIMAP_FROMDEVICE 0x0020
#define ATL1C_PCIMAP_DIRECTION_MASK 0x0030
dma_addr_t dma;
};
#define ATL1C_SET_BUFFER_STATE(buff, state) do { \
((buff)->flags) &= ~ATL1C_BUFFER_STATE_MASK; \
((buff)->flags) |= (state); \
} while (0)
#define ATL1C_SET_PCIMAP_TYPE(buff, type, direction) do { \
((buff)->flags) &= ~ATL1C_PCIMAP_TYPE_MASK; \
((buff)->flags) |= (type); \
((buff)->flags) &= ~ATL1C_PCIMAP_DIRECTION_MASK; \
((buff)->flags) |= (direction); \
} while (0)
/* transimit packet descriptor (tpd) ring */
struct atl1c_tpd_ring {
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
u16 size; /* descriptor ring length in bytes */
u16 count; /* number of descriptors in the ring */
u16 next_to_use; /* this is protectd by adapter->tx_lock */
atomic_t next_to_clean;
struct atl1c_buffer *buffer_info;
};
/* receive free descriptor (rfd) ring */
struct atl1c_rfd_ring {
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
u16 size; /* descriptor ring length in bytes */
u16 count; /* number of descriptors in the ring */
u16 next_to_use;
u16 next_to_clean;
struct atl1c_buffer *buffer_info;
};
/* receive return descriptor (rrd) ring */
struct atl1c_rrd_ring {
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
u16 size; /* descriptor ring length in bytes */
u16 count; /* number of descriptors in the ring */
u16 next_to_use;
u16 next_to_clean;
};
/* board specific private data structure */
struct atl1c_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
struct napi_struct napi;
struct page *rx_page;
unsigned int rx_page_offset;
unsigned int rx_frag_size;
struct atl1c_hw hw;
struct atl1c_hw_stats hw_stats;
struct mii_if_info mii; /* MII interface info */
u16 rx_buffer_len;
unsigned long flags;
#define __AT_TESTING 0x0001
#define __AT_RESETTING 0x0002
#define __AT_DOWN 0x0003
unsigned long work_event;
#define ATL1C_WORK_EVENT_RESET 0
#define ATL1C_WORK_EVENT_LINK_CHANGE 1
u32 msg_enable;
bool have_msi;
u32 wol;
u16 link_speed;
u16 link_duplex;
spinlock_t mdio_lock;
spinlock_t tx_lock;
atomic_t irq_sem;
struct work_struct common_task;
struct timer_list watchdog_timer;
struct timer_list phy_config_timer;
/* All Descriptor memory */
struct atl1c_ring_header ring_header;
struct atl1c_tpd_ring tpd_ring[AT_MAX_TRANSMIT_QUEUE];
struct atl1c_rfd_ring rfd_ring;
struct atl1c_rrd_ring rrd_ring;
u32 bd_number; /* board number;*/
};
#define AT_WRITE_REG(a, reg, value) ( \
writel((value), ((a)->hw_addr + reg)))
#define AT_WRITE_FLUSH(a) (\
readl((a)->hw_addr))
#define AT_READ_REG(a, reg, pdata) do { \
if (unlikely((a)->hibernate)) { \
readl((a)->hw_addr + reg); \
*(u32 *)pdata = readl((a)->hw_addr + reg); \
} else { \
*(u32 *)pdata = readl((a)->hw_addr + reg); \
} \
} while (0)
#define AT_WRITE_REGB(a, reg, value) (\
writeb((value), ((a)->hw_addr + reg)))
#define AT_READ_REGB(a, reg) (\
readb((a)->hw_addr + reg))
#define AT_WRITE_REGW(a, reg, value) (\
writew((value), ((a)->hw_addr + reg)))
#define AT_READ_REGW(a, reg, pdata) do { \
if (unlikely((a)->hibernate)) { \
readw((a)->hw_addr + reg); \
*(u16 *)pdata = readw((a)->hw_addr + reg); \
} else { \
*(u16 *)pdata = readw((a)->hw_addr + reg); \
} \
} while (0)
#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \
writel((value), (((a)->hw_addr + reg) + ((offset) << 2))))
#define AT_READ_REG_ARRAY(a, reg, offset) ( \
readl(((a)->hw_addr + reg) + ((offset) << 2)))
extern char atl1c_driver_name[];
extern char atl1c_driver_version[];
extern void atl1c_reinit_locked(struct atl1c_adapter *adapter);
extern s32 atl1c_reset_hw(struct atl1c_hw *hw);
extern void atl1c_set_ethtool_ops(struct net_device *netdev);
#endif /* _ATL1C_H_ */

View File

@@ -1,309 +0,0 @@
/*
* Copyright(c) 2009 - 2009 Atheros Corporation. All rights reserved.
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/slab.h>
#include "atl1c.h"
static int atl1c_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw *hw = &adapter->hw;
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg |
SUPPORTED_TP);
if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M)
ecmd->supported |= SUPPORTED_1000baseT_Full;
ecmd->advertising = ADVERTISED_TP;
ecmd->advertising |= hw->autoneg_advertised;
ecmd->port = PORT_TP;
ecmd->phy_address = 0;
ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed != SPEED_0) {
ethtool_cmd_speed_set(ecmd, adapter->link_speed);
if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
ethtool_cmd_speed_set(ecmd, -1);
ecmd->duplex = -1;
}
ecmd->autoneg = AUTONEG_ENABLE;
return 0;
}
static int atl1c_set_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw *hw = &adapter->hw;
u16 autoneg_advertised;
while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
msleep(1);
if (ecmd->autoneg == AUTONEG_ENABLE) {
autoneg_advertised = ADVERTISED_Autoneg;
} else {
u32 speed = ethtool_cmd_speed(ecmd);
if (speed == SPEED_1000) {
if (ecmd->duplex != DUPLEX_FULL) {
if (netif_msg_link(adapter))
dev_warn(&adapter->pdev->dev,
"1000M half is invalid\n");
clear_bit(__AT_RESETTING, &adapter->flags);
return -EINVAL;
}
autoneg_advertised = ADVERTISED_1000baseT_Full;
} else if (speed == SPEED_100) {
if (ecmd->duplex == DUPLEX_FULL)
autoneg_advertised = ADVERTISED_100baseT_Full;
else
autoneg_advertised = ADVERTISED_100baseT_Half;
} else {
if (ecmd->duplex == DUPLEX_FULL)
autoneg_advertised = ADVERTISED_10baseT_Full;
else
autoneg_advertised = ADVERTISED_10baseT_Half;
}
}
if (hw->autoneg_advertised != autoneg_advertised) {
hw->autoneg_advertised = autoneg_advertised;
if (atl1c_restart_autoneg(hw) != 0) {
if (netif_msg_link(adapter))
dev_warn(&adapter->pdev->dev,
"ethtool speed/duplex setting failed\n");
clear_bit(__AT_RESETTING, &adapter->flags);
return -EINVAL;
}
}
clear_bit(__AT_RESETTING, &adapter->flags);
return 0;
}
static u32 atl1c_get_msglevel(struct net_device *netdev)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
return adapter->msg_enable;
}
static void atl1c_set_msglevel(struct net_device *netdev, u32 data)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
adapter->msg_enable = data;
}
static int atl1c_get_regs_len(struct net_device *netdev)
{
return AT_REGS_LEN;
}
static void atl1c_get_regs(struct net_device *netdev,
struct ethtool_regs *regs, void *p)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw *hw = &adapter->hw;
u32 *regs_buff = p;
u16 phy_data;
memset(p, 0, AT_REGS_LEN);
regs->version = 1;
AT_READ_REG(hw, REG_PM_CTRL, p++);
AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL, p++);
AT_READ_REG(hw, REG_TWSI_CTRL, p++);
AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL, p++);
AT_READ_REG(hw, REG_MASTER_CTRL, p++);
AT_READ_REG(hw, REG_MANUAL_TIMER_INIT, p++);
AT_READ_REG(hw, REG_IRQ_MODRT_TIMER_INIT, p++);
AT_READ_REG(hw, REG_GPHY_CTRL, p++);
AT_READ_REG(hw, REG_LINK_CTRL, p++);
AT_READ_REG(hw, REG_IDLE_STATUS, p++);
AT_READ_REG(hw, REG_MDIO_CTRL, p++);
AT_READ_REG(hw, REG_SERDES, p++);
AT_READ_REG(hw, REG_MAC_CTRL, p++);
AT_READ_REG(hw, REG_MAC_IPG_IFG, p++);
AT_READ_REG(hw, REG_MAC_STA_ADDR, p++);
AT_READ_REG(hw, REG_MAC_STA_ADDR+4, p++);
AT_READ_REG(hw, REG_RX_HASH_TABLE, p++);
AT_READ_REG(hw, REG_RX_HASH_TABLE+4, p++);
AT_READ_REG(hw, REG_RXQ_CTRL, p++);
AT_READ_REG(hw, REG_TXQ_CTRL, p++);
AT_READ_REG(hw, REG_MTU, p++);
AT_READ_REG(hw, REG_WOL_CTRL, p++);
atl1c_read_phy_reg(hw, MII_BMCR, &phy_data);
regs_buff[AT_REGS_LEN/sizeof(u32) - 2] = (u32) phy_data;
atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
regs_buff[AT_REGS_LEN/sizeof(u32) - 1] = (u32) phy_data;
}
static int atl1c_get_eeprom_len(struct net_device *netdev)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
if (atl1c_check_eeprom_exist(&adapter->hw))
return AT_EEPROM_LEN;
else
return 0;
}
static int atl1c_get_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, u8 *bytes)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw *hw = &adapter->hw;
u32 *eeprom_buff;
int first_dword, last_dword;
int ret_val = 0;
int i;
if (eeprom->len == 0)
return -EINVAL;
if (!atl1c_check_eeprom_exist(hw)) /* not exist */
return -EINVAL;
eeprom->magic = adapter->pdev->vendor |
(adapter->pdev->device << 16);
first_dword = eeprom->offset >> 2;
last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
eeprom_buff = kmalloc(sizeof(u32) *
(last_dword - first_dword + 1), GFP_KERNEL);
if (eeprom_buff == NULL)
return -ENOMEM;
for (i = first_dword; i < last_dword; i++) {
if (!atl1c_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) {
kfree(eeprom_buff);
return -EIO;
}
}
memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
eeprom->len);
kfree(eeprom_buff);
return ret_val;
return 0;
}
static void atl1c_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
strlcpy(drvinfo->driver, atl1c_driver_name, sizeof(drvinfo->driver));
strlcpy(drvinfo->version, atl1c_driver_version,
sizeof(drvinfo->version));
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
drvinfo->n_stats = 0;
drvinfo->testinfo_len = 0;
drvinfo->regdump_len = atl1c_get_regs_len(netdev);
drvinfo->eedump_len = atl1c_get_eeprom_len(netdev);
}
static void atl1c_get_wol(struct net_device *netdev,
struct ethtool_wolinfo *wol)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
wol->supported = WAKE_MAGIC | WAKE_PHY;
wol->wolopts = 0;
if (adapter->wol & AT_WUFC_EX)
wol->wolopts |= WAKE_UCAST;
if (adapter->wol & AT_WUFC_MC)
wol->wolopts |= WAKE_MCAST;
if (adapter->wol & AT_WUFC_BC)
wol->wolopts |= WAKE_BCAST;
if (adapter->wol & AT_WUFC_MAG)
wol->wolopts |= WAKE_MAGIC;
if (adapter->wol & AT_WUFC_LNKC)
wol->wolopts |= WAKE_PHY;
}
static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
return -EOPNOTSUPP;
/* these settings will always override what we currently have */
adapter->wol = 0;
if (wol->wolopts & WAKE_MAGIC)
adapter->wol |= AT_WUFC_MAG;
if (wol->wolopts & WAKE_PHY)
adapter->wol |= AT_WUFC_LNKC;
device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
return 0;
}
static int atl1c_nway_reset(struct net_device *netdev)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
if (netif_running(netdev))
atl1c_reinit_locked(adapter);
return 0;
}
static const struct ethtool_ops atl1c_ethtool_ops = {
.get_settings = atl1c_get_settings,
.set_settings = atl1c_set_settings,
.get_drvinfo = atl1c_get_drvinfo,
.get_regs_len = atl1c_get_regs_len,
.get_regs = atl1c_get_regs,
.get_wol = atl1c_get_wol,
.set_wol = atl1c_set_wol,
.get_msglevel = atl1c_get_msglevel,
.set_msglevel = atl1c_set_msglevel,
.nway_reset = atl1c_nway_reset,
.get_link = ethtool_op_get_link,
.get_eeprom_len = atl1c_get_eeprom_len,
.get_eeprom = atl1c_get_eeprom,
};
void atl1c_set_ethtool_ops(struct net_device *netdev)
{
SET_ETHTOOL_OPS(netdev, &atl1c_ethtool_ops);
}

View File

@@ -1,865 +0,0 @@
/*
* Copyright(c) 2007 Atheros Corporation. All rights reserved.
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mii.h>
#include <linux/crc32.h>
#include "atl1c.h"
/*
* check_eeprom_exist
* return 1 if eeprom exist
*/
int atl1c_check_eeprom_exist(struct atl1c_hw *hw)
{
u32 data;
AT_READ_REG(hw, REG_TWSI_DEBUG, &data);
if (data & TWSI_DEBUG_DEV_EXIST)
return 1;
AT_READ_REG(hw, REG_MASTER_CTRL, &data);
if (data & MASTER_CTRL_OTP_SEL)
return 1;
return 0;
}
void atl1c_hw_set_mac_addr(struct atl1c_hw *hw, u8 *mac_addr)
{
u32 value;
/*
* 00-0B-6A-F6-00-DC
* 0: 6AF600DC 1: 000B
* low dword
*/
value = mac_addr[2] << 24 |
mac_addr[3] << 16 |
mac_addr[4] << 8 |
mac_addr[5];
AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
/* hight dword */
value = mac_addr[0] << 8 |
mac_addr[1];
AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
}
/* read mac address from hardware register */
static bool atl1c_read_current_addr(struct atl1c_hw *hw, u8 *eth_addr)
{
u32 addr[2];
AT_READ_REG(hw, REG_MAC_STA_ADDR, &addr[0]);
AT_READ_REG(hw, REG_MAC_STA_ADDR + 4, &addr[1]);
*(u32 *) &eth_addr[2] = htonl(addr[0]);
*(u16 *) &eth_addr[0] = htons((u16)addr[1]);
return is_valid_ether_addr(eth_addr);
}
/*
* atl1c_get_permanent_address
* return 0 if get valid mac address,
*/
static int atl1c_get_permanent_address(struct atl1c_hw *hw)
{
u32 i;
u32 otp_ctrl_data;
u32 twsi_ctrl_data;
u16 phy_data;
bool raise_vol = false;
/* MAC-address from BIOS is the 1st priority */
if (atl1c_read_current_addr(hw, hw->perm_mac_addr))
return 0;
/* init */
AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
if (atl1c_check_eeprom_exist(hw)) {
if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c) {
/* Enable OTP CLK */
if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
otp_ctrl_data |= OTP_CTRL_CLK_EN;
AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
AT_WRITE_FLUSH(hw);
msleep(1);
}
}
/* raise voltage temporally for l2cb */
if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
atl1c_read_phy_dbg(hw, MIIDBG_ANACTRL, &phy_data);
phy_data &= ~ANACTRL_HB_EN;
atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, phy_data);
atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
phy_data |= VOLT_CTRL_SWLOWEST;
atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
udelay(20);
raise_vol = true;
}
AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART;
AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data);
for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) {
msleep(10);
AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0)
break;
}
if (i >= AT_TWSI_EEPROM_TIMEOUT)
return -1;
}
/* Disable OTP_CLK */
if ((hw->nic_type == athr_l1c || hw->nic_type == athr_l2c)) {
otp_ctrl_data &= ~OTP_CTRL_CLK_EN;
AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
msleep(1);
}
if (raise_vol) {
atl1c_read_phy_dbg(hw, MIIDBG_ANACTRL, &phy_data);
phy_data |= ANACTRL_HB_EN;
atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, phy_data);
atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
phy_data &= ~VOLT_CTRL_SWLOWEST;
atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
udelay(20);
}
if (atl1c_read_current_addr(hw, hw->perm_mac_addr))
return 0;
return -1;
}
bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value)
{
int i;
int ret = false;
u32 otp_ctrl_data;
u32 control;
u32 data;
if (offset & 3)
return ret; /* address do not align */
AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
AT_WRITE_REG(hw, REG_OTP_CTRL,
(otp_ctrl_data | OTP_CTRL_CLK_EN));
AT_WRITE_REG(hw, REG_EEPROM_DATA_LO, 0);
control = (offset & EEPROM_CTRL_ADDR_MASK) << EEPROM_CTRL_ADDR_SHIFT;
AT_WRITE_REG(hw, REG_EEPROM_CTRL, control);
for (i = 0; i < 10; i++) {
udelay(100);
AT_READ_REG(hw, REG_EEPROM_CTRL, &control);
if (control & EEPROM_CTRL_RW)
break;
}
if (control & EEPROM_CTRL_RW) {
AT_READ_REG(hw, REG_EEPROM_CTRL, &data);
AT_READ_REG(hw, REG_EEPROM_DATA_LO, p_value);
data = data & 0xFFFF;
*p_value = swab32((data << 16) | (*p_value >> 16));
ret = true;
}
if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
return ret;
}
/*
* Reads the adapter's MAC address from the EEPROM
*
* hw - Struct containing variables accessed by shared code
*/
int atl1c_read_mac_addr(struct atl1c_hw *hw)
{
int err = 0;
err = atl1c_get_permanent_address(hw);
if (err)
eth_random_addr(hw->perm_mac_addr);
memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
return err;
}
/*
* atl1c_hash_mc_addr
* purpose
* set hash value for a multicast address
* hash calcu processing :
* 1. calcu 32bit CRC for multicast address
* 2. reverse crc with MSB to LSB
*/
u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr)
{
u32 crc32;
u32 value = 0;
int i;
crc32 = ether_crc_le(6, mc_addr);
for (i = 0; i < 32; i++)
value |= (((crc32 >> i) & 1) << (31 - i));
return value;
}
/*
* Sets the bit in the multicast table corresponding to the hash value.
* hw - Struct containing variables accessed by shared code
* hash_value - Multicast address hash value
*/
void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value)
{
u32 hash_bit, hash_reg;
u32 mta;
/*
* The HASH Table is a register array of 2 32-bit registers.
* It is treated like an array of 64 bits. We want to set
* bit BitArray[hash_value]. So we figure out what register
* the bit is in, read it, OR in the new bit, then write
* back the new value. The register is determined by the
* upper bit of the hash value and the bit within that
* register are determined by the lower 5 bits of the value.
*/
hash_reg = (hash_value >> 31) & 0x1;
hash_bit = (hash_value >> 26) & 0x1F;
mta = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
mta |= (1 << hash_bit);
AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
}
/*
* wait mdio module be idle
* return true: idle
* false: still busy
*/
bool atl1c_wait_mdio_idle(struct atl1c_hw *hw)
{
u32 val;
int i;
for (i = 0; i < MDIO_MAX_AC_TO; i++) {
AT_READ_REG(hw, REG_MDIO_CTRL, &val);
if (!(val & (MDIO_CTRL_BUSY | MDIO_CTRL_START)))
break;
udelay(10);
}
return i != MDIO_MAX_AC_TO;
}
void atl1c_stop_phy_polling(struct atl1c_hw *hw)
{
if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
return;
AT_WRITE_REG(hw, REG_MDIO_CTRL, 0);
atl1c_wait_mdio_idle(hw);
}
void atl1c_start_phy_polling(struct atl1c_hw *hw, u16 clk_sel)
{
u32 val;
if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
return;
val = MDIO_CTRL_SPRES_PRMBL |
FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
FIELDX(MDIO_CTRL_REG, 1) |
MDIO_CTRL_START |
MDIO_CTRL_OP_READ;
AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
atl1c_wait_mdio_idle(hw);
val |= MDIO_CTRL_AP_EN;
val &= ~MDIO_CTRL_START;
AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
udelay(30);
}
/*
* atl1c_read_phy_core
* core funtion to read register in PHY via MDIO control regsiter.
* ext: extension register (see IEEE 802.3)
* dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0)
* reg: reg to read
*/
int atl1c_read_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
u16 reg, u16 *phy_data)
{
u32 val;
u16 clk_sel = MDIO_CTRL_CLK_25_4;
atl1c_stop_phy_polling(hw);
*phy_data = 0;
/* only l2c_b2 & l1d_2 could use slow clock */
if ((hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) &&
hw->hibernate)
clk_sel = MDIO_CTRL_CLK_25_128;
if (ext) {
val = FIELDX(MDIO_EXTN_DEVAD, dev) | FIELDX(MDIO_EXTN_REG, reg);
AT_WRITE_REG(hw, REG_MDIO_EXTN, val);
val = MDIO_CTRL_SPRES_PRMBL |
FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
MDIO_CTRL_START |
MDIO_CTRL_MODE_EXT |
MDIO_CTRL_OP_READ;
} else {
val = MDIO_CTRL_SPRES_PRMBL |
FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
FIELDX(MDIO_CTRL_REG, reg) |
MDIO_CTRL_START |
MDIO_CTRL_OP_READ;
}
AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
if (!atl1c_wait_mdio_idle(hw))
return -1;
AT_READ_REG(hw, REG_MDIO_CTRL, &val);
*phy_data = (u16)FIELD_GETX(val, MDIO_CTRL_DATA);
atl1c_start_phy_polling(hw, clk_sel);
return 0;
}
/*
* atl1c_write_phy_core
* core funtion to write to register in PHY via MDIO control regsiter.
* ext: extension register (see IEEE 802.3)
* dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0)
* reg: reg to write
*/
int atl1c_write_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
u16 reg, u16 phy_data)
{
u32 val;
u16 clk_sel = MDIO_CTRL_CLK_25_4;
atl1c_stop_phy_polling(hw);
/* only l2c_b2 & l1d_2 could use slow clock */
if ((hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) &&
hw->hibernate)
clk_sel = MDIO_CTRL_CLK_25_128;
if (ext) {
val = FIELDX(MDIO_EXTN_DEVAD, dev) | FIELDX(MDIO_EXTN_REG, reg);
AT_WRITE_REG(hw, REG_MDIO_EXTN, val);
val = MDIO_CTRL_SPRES_PRMBL |
FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
FIELDX(MDIO_CTRL_DATA, phy_data) |
MDIO_CTRL_START |
MDIO_CTRL_MODE_EXT;
} else {
val = MDIO_CTRL_SPRES_PRMBL |
FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
FIELDX(MDIO_CTRL_DATA, phy_data) |
FIELDX(MDIO_CTRL_REG, reg) |
MDIO_CTRL_START;
}
AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
if (!atl1c_wait_mdio_idle(hw))
return -1;
atl1c_start_phy_polling(hw, clk_sel);
return 0;
}
/*
* Reads the value from a PHY register
* hw - Struct containing variables accessed by shared code
* reg_addr - address of the PHY register to read
*/
int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
{
return atl1c_read_phy_core(hw, false, 0, reg_addr, phy_data);
}
/*
* Writes a value to a PHY register
* hw - Struct containing variables accessed by shared code
* reg_addr - address of the PHY register to write
* data - data to write to the PHY
*/
int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data)
{
return atl1c_write_phy_core(hw, false, 0, reg_addr, phy_data);
}
/* read from PHY extension register */
int atl1c_read_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
u16 reg_addr, u16 *phy_data)
{
return atl1c_read_phy_core(hw, true, dev_addr, reg_addr, phy_data);
}
/* write to PHY extension register */
int atl1c_write_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
u16 reg_addr, u16 phy_data)
{
return atl1c_write_phy_core(hw, true, dev_addr, reg_addr, phy_data);
}
int atl1c_read_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
{
int err;
err = atl1c_write_phy_reg(hw, MII_DBG_ADDR, reg_addr);
if (unlikely(err))
return err;
else
err = atl1c_read_phy_reg(hw, MII_DBG_DATA, phy_data);
return err;
}
int atl1c_write_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 phy_data)
{
int err;
err = atl1c_write_phy_reg(hw, MII_DBG_ADDR, reg_addr);
if (unlikely(err))
return err;
else
err = atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
return err;
}
/*
* Configures PHY autoneg and flow control advertisement settings
*
* hw - Struct containing variables accessed by shared code
*/
static int atl1c_phy_setup_adv(struct atl1c_hw *hw)
{
u16 mii_adv_data = ADVERTISE_DEFAULT_CAP & ~ADVERTISE_ALL;
u16 mii_giga_ctrl_data = GIGA_CR_1000T_DEFAULT_CAP &
~GIGA_CR_1000T_SPEED_MASK;
if (hw->autoneg_advertised & ADVERTISED_10baseT_Half)
mii_adv_data |= ADVERTISE_10HALF;
if (hw->autoneg_advertised & ADVERTISED_10baseT_Full)
mii_adv_data |= ADVERTISE_10FULL;
if (hw->autoneg_advertised & ADVERTISED_100baseT_Half)
mii_adv_data |= ADVERTISE_100HALF;
if (hw->autoneg_advertised & ADVERTISED_100baseT_Full)
mii_adv_data |= ADVERTISE_100FULL;
if (hw->autoneg_advertised & ADVERTISED_Autoneg)
mii_adv_data |= ADVERTISE_10HALF | ADVERTISE_10FULL |
ADVERTISE_100HALF | ADVERTISE_100FULL;
if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M) {
if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half)
mii_giga_ctrl_data |= ADVERTISE_1000HALF;
if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full)
mii_giga_ctrl_data |= ADVERTISE_1000FULL;
if (hw->autoneg_advertised & ADVERTISED_Autoneg)
mii_giga_ctrl_data |= ADVERTISE_1000HALF |
ADVERTISE_1000FULL;
}
if (atl1c_write_phy_reg(hw, MII_ADVERTISE, mii_adv_data) != 0 ||
atl1c_write_phy_reg(hw, MII_CTRL1000, mii_giga_ctrl_data) != 0)
return -1;
return 0;
}
void atl1c_phy_disable(struct atl1c_hw *hw)
{
atl1c_power_saving(hw, 0);
}
int atl1c_phy_reset(struct atl1c_hw *hw)
{
struct atl1c_adapter *adapter = hw->adapter;
struct pci_dev *pdev = adapter->pdev;
u16 phy_data;
u32 phy_ctrl_data, lpi_ctrl;
int err;
/* reset PHY core */
AT_READ_REG(hw, REG_GPHY_CTRL, &phy_ctrl_data);
phy_ctrl_data &= ~(GPHY_CTRL_EXT_RESET | GPHY_CTRL_PHY_IDDQ |
GPHY_CTRL_GATE_25M_EN | GPHY_CTRL_PWDOWN_HW | GPHY_CTRL_CLS);
phy_ctrl_data |= GPHY_CTRL_SEL_ANA_RST;
if (!(hw->ctrl_flags & ATL1C_HIB_DISABLE))
phy_ctrl_data |= (GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE);
else
phy_ctrl_data &= ~(GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE);
AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
AT_WRITE_FLUSH(hw);
udelay(10);
AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data | GPHY_CTRL_EXT_RESET);
AT_WRITE_FLUSH(hw);
udelay(10 * GPHY_CTRL_EXT_RST_TO); /* delay 800us */
/* switch clock */
if (hw->nic_type == athr_l2c_b) {
atl1c_read_phy_dbg(hw, MIIDBG_CFGLPSPD, &phy_data);
atl1c_write_phy_dbg(hw, MIIDBG_CFGLPSPD,
phy_data & ~CFGLPSPD_RSTCNT_CLK125SW);
}
/* tx-half amplitude issue fix */
if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
atl1c_read_phy_dbg(hw, MIIDBG_CABLE1TH_DET, &phy_data);
phy_data |= CABLE1TH_DET_EN;
atl1c_write_phy_dbg(hw, MIIDBG_CABLE1TH_DET, phy_data);
}
/* clear bit3 of dbgport 3B to lower voltage */
if (!(hw->ctrl_flags & ATL1C_HIB_DISABLE)) {
if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
phy_data &= ~VOLT_CTRL_SWLOWEST;
atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
}
/* power saving config */
phy_data =
hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2 ?
L1D_LEGCYPS_DEF : L1C_LEGCYPS_DEF;
atl1c_write_phy_dbg(hw, MIIDBG_LEGCYPS, phy_data);
/* hib */
atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
SYSMODCTRL_IECHOADJ_DEF);
} else {
/* disable pws */
atl1c_read_phy_dbg(hw, MIIDBG_LEGCYPS, &phy_data);
atl1c_write_phy_dbg(hw, MIIDBG_LEGCYPS,
phy_data & ~LEGCYPS_EN);
/* disable hibernate */
atl1c_read_phy_dbg(hw, MIIDBG_HIBNEG, &phy_data);
atl1c_write_phy_dbg(hw, MIIDBG_HIBNEG,
phy_data & HIBNEG_PSHIB_EN);
}
/* disable AZ(EEE) by default */
if (hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2 ||
hw->nic_type == athr_l2c_b2) {
AT_READ_REG(hw, REG_LPI_CTRL, &lpi_ctrl);
AT_WRITE_REG(hw, REG_LPI_CTRL, lpi_ctrl & ~LPI_CTRL_EN);
atl1c_write_phy_ext(hw, MIIEXT_ANEG, MIIEXT_LOCAL_EEEADV, 0);
atl1c_write_phy_ext(hw, MIIEXT_PCS, MIIEXT_CLDCTRL3,
L2CB_CLDCTRL3);
}
/* other debug port to set */
atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, ANACTRL_DEF);
atl1c_write_phy_dbg(hw, MIIDBG_SRDSYSMOD, SRDSYSMOD_DEF);
atl1c_write_phy_dbg(hw, MIIDBG_TST10BTCFG, TST10BTCFG_DEF);
/* UNH-IOL test issue, set bit7 */
atl1c_write_phy_dbg(hw, MIIDBG_TST100BTCFG,
TST100BTCFG_DEF | TST100BTCFG_LITCH_EN);
/* set phy interrupt mask */
phy_data = IER_LINK_UP | IER_LINK_DOWN;
err = atl1c_write_phy_reg(hw, MII_IER, phy_data);
if (err) {
if (netif_msg_hw(adapter))
dev_err(&pdev->dev,
"Error enable PHY linkChange Interrupt\n");
return err;
}
return 0;
}
int atl1c_phy_init(struct atl1c_hw *hw)
{
struct atl1c_adapter *adapter = hw->adapter;
struct pci_dev *pdev = adapter->pdev;
int ret_val;
u16 mii_bmcr_data = BMCR_RESET;
if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &hw->phy_id1) != 0) ||
(atl1c_read_phy_reg(hw, MII_PHYSID2, &hw->phy_id2) != 0)) {
dev_err(&pdev->dev, "Error get phy ID\n");
return -1;
}
switch (hw->media_type) {
case MEDIA_TYPE_AUTO_SENSOR:
ret_val = atl1c_phy_setup_adv(hw);
if (ret_val) {
if (netif_msg_link(adapter))
dev_err(&pdev->dev,
"Error Setting up Auto-Negotiation\n");
return ret_val;
}
mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART;
break;
case MEDIA_TYPE_100M_FULL:
mii_bmcr_data |= BMCR_SPEED100 | BMCR_FULLDPLX;
break;
case MEDIA_TYPE_100M_HALF:
mii_bmcr_data |= BMCR_SPEED100;
break;
case MEDIA_TYPE_10M_FULL:
mii_bmcr_data |= BMCR_FULLDPLX;
break;
case MEDIA_TYPE_10M_HALF:
break;
default:
if (netif_msg_link(adapter))
dev_err(&pdev->dev, "Wrong Media type %d\n",
hw->media_type);
return -1;
break;
}
ret_val = atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
if (ret_val)
return ret_val;
hw->phy_configured = true;
return 0;
}
/*
* Detects the current speed and duplex settings of the hardware.
*
* hw - Struct containing variables accessed by shared code
* speed - Speed of the connection
* duplex - Duplex setting of the connection
*/
int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex)
{
int err;
u16 phy_data;
/* Read PHY Specific Status Register (17) */
err = atl1c_read_phy_reg(hw, MII_GIGA_PSSR, &phy_data);
if (err)
return err;
if (!(phy_data & GIGA_PSSR_SPD_DPLX_RESOLVED))
return -1;
switch (phy_data & GIGA_PSSR_SPEED) {
case GIGA_PSSR_1000MBS:
*speed = SPEED_1000;
break;
case GIGA_PSSR_100MBS:
*speed = SPEED_100;
break;
case GIGA_PSSR_10MBS:
*speed = SPEED_10;
break;
default:
return -1;
break;
}
if (phy_data & GIGA_PSSR_DPLX)
*duplex = FULL_DUPLEX;
else
*duplex = HALF_DUPLEX;
return 0;
}
/* select one link mode to get lower power consumption */
int atl1c_phy_to_ps_link(struct atl1c_hw *hw)
{
struct atl1c_adapter *adapter = hw->adapter;
struct pci_dev *pdev = adapter->pdev;
int ret = 0;
u16 autoneg_advertised = ADVERTISED_10baseT_Half;
u16 save_autoneg_advertised;
u16 phy_data;
u16 mii_lpa_data;
u16 speed = SPEED_0;
u16 duplex = FULL_DUPLEX;
int i;
atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
if (phy_data & BMSR_LSTATUS) {
atl1c_read_phy_reg(hw, MII_LPA, &mii_lpa_data);
if (mii_lpa_data & LPA_10FULL)
autoneg_advertised = ADVERTISED_10baseT_Full;
else if (mii_lpa_data & LPA_10HALF)
autoneg_advertised = ADVERTISED_10baseT_Half;
else if (mii_lpa_data & LPA_100HALF)
autoneg_advertised = ADVERTISED_100baseT_Half;
else if (mii_lpa_data & LPA_100FULL)
autoneg_advertised = ADVERTISED_100baseT_Full;
save_autoneg_advertised = hw->autoneg_advertised;
hw->phy_configured = false;
hw->autoneg_advertised = autoneg_advertised;
if (atl1c_restart_autoneg(hw) != 0) {
dev_dbg(&pdev->dev, "phy autoneg failed\n");
ret = -1;
}
hw->autoneg_advertised = save_autoneg_advertised;
if (mii_lpa_data) {
for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
mdelay(100);
atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
if (phy_data & BMSR_LSTATUS) {
if (atl1c_get_speed_and_duplex(hw, &speed,
&duplex) != 0)
dev_dbg(&pdev->dev,
"get speed and duplex failed\n");
break;
}
}
}
} else {
speed = SPEED_10;
duplex = HALF_DUPLEX;
}
adapter->link_speed = speed;
adapter->link_duplex = duplex;
return ret;
}
int atl1c_restart_autoneg(struct atl1c_hw *hw)
{
int err = 0;
u16 mii_bmcr_data = BMCR_RESET;
err = atl1c_phy_setup_adv(hw);
if (err)
return err;
mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART;
return atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
}
int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc)
{
struct atl1c_adapter *adapter = hw->adapter;
struct pci_dev *pdev = adapter->pdev;
u32 master_ctrl, mac_ctrl, phy_ctrl;
u32 wol_ctrl, speed;
u16 phy_data;
wol_ctrl = 0;
speed = adapter->link_speed == SPEED_1000 ?
MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100;
AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl);
AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl);
AT_READ_REG(hw, REG_GPHY_CTRL, &phy_ctrl);
master_ctrl &= ~MASTER_CTRL_CLK_SEL_DIS;
mac_ctrl = FIELD_SETX(mac_ctrl, MAC_CTRL_SPEED, speed);
mac_ctrl &= ~(MAC_CTRL_DUPLX | MAC_CTRL_RX_EN | MAC_CTRL_TX_EN);
if (adapter->link_duplex == FULL_DUPLEX)
mac_ctrl |= MAC_CTRL_DUPLX;
phy_ctrl &= ~(GPHY_CTRL_EXT_RESET | GPHY_CTRL_CLS);
phy_ctrl |= GPHY_CTRL_SEL_ANA_RST | GPHY_CTRL_HIB_PULSE |
GPHY_CTRL_HIB_EN;
if (!wufc) { /* without WoL */
master_ctrl |= MASTER_CTRL_CLK_SEL_DIS;
phy_ctrl |= GPHY_CTRL_PHY_IDDQ | GPHY_CTRL_PWDOWN_HW;
AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl);
AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl);
AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl);
AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
hw->phy_configured = false; /* re-init PHY when resume */
return 0;
}
phy_ctrl |= GPHY_CTRL_EXT_RESET;
if (wufc & AT_WUFC_MAG) {
mac_ctrl |= MAC_CTRL_RX_EN | MAC_CTRL_BC_EN;
wol_ctrl |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
if (hw->nic_type == athr_l2c_b && hw->revision_id == L2CB_V11)
wol_ctrl |= WOL_PATTERN_EN | WOL_PATTERN_PME_EN;
}
if (wufc & AT_WUFC_LNKC) {
wol_ctrl |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) {
dev_dbg(&pdev->dev, "%s: write phy MII_IER failed.\n",
atl1c_driver_name);
}
}
/* clear PHY interrupt */
atl1c_read_phy_reg(hw, MII_ISR, &phy_data);
dev_dbg(&pdev->dev, "%s: suspend MAC=%x,MASTER=%x,PHY=0x%x,WOL=%x\n",
atl1c_driver_name, mac_ctrl, master_ctrl, phy_ctrl, wol_ctrl);
AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl);
AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl);
AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl);
AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl);
return 0;
}
/* configure phy after Link change Event */
void atl1c_post_phy_linkchg(struct atl1c_hw *hw, u16 link_speed)
{
u16 phy_val;
bool adj_thresh = false;
if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2 ||
hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2)
adj_thresh = true;
if (link_speed != SPEED_0) { /* link up */
/* az with brcm, half-amp */
if (hw->nic_type == athr_l1d_2) {
atl1c_read_phy_ext(hw, MIIEXT_PCS, MIIEXT_CLDCTRL6,
&phy_val);
phy_val = FIELD_GETX(phy_val, CLDCTRL6_CAB_LEN);
phy_val = phy_val > CLDCTRL6_CAB_LEN_SHORT ?
AZ_ANADECT_LONG : AZ_ANADECT_DEF;
atl1c_write_phy_dbg(hw, MIIDBG_AZ_ANADECT, phy_val);
}
/* threshold adjust */
if (adj_thresh && link_speed == SPEED_100 && hw->msi_lnkpatch) {
atl1c_write_phy_dbg(hw, MIIDBG_MSE16DB, L1D_MSE16DB_UP);
atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
L1D_SYSMODCTRL_IECHOADJ_DEF);
}
} else { /* link down */
if (adj_thresh && hw->msi_lnkpatch) {
atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
SYSMODCTRL_IECHOADJ_DEF);
atl1c_write_phy_dbg(hw, MIIDBG_MSE16DB,
L1D_MSE16DB_DOWN);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
obj-m += atl1c.o
atl1c-objs := atl1c_main.o atl1c_hw.o atl1c_ethtool.o

View File

@@ -1,605 +0,0 @@
/*
* Copyright(c) 2008 - 2009 Atheros Corporation. All rights reserved.
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _ATL1C_H_
#define _ATL1C_H_
#include <linux/interrupt.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/udp.h>
#include <linux/mii.h>
#include <linux/io.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/tcp.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/workqueue.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
#include "atl1c_hw.h"
/* Wake Up Filter Control */
#define AT_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
#define AT_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */
#define AT_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */
#define AT_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */
#define AT_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */
#define AT_VLAN_TO_TAG(_vlan, _tag) \
_tag = ((((_vlan) >> 8) & 0xFF) |\
(((_vlan) & 0xFF) << 8))
#define AT_TAG_TO_VLAN(_tag, _vlan) \
_vlan = ((((_tag) >> 8) & 0xFF) |\
(((_tag) & 0xFF) << 8))
#define SPEED_0 0xffff
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2
#define AT_RX_BUF_SIZE (ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN)
#define MAX_JUMBO_FRAME_SIZE (6*1024)
#define AT_MAX_RECEIVE_QUEUE 4
#define AT_DEF_RECEIVE_QUEUE 1
#define AT_MAX_TRANSMIT_QUEUE 2
#define AT_DMA_HI_ADDR_MASK 0xffffffff00000000ULL
#define AT_DMA_LO_ADDR_MASK 0x00000000ffffffffULL
#define AT_TX_WATCHDOG (5 * HZ)
#define AT_MAX_INT_WORK 5
#define AT_TWSI_EEPROM_TIMEOUT 100
#define AT_HW_MAX_IDLE_DELAY 10
#define AT_SUSPEND_LINK_TIMEOUT 100
#define AT_ASPM_L0S_TIMER 6
#define AT_ASPM_L1_TIMER 12
#define AT_LCKDET_TIMER 12
#define ATL1C_PCIE_L0S_L1_DISABLE 0x01
#define ATL1C_PCIE_PHY_RESET 0x02
#define ATL1C_ASPM_L0s_ENABLE 0x0001
#define ATL1C_ASPM_L1_ENABLE 0x0002
#define AT_REGS_LEN (74 * sizeof(u32))
#define AT_EEPROM_LEN 512
#define ATL1C_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i]))
#define ATL1C_RFD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_rx_free_desc)
#define ATL1C_TPD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_tpd_desc)
#define ATL1C_RRD_DESC(R, i) ATL1C_GET_DESC(R, i, struct atl1c_recv_ret_status)
/* tpd word 1 bit 0:7 General Checksum task offload */
#define TPD_L4HDR_OFFSET_MASK 0x00FF
#define TPD_L4HDR_OFFSET_SHIFT 0
/* tpd word 1 bit 0:7 Large Send task offload (IPv4/IPV6) */
#define TPD_TCPHDR_OFFSET_MASK 0x00FF
#define TPD_TCPHDR_OFFSET_SHIFT 0
/* tpd word 1 bit 0:7 Custom Checksum task offload */
#define TPD_PLOADOFFSET_MASK 0x00FF
#define TPD_PLOADOFFSET_SHIFT 0
/* tpd word 1 bit 8:17 */
#define TPD_CCSUM_EN_MASK 0x0001
#define TPD_CCSUM_EN_SHIFT 8
#define TPD_IP_CSUM_MASK 0x0001
#define TPD_IP_CSUM_SHIFT 9
#define TPD_TCP_CSUM_MASK 0x0001
#define TPD_TCP_CSUM_SHIFT 10
#define TPD_UDP_CSUM_MASK 0x0001
#define TPD_UDP_CSUM_SHIFT 11
#define TPD_LSO_EN_MASK 0x0001 /* TCP Large Send Offload */
#define TPD_LSO_EN_SHIFT 12
#define TPD_LSO_VER_MASK 0x0001
#define TPD_LSO_VER_SHIFT 13 /* 0 : ipv4; 1 : ipv4/ipv6 */
#define TPD_CON_VTAG_MASK 0x0001
#define TPD_CON_VTAG_SHIFT 14
#define TPD_INS_VTAG_MASK 0x0001
#define TPD_INS_VTAG_SHIFT 15
#define TPD_IPV4_PACKET_MASK 0x0001 /* valid when LSO VER is 1 */
#define TPD_IPV4_PACKET_SHIFT 16
#define TPD_ETH_TYPE_MASK 0x0001
#define TPD_ETH_TYPE_SHIFT 17 /* 0 : 802.3 frame; 1 : Ethernet */
/* tpd word 18:25 Custom Checksum task offload */
#define TPD_CCSUM_OFFSET_MASK 0x00FF
#define TPD_CCSUM_OFFSET_SHIFT 18
#define TPD_CCSUM_EPAD_MASK 0x0001
#define TPD_CCSUM_EPAD_SHIFT 30
/* tpd word 18:30 Large Send task offload (IPv4/IPV6) */
#define TPD_MSS_MASK 0x1FFF
#define TPD_MSS_SHIFT 18
#define TPD_EOP_MASK 0x0001
#define TPD_EOP_SHIFT 31
struct atl1c_tpd_desc {
__le16 buffer_len; /* include 4-byte CRC */
__le16 vlan_tag;
__le32 word1;
__le64 buffer_addr;
};
struct atl1c_tpd_ext_desc {
u32 reservd_0;
__le32 word1;
__le32 pkt_len;
u32 reservd_1;
};
/* rrs word 0 bit 0:31 */
#define RRS_RX_CSUM_MASK 0xFFFF
#define RRS_RX_CSUM_SHIFT 0
#define RRS_RX_RFD_CNT_MASK 0x000F
#define RRS_RX_RFD_CNT_SHIFT 16
#define RRS_RX_RFD_INDEX_MASK 0x0FFF
#define RRS_RX_RFD_INDEX_SHIFT 20
/* rrs flag bit 0:16 */
#define RRS_HEAD_LEN_MASK 0x00FF
#define RRS_HEAD_LEN_SHIFT 0
#define RRS_HDS_TYPE_MASK 0x0003
#define RRS_HDS_TYPE_SHIFT 8
#define RRS_CPU_NUM_MASK 0x0003
#define RRS_CPU_NUM_SHIFT 10
#define RRS_HASH_FLG_MASK 0x000F
#define RRS_HASH_FLG_SHIFT 12
#define RRS_HDS_TYPE_HEAD 1
#define RRS_HDS_TYPE_DATA 2
#define RRS_IS_NO_HDS_TYPE(flag) \
((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == 0)
#define RRS_IS_HDS_HEAD(flag) \
((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
RRS_HDS_TYPE_HEAD)
#define RRS_IS_HDS_DATA(flag) \
((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
RRS_HDS_TYPE_DATA)
/* rrs word 3 bit 0:31 */
#define RRS_PKT_SIZE_MASK 0x3FFF
#define RRS_PKT_SIZE_SHIFT 0
#define RRS_ERR_L4_CSUM_MASK 0x0001
#define RRS_ERR_L4_CSUM_SHIFT 14
#define RRS_ERR_IP_CSUM_MASK 0x0001
#define RRS_ERR_IP_CSUM_SHIFT 15
#define RRS_VLAN_INS_MASK 0x0001
#define RRS_VLAN_INS_SHIFT 16
#define RRS_PROT_ID_MASK 0x0007
#define RRS_PROT_ID_SHIFT 17
#define RRS_RX_ERR_SUM_MASK 0x0001
#define RRS_RX_ERR_SUM_SHIFT 20
#define RRS_RX_ERR_CRC_MASK 0x0001
#define RRS_RX_ERR_CRC_SHIFT 21
#define RRS_RX_ERR_FAE_MASK 0x0001
#define RRS_RX_ERR_FAE_SHIFT 22
#define RRS_RX_ERR_TRUNC_MASK 0x0001
#define RRS_RX_ERR_TRUNC_SHIFT 23
#define RRS_RX_ERR_RUNC_MASK 0x0001
#define RRS_RX_ERR_RUNC_SHIFT 24
#define RRS_RX_ERR_ICMP_MASK 0x0001
#define RRS_RX_ERR_ICMP_SHIFT 25
#define RRS_PACKET_BCAST_MASK 0x0001
#define RRS_PACKET_BCAST_SHIFT 26
#define RRS_PACKET_MCAST_MASK 0x0001
#define RRS_PACKET_MCAST_SHIFT 27
#define RRS_PACKET_TYPE_MASK 0x0001
#define RRS_PACKET_TYPE_SHIFT 28
#define RRS_FIFO_FULL_MASK 0x0001
#define RRS_FIFO_FULL_SHIFT 29
#define RRS_802_3_LEN_ERR_MASK 0x0001
#define RRS_802_3_LEN_ERR_SHIFT 30
#define RRS_RXD_UPDATED_MASK 0x0001
#define RRS_RXD_UPDATED_SHIFT 31
#define RRS_ERR_L4_CSUM 0x00004000
#define RRS_ERR_IP_CSUM 0x00008000
#define RRS_VLAN_INS 0x00010000
#define RRS_RX_ERR_SUM 0x00100000
#define RRS_RX_ERR_CRC 0x00200000
#define RRS_802_3_LEN_ERR 0x40000000
#define RRS_RXD_UPDATED 0x80000000
#define RRS_PACKET_TYPE_802_3 1
#define RRS_PACKET_TYPE_ETH 0
#define RRS_PACKET_IS_ETH(word) \
((((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK) == \
RRS_PACKET_TYPE_ETH)
#define RRS_RXD_IS_VALID(word) \
((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1)
#define RRS_PACKET_PROT_IS_IPV4_ONLY(word) \
((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 1)
#define RRS_PACKET_PROT_IS_IPV6_ONLY(word) \
((((word) >> RRS_PROT_ID_SHIFT) & RRS_PROT_ID_MASK) == 6)
struct atl1c_recv_ret_status {
__le32 word0;
__le32 rss_hash;
__le16 vlan_tag;
__le16 flag;
__le32 word3;
};
/* RFD descriptor */
struct atl1c_rx_free_desc {
__le64 buffer_addr;
};
/* DMA Order Settings */
enum atl1c_dma_order {
atl1c_dma_ord_in = 1,
atl1c_dma_ord_enh = 2,
atl1c_dma_ord_out = 4
};
enum atl1c_dma_rcb {
atl1c_rcb_64 = 0,
atl1c_rcb_128 = 1
};
enum atl1c_mac_speed {
atl1c_mac_speed_0 = 0,
atl1c_mac_speed_10_100 = 1,
atl1c_mac_speed_1000 = 2
};
enum atl1c_dma_req_block {
atl1c_dma_req_128 = 0,
atl1c_dma_req_256 = 1,
atl1c_dma_req_512 = 2,
atl1c_dma_req_1024 = 3,
atl1c_dma_req_2048 = 4,
atl1c_dma_req_4096 = 5
};
enum atl1c_nic_type {
athr_l1c = 0,
athr_l2c = 1,
athr_l2c_b,
athr_l2c_b2,
athr_l1d,
athr_l1d_2,
};
enum atl1c_trans_queue {
atl1c_trans_normal = 0,
atl1c_trans_high = 1
};
struct atl1c_hw_stats {
/* rx */
unsigned long rx_ok; /* The number of good packet received. */
unsigned long rx_bcast; /* The number of good broadcast packet received. */
unsigned long rx_mcast; /* The number of good multicast packet received. */
unsigned long rx_pause; /* The number of Pause packet received. */
unsigned long rx_ctrl; /* The number of Control packet received other than Pause frame. */
unsigned long rx_fcs_err; /* The number of packets with bad FCS. */
unsigned long rx_len_err; /* The number of packets with mismatch of length field and actual size. */
unsigned long rx_byte_cnt; /* The number of bytes of good packet received. FCS is NOT included. */
unsigned long rx_runt; /* The number of packets received that are less than 64 byte long and with good FCS. */
unsigned long rx_frag; /* The number of packets received that are less than 64 byte long and with bad FCS. */
unsigned long rx_sz_64; /* The number of good and bad packets received that are 64 byte long. */
unsigned long rx_sz_65_127; /* The number of good and bad packets received that are between 65 and 127-byte long. */
unsigned long rx_sz_128_255; /* The number of good and bad packets received that are between 128 and 255-byte long. */
unsigned long rx_sz_256_511; /* The number of good and bad packets received that are between 256 and 511-byte long. */
unsigned long rx_sz_512_1023; /* The number of good and bad packets received that are between 512 and 1023-byte long. */
unsigned long rx_sz_1024_1518; /* The number of good and bad packets received that are between 1024 and 1518-byte long. */
unsigned long rx_sz_1519_max; /* The number of good and bad packets received that are between 1519-byte and MTU. */
unsigned long rx_sz_ov; /* The number of good and bad packets received that are more than MTU size truncated by Selene. */
unsigned long rx_rxf_ov; /* The number of frame dropped due to occurrence of RX FIFO overflow. */
unsigned long rx_rrd_ov; /* The number of frame dropped due to occurrence of RRD overflow. */
unsigned long rx_align_err; /* Alignment Error */
unsigned long rx_bcast_byte_cnt; /* The byte count of broadcast packet received, excluding FCS. */
unsigned long rx_mcast_byte_cnt; /* The byte count of multicast packet received, excluding FCS. */
unsigned long rx_err_addr; /* The number of packets dropped due to address filtering. */
/* tx */
unsigned long tx_ok; /* The number of good packet transmitted. */
unsigned long tx_bcast; /* The number of good broadcast packet transmitted. */
unsigned long tx_mcast; /* The number of good multicast packet transmitted. */
unsigned long tx_pause; /* The number of Pause packet transmitted. */
unsigned long tx_exc_defer; /* The number of packets transmitted with excessive deferral. */
unsigned long tx_ctrl; /* The number of packets transmitted is a control frame, excluding Pause frame. */
unsigned long tx_defer; /* The number of packets transmitted that is deferred. */
unsigned long tx_byte_cnt; /* The number of bytes of data transmitted. FCS is NOT included. */
unsigned long tx_sz_64; /* The number of good and bad packets transmitted that are 64 byte long. */
unsigned long tx_sz_65_127; /* The number of good and bad packets transmitted that are between 65 and 127-byte long. */
unsigned long tx_sz_128_255; /* The number of good and bad packets transmitted that are between 128 and 255-byte long. */
unsigned long tx_sz_256_511; /* The number of good and bad packets transmitted that are between 256 and 511-byte long. */
unsigned long tx_sz_512_1023; /* The number of good and bad packets transmitted that are between 512 and 1023-byte long. */
unsigned long tx_sz_1024_1518; /* The number of good and bad packets transmitted that are between 1024 and 1518-byte long. */
unsigned long tx_sz_1519_max; /* The number of good and bad packets transmitted that are between 1519-byte and MTU. */
unsigned long tx_1_col; /* The number of packets subsequently transmitted successfully with a single prior collision. */
unsigned long tx_2_col; /* The number of packets subsequently transmitted successfully with multiple prior collisions. */
unsigned long tx_late_col; /* The number of packets transmitted with late collisions. */
unsigned long tx_abort_col; /* The number of transmit packets aborted due to excessive collisions. */
unsigned long tx_underrun; /* The number of transmit packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
unsigned long tx_rd_eop; /* The number of times that read beyond the EOP into the next frame area when TRD was not written timely */
unsigned long tx_len_err; /* The number of transmit packets with length field does NOT match the actual frame size. */
unsigned long tx_trunc; /* The number of transmit packets truncated due to size exceeding MTU. */
unsigned long tx_bcast_byte; /* The byte count of broadcast packet transmitted, excluding FCS. */
unsigned long tx_mcast_byte; /* The byte count of multicast packet transmitted, excluding FCS. */
};
struct atl1c_hw {
u8 __iomem *hw_addr; /* inner register address */
struct atl1c_adapter *adapter;
enum atl1c_nic_type nic_type;
enum atl1c_dma_order dma_order;
enum atl1c_dma_rcb rcb_value;
enum atl1c_dma_req_block dmar_block;
u16 device_id;
u16 vendor_id;
u16 subsystem_id;
u16 subsystem_vendor_id;
u8 revision_id;
u16 phy_id1;
u16 phy_id2;
u32 intr_mask;
u8 preamble_len;
u16 max_frame_size;
u16 min_frame_size;
enum atl1c_mac_speed mac_speed;
bool mac_duplex;
bool hibernate;
u16 media_type;
#define MEDIA_TYPE_AUTO_SENSOR 0
#define MEDIA_TYPE_100M_FULL 1
#define MEDIA_TYPE_100M_HALF 2
#define MEDIA_TYPE_10M_FULL 3
#define MEDIA_TYPE_10M_HALF 4
u16 autoneg_advertised;
u16 mii_autoneg_adv_reg;
u16 mii_1000t_ctrl_reg;
u16 tx_imt; /* TX Interrupt Moderator timer ( 2us resolution) */
u16 rx_imt; /* RX Interrupt Moderator timer ( 2us resolution) */
u16 ict; /* Interrupt Clear timer (2us resolution) */
u16 ctrl_flags;
#define ATL1C_INTR_CLEAR_ON_READ 0x0001
#define ATL1C_INTR_MODRT_ENABLE 0x0002
#define ATL1C_CMB_ENABLE 0x0004
#define ATL1C_SMB_ENABLE 0x0010
#define ATL1C_TXQ_MODE_ENHANCE 0x0020
#define ATL1C_RX_IPV6_CHKSUM 0x0040
#define ATL1C_ASPM_L0S_SUPPORT 0x0080
#define ATL1C_ASPM_L1_SUPPORT 0x0100
#define ATL1C_ASPM_CTRL_MON 0x0200
#define ATL1C_HIB_DISABLE 0x0400
#define ATL1C_APS_MODE_ENABLE 0x0800
#define ATL1C_LINK_EXT_SYNC 0x1000
#define ATL1C_CLK_GATING_EN 0x2000
#define ATL1C_FPGA_VERSION 0x8000
u16 link_cap_flags;
#define ATL1C_LINK_CAP_1000M 0x0001
u32 smb_timer;
u16 rrd_thresh; /* Threshold of number of RRD produced to trigger
interrupt request */
u16 tpd_thresh;
u8 tpd_burst; /* Number of TPD to prefetch in cache-aligned burst. */
u8 rfd_burst;
u32 base_cpu;
u32 indirect_tab;
u8 mac_addr[ETH_ALEN];
u8 perm_mac_addr[ETH_ALEN];
bool phy_configured;
bool re_autoneg;
bool emi_ca;
bool msi_lnkpatch; /* link patch for specific platforms */
};
/*
* atl1c_ring_header represents a single, contiguous block of DMA space
* mapped for the three descriptor rings (tpd, rfd, rrd) described below
*/
struct atl1c_ring_header {
void *desc; /* virtual address */
dma_addr_t dma; /* physical address*/
unsigned int size; /* length in bytes */
};
/*
* atl1c_buffer is wrapper around a pointer to a socket buffer
* so a DMA handle can be stored along with the skb
*/
struct atl1c_buffer {
struct sk_buff *skb; /* socket buffer */
u16 length; /* rx buffer length */
u16 flags; /* information of buffer */
#define ATL1C_BUFFER_FREE 0x0001
#define ATL1C_BUFFER_BUSY 0x0002
#define ATL1C_BUFFER_STATE_MASK 0x0003
#define ATL1C_PCIMAP_SINGLE 0x0004
#define ATL1C_PCIMAP_PAGE 0x0008
#define ATL1C_PCIMAP_TYPE_MASK 0x000C
#define ATL1C_PCIMAP_TODEVICE 0x0010
#define ATL1C_PCIMAP_FROMDEVICE 0x0020
#define ATL1C_PCIMAP_DIRECTION_MASK 0x0030
dma_addr_t dma;
};
#define ATL1C_SET_BUFFER_STATE(buff, state) do { \
((buff)->flags) &= ~ATL1C_BUFFER_STATE_MASK; \
((buff)->flags) |= (state); \
} while (0)
#define ATL1C_SET_PCIMAP_TYPE(buff, type, direction) do { \
((buff)->flags) &= ~ATL1C_PCIMAP_TYPE_MASK; \
((buff)->flags) |= (type); \
((buff)->flags) &= ~ATL1C_PCIMAP_DIRECTION_MASK; \
((buff)->flags) |= (direction); \
} while (0)
/* transimit packet descriptor (tpd) ring */
struct atl1c_tpd_ring {
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
u16 size; /* descriptor ring length in bytes */
u16 count; /* number of descriptors in the ring */
u16 next_to_use; /* this is protectd by adapter->tx_lock */
atomic_t next_to_clean;
struct atl1c_buffer *buffer_info;
};
/* receive free descriptor (rfd) ring */
struct atl1c_rfd_ring {
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
u16 size; /* descriptor ring length in bytes */
u16 count; /* number of descriptors in the ring */
u16 next_to_use;
u16 next_to_clean;
struct atl1c_buffer *buffer_info;
};
/* receive return descriptor (rrd) ring */
struct atl1c_rrd_ring {
void *desc; /* descriptor ring virtual address */
dma_addr_t dma; /* descriptor ring physical address */
u16 size; /* descriptor ring length in bytes */
u16 count; /* number of descriptors in the ring */
u16 next_to_use;
u16 next_to_clean;
};
/* board specific private data structure */
struct atl1c_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
struct napi_struct napi;
struct page *rx_page;
unsigned int rx_page_offset;
unsigned int rx_frag_size;
struct atl1c_hw hw;
struct atl1c_hw_stats hw_stats;
struct mii_if_info mii; /* MII interface info */
u16 rx_buffer_len;
unsigned long flags;
#define __AT_TESTING 0x0001
#define __AT_RESETTING 0x0002
#define __AT_DOWN 0x0003
unsigned long work_event;
#define ATL1C_WORK_EVENT_RESET 0
#define ATL1C_WORK_EVENT_LINK_CHANGE 1
u32 msg_enable;
bool have_msi;
u32 wol;
u16 link_speed;
u16 link_duplex;
spinlock_t mdio_lock;
spinlock_t tx_lock;
atomic_t irq_sem;
struct work_struct common_task;
struct timer_list watchdog_timer;
struct timer_list phy_config_timer;
/* All Descriptor memory */
struct atl1c_ring_header ring_header;
struct atl1c_tpd_ring tpd_ring[AT_MAX_TRANSMIT_QUEUE];
struct atl1c_rfd_ring rfd_ring;
struct atl1c_rrd_ring rrd_ring;
u32 bd_number; /* board number;*/
};
#define AT_WRITE_REG(a, reg, value) ( \
writel((value), ((a)->hw_addr + reg)))
#define AT_WRITE_FLUSH(a) (\
readl((a)->hw_addr))
#define AT_READ_REG(a, reg, pdata) do { \
if (unlikely((a)->hibernate)) { \
readl((a)->hw_addr + reg); \
*(u32 *)pdata = readl((a)->hw_addr + reg); \
} else { \
*(u32 *)pdata = readl((a)->hw_addr + reg); \
} \
} while (0)
#define AT_WRITE_REGB(a, reg, value) (\
writeb((value), ((a)->hw_addr + reg)))
#define AT_READ_REGB(a, reg) (\
readb((a)->hw_addr + reg))
#define AT_WRITE_REGW(a, reg, value) (\
writew((value), ((a)->hw_addr + reg)))
#define AT_READ_REGW(a, reg, pdata) do { \
if (unlikely((a)->hibernate)) { \
readw((a)->hw_addr + reg); \
*(u16 *)pdata = readw((a)->hw_addr + reg); \
} else { \
*(u16 *)pdata = readw((a)->hw_addr + reg); \
} \
} while (0)
#define AT_WRITE_REG_ARRAY(a, reg, offset, value) ( \
writel((value), (((a)->hw_addr + reg) + ((offset) << 2))))
#define AT_READ_REG_ARRAY(a, reg, offset) ( \
readl(((a)->hw_addr + reg) + ((offset) << 2)))
extern char atl1c_driver_name[];
extern char atl1c_driver_version[];
void atl1c_reinit_locked(struct atl1c_adapter *adapter);
s32 atl1c_reset_hw(struct atl1c_hw *hw);
void atl1c_set_ethtool_ops(struct net_device *netdev);
#endif /* _ATL1C_H_ */

View File

@@ -1,305 +0,0 @@
/*
* Copyright(c) 2009 - 2009 Atheros Corporation. All rights reserved.
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include <linux/netdevice.h>
#include <linux/ethtool.h>
#include <linux/slab.h>
#include "atl1c.h"
static int atl1c_get_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw *hw = &adapter->hw;
ecmd->supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg |
SUPPORTED_TP);
if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M)
ecmd->supported |= SUPPORTED_1000baseT_Full;
ecmd->advertising = ADVERTISED_TP;
ecmd->advertising |= hw->autoneg_advertised;
ecmd->port = PORT_TP;
ecmd->phy_address = 0;
ecmd->transceiver = XCVR_INTERNAL;
if (adapter->link_speed != SPEED_0) {
ethtool_cmd_speed_set(ecmd, adapter->link_speed);
if (adapter->link_duplex == FULL_DUPLEX)
ecmd->duplex = DUPLEX_FULL;
else
ecmd->duplex = DUPLEX_HALF;
} else {
ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
ecmd->duplex = DUPLEX_UNKNOWN;
}
ecmd->autoneg = AUTONEG_ENABLE;
return 0;
}
static int atl1c_set_settings(struct net_device *netdev,
struct ethtool_cmd *ecmd)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw *hw = &adapter->hw;
u16 autoneg_advertised;
while (test_and_set_bit(__AT_RESETTING, &adapter->flags))
msleep(1);
if (ecmd->autoneg == AUTONEG_ENABLE) {
autoneg_advertised = ADVERTISED_Autoneg;
} else {
u32 speed = ethtool_cmd_speed(ecmd);
if (speed == SPEED_1000) {
if (ecmd->duplex != DUPLEX_FULL) {
if (netif_msg_link(adapter))
dev_warn(&adapter->pdev->dev,
"1000M half is invalid\n");
clear_bit(__AT_RESETTING, &adapter->flags);
return -EINVAL;
}
autoneg_advertised = ADVERTISED_1000baseT_Full;
} else if (speed == SPEED_100) {
if (ecmd->duplex == DUPLEX_FULL)
autoneg_advertised = ADVERTISED_100baseT_Full;
else
autoneg_advertised = ADVERTISED_100baseT_Half;
} else {
if (ecmd->duplex == DUPLEX_FULL)
autoneg_advertised = ADVERTISED_10baseT_Full;
else
autoneg_advertised = ADVERTISED_10baseT_Half;
}
}
if (hw->autoneg_advertised != autoneg_advertised) {
hw->autoneg_advertised = autoneg_advertised;
if (atl1c_restart_autoneg(hw) != 0) {
if (netif_msg_link(adapter))
dev_warn(&adapter->pdev->dev,
"ethtool speed/duplex setting failed\n");
clear_bit(__AT_RESETTING, &adapter->flags);
return -EINVAL;
}
}
clear_bit(__AT_RESETTING, &adapter->flags);
return 0;
}
static u32 atl1c_get_msglevel(struct net_device *netdev)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
return adapter->msg_enable;
}
static void atl1c_set_msglevel(struct net_device *netdev, u32 data)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
adapter->msg_enable = data;
}
static int atl1c_get_regs_len(struct net_device *netdev)
{
return AT_REGS_LEN;
}
static void atl1c_get_regs(struct net_device *netdev,
struct ethtool_regs *regs, void *p)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw *hw = &adapter->hw;
u32 *regs_buff = p;
u16 phy_data;
memset(p, 0, AT_REGS_LEN);
regs->version = 1;
AT_READ_REG(hw, REG_PM_CTRL, p++);
AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL, p++);
AT_READ_REG(hw, REG_TWSI_CTRL, p++);
AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL, p++);
AT_READ_REG(hw, REG_MASTER_CTRL, p++);
AT_READ_REG(hw, REG_MANUAL_TIMER_INIT, p++);
AT_READ_REG(hw, REG_IRQ_MODRT_TIMER_INIT, p++);
AT_READ_REG(hw, REG_GPHY_CTRL, p++);
AT_READ_REG(hw, REG_LINK_CTRL, p++);
AT_READ_REG(hw, REG_IDLE_STATUS, p++);
AT_READ_REG(hw, REG_MDIO_CTRL, p++);
AT_READ_REG(hw, REG_SERDES, p++);
AT_READ_REG(hw, REG_MAC_CTRL, p++);
AT_READ_REG(hw, REG_MAC_IPG_IFG, p++);
AT_READ_REG(hw, REG_MAC_STA_ADDR, p++);
AT_READ_REG(hw, REG_MAC_STA_ADDR+4, p++);
AT_READ_REG(hw, REG_RX_HASH_TABLE, p++);
AT_READ_REG(hw, REG_RX_HASH_TABLE+4, p++);
AT_READ_REG(hw, REG_RXQ_CTRL, p++);
AT_READ_REG(hw, REG_TXQ_CTRL, p++);
AT_READ_REG(hw, REG_MTU, p++);
AT_READ_REG(hw, REG_WOL_CTRL, p++);
atl1c_read_phy_reg(hw, MII_BMCR, &phy_data);
regs_buff[AT_REGS_LEN/sizeof(u32) - 2] = (u32) phy_data;
atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
regs_buff[AT_REGS_LEN/sizeof(u32) - 1] = (u32) phy_data;
}
static int atl1c_get_eeprom_len(struct net_device *netdev)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
if (atl1c_check_eeprom_exist(&adapter->hw))
return AT_EEPROM_LEN;
else
return 0;
}
static int atl1c_get_eeprom(struct net_device *netdev,
struct ethtool_eeprom *eeprom, u8 *bytes)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
struct atl1c_hw *hw = &adapter->hw;
u32 *eeprom_buff;
int first_dword, last_dword;
int ret_val = 0;
int i;
if (eeprom->len == 0)
return -EINVAL;
if (!atl1c_check_eeprom_exist(hw)) /* not exist */
return -EINVAL;
eeprom->magic = adapter->pdev->vendor |
(adapter->pdev->device << 16);
first_dword = eeprom->offset >> 2;
last_dword = (eeprom->offset + eeprom->len - 1) >> 2;
eeprom_buff = kmalloc(sizeof(u32) *
(last_dword - first_dword + 1), GFP_KERNEL);
if (eeprom_buff == NULL)
return -ENOMEM;
for (i = first_dword; i < last_dword; i++) {
if (!atl1c_read_eeprom(hw, i * 4, &(eeprom_buff[i-first_dword]))) {
kfree(eeprom_buff);
return -EIO;
}
}
memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3),
eeprom->len);
kfree(eeprom_buff);
return ret_val;
return 0;
}
static void atl1c_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
strlcpy(drvinfo->driver, atl1c_driver_name, sizeof(drvinfo->driver));
strlcpy(drvinfo->version, atl1c_driver_version,
sizeof(drvinfo->version));
strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
sizeof(drvinfo->bus_info));
}
static void atl1c_get_wol(struct net_device *netdev,
struct ethtool_wolinfo *wol)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
wol->supported = WAKE_MAGIC | WAKE_PHY;
wol->wolopts = 0;
if (adapter->wol & AT_WUFC_EX)
wol->wolopts |= WAKE_UCAST;
if (adapter->wol & AT_WUFC_MC)
wol->wolopts |= WAKE_MCAST;
if (adapter->wol & AT_WUFC_BC)
wol->wolopts |= WAKE_BCAST;
if (adapter->wol & AT_WUFC_MAG)
wol->wolopts |= WAKE_MAGIC;
if (adapter->wol & AT_WUFC_LNKC)
wol->wolopts |= WAKE_PHY;
}
static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
return -EOPNOTSUPP;
/* these settings will always override what we currently have */
adapter->wol = 0;
if (wol->wolopts & WAKE_MAGIC)
adapter->wol |= AT_WUFC_MAG;
if (wol->wolopts & WAKE_PHY)
adapter->wol |= AT_WUFC_LNKC;
device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
return 0;
}
static int atl1c_nway_reset(struct net_device *netdev)
{
struct atl1c_adapter *adapter = netdev_priv(netdev);
if (netif_running(netdev))
atl1c_reinit_locked(adapter);
return 0;
}
static const struct ethtool_ops atl1c_ethtool_ops = {
.get_settings = atl1c_get_settings,
.set_settings = atl1c_set_settings,
.get_drvinfo = atl1c_get_drvinfo,
.get_regs_len = atl1c_get_regs_len,
.get_regs = atl1c_get_regs,
.get_wol = atl1c_get_wol,
.set_wol = atl1c_set_wol,
.get_msglevel = atl1c_get_msglevel,
.set_msglevel = atl1c_set_msglevel,
.nway_reset = atl1c_nway_reset,
.get_link = ethtool_op_get_link,
.get_eeprom_len = atl1c_get_eeprom_len,
.get_eeprom = atl1c_get_eeprom,
};
void atl1c_set_ethtool_ops(struct net_device *netdev)
{
netdev->ethtool_ops = &atl1c_ethtool_ops;
}

View File

@@ -1,863 +0,0 @@
/*
* Copyright(c) 2007 Atheros Corporation. All rights reserved.
*
* Derived from Intel e1000 driver
* Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59
* Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mii.h>
#include <linux/crc32.h>
#include "atl1c.h"
/*
* check_eeprom_exist
* return 1 if eeprom exist
*/
int atl1c_check_eeprom_exist(struct atl1c_hw *hw)
{
u32 data;
AT_READ_REG(hw, REG_TWSI_DEBUG, &data);
if (data & TWSI_DEBUG_DEV_EXIST)
return 1;
AT_READ_REG(hw, REG_MASTER_CTRL, &data);
if (data & MASTER_CTRL_OTP_SEL)
return 1;
return 0;
}
void atl1c_hw_set_mac_addr(struct atl1c_hw *hw, u8 *mac_addr)
{
u32 value;
/*
* 00-0B-6A-F6-00-DC
* 0: 6AF600DC 1: 000B
* low dword
*/
value = mac_addr[2] << 24 |
mac_addr[3] << 16 |
mac_addr[4] << 8 |
mac_addr[5];
AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
/* hight dword */
value = mac_addr[0] << 8 |
mac_addr[1];
AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
}
/* read mac address from hardware register */
static bool atl1c_read_current_addr(struct atl1c_hw *hw, u8 *eth_addr)
{
u32 addr[2];
AT_READ_REG(hw, REG_MAC_STA_ADDR, &addr[0]);
AT_READ_REG(hw, REG_MAC_STA_ADDR + 4, &addr[1]);
*(u32 *) &eth_addr[2] = htonl(addr[0]);
*(u16 *) &eth_addr[0] = htons((u16)addr[1]);
return is_valid_ether_addr(eth_addr);
}
/*
* atl1c_get_permanent_address
* return 0 if get valid mac address,
*/
static int atl1c_get_permanent_address(struct atl1c_hw *hw)
{
u32 i;
u32 otp_ctrl_data;
u32 twsi_ctrl_data;
u16 phy_data;
bool raise_vol = false;
/* MAC-address from BIOS is the 1st priority */
if (atl1c_read_current_addr(hw, hw->perm_mac_addr))
return 0;
/* init */
AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
if (atl1c_check_eeprom_exist(hw)) {
if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c) {
/* Enable OTP CLK */
if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
otp_ctrl_data |= OTP_CTRL_CLK_EN;
AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
AT_WRITE_FLUSH(hw);
msleep(1);
}
}
/* raise voltage temporally for l2cb */
if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
atl1c_read_phy_dbg(hw, MIIDBG_ANACTRL, &phy_data);
phy_data &= ~ANACTRL_HB_EN;
atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, phy_data);
atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
phy_data |= VOLT_CTRL_SWLOWEST;
atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
udelay(20);
raise_vol = true;
}
AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART;
AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data);
for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) {
msleep(10);
AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0)
break;
}
if (i >= AT_TWSI_EEPROM_TIMEOUT)
return -1;
}
/* Disable OTP_CLK */
if ((hw->nic_type == athr_l1c || hw->nic_type == athr_l2c)) {
otp_ctrl_data &= ~OTP_CTRL_CLK_EN;
AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
msleep(1);
}
if (raise_vol) {
atl1c_read_phy_dbg(hw, MIIDBG_ANACTRL, &phy_data);
phy_data |= ANACTRL_HB_EN;
atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, phy_data);
atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
phy_data &= ~VOLT_CTRL_SWLOWEST;
atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
udelay(20);
}
if (atl1c_read_current_addr(hw, hw->perm_mac_addr))
return 0;
return -1;
}
bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value)
{
int i;
bool ret = false;
u32 otp_ctrl_data;
u32 control;
u32 data;
if (offset & 3)
return ret; /* address do not align */
AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
AT_WRITE_REG(hw, REG_OTP_CTRL,
(otp_ctrl_data | OTP_CTRL_CLK_EN));
AT_WRITE_REG(hw, REG_EEPROM_DATA_LO, 0);
control = (offset & EEPROM_CTRL_ADDR_MASK) << EEPROM_CTRL_ADDR_SHIFT;
AT_WRITE_REG(hw, REG_EEPROM_CTRL, control);
for (i = 0; i < 10; i++) {
udelay(100);
AT_READ_REG(hw, REG_EEPROM_CTRL, &control);
if (control & EEPROM_CTRL_RW)
break;
}
if (control & EEPROM_CTRL_RW) {
AT_READ_REG(hw, REG_EEPROM_CTRL, &data);
AT_READ_REG(hw, REG_EEPROM_DATA_LO, p_value);
data = data & 0xFFFF;
*p_value = swab32((data << 16) | (*p_value >> 16));
ret = true;
}
if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
return ret;
}
/*
* Reads the adapter's MAC address from the EEPROM
*
* hw - Struct containing variables accessed by shared code
*/
int atl1c_read_mac_addr(struct atl1c_hw *hw)
{
int err = 0;
err = atl1c_get_permanent_address(hw);
if (err)
eth_random_addr(hw->perm_mac_addr);
memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
return err;
}
/*
* atl1c_hash_mc_addr
* purpose
* set hash value for a multicast address
* hash calcu processing :
* 1. calcu 32bit CRC for multicast address
* 2. reverse crc with MSB to LSB
*/
u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr)
{
u32 crc32;
u32 value = 0;
int i;
crc32 = ether_crc_le(6, mc_addr);
for (i = 0; i < 32; i++)
value |= (((crc32 >> i) & 1) << (31 - i));
return value;
}
/*
* Sets the bit in the multicast table corresponding to the hash value.
* hw - Struct containing variables accessed by shared code
* hash_value - Multicast address hash value
*/
void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value)
{
u32 hash_bit, hash_reg;
u32 mta;
/*
* The HASH Table is a register array of 2 32-bit registers.
* It is treated like an array of 64 bits. We want to set
* bit BitArray[hash_value]. So we figure out what register
* the bit is in, read it, OR in the new bit, then write
* back the new value. The register is determined by the
* upper bit of the hash value and the bit within that
* register are determined by the lower 5 bits of the value.
*/
hash_reg = (hash_value >> 31) & 0x1;
hash_bit = (hash_value >> 26) & 0x1F;
mta = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
mta |= (1 << hash_bit);
AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
}
/*
* wait mdio module be idle
* return true: idle
* false: still busy
*/
bool atl1c_wait_mdio_idle(struct atl1c_hw *hw)
{
u32 val;
int i;
for (i = 0; i < MDIO_MAX_AC_TO; i++) {
AT_READ_REG(hw, REG_MDIO_CTRL, &val);
if (!(val & (MDIO_CTRL_BUSY | MDIO_CTRL_START)))
break;
udelay(10);
}
return i != MDIO_MAX_AC_TO;
}
void atl1c_stop_phy_polling(struct atl1c_hw *hw)
{
if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
return;
AT_WRITE_REG(hw, REG_MDIO_CTRL, 0);
atl1c_wait_mdio_idle(hw);
}
void atl1c_start_phy_polling(struct atl1c_hw *hw, u16 clk_sel)
{
u32 val;
if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
return;
val = MDIO_CTRL_SPRES_PRMBL |
FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
FIELDX(MDIO_CTRL_REG, 1) |
MDIO_CTRL_START |
MDIO_CTRL_OP_READ;
AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
atl1c_wait_mdio_idle(hw);
val |= MDIO_CTRL_AP_EN;
val &= ~MDIO_CTRL_START;
AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
udelay(30);
}
/*
* atl1c_read_phy_core
* core function to read register in PHY via MDIO control regsiter.
* ext: extension register (see IEEE 802.3)
* dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0)
* reg: reg to read
*/
int atl1c_read_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
u16 reg, u16 *phy_data)
{
u32 val;
u16 clk_sel = MDIO_CTRL_CLK_25_4;
atl1c_stop_phy_polling(hw);
*phy_data = 0;
/* only l2c_b2 & l1d_2 could use slow clock */
if ((hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) &&
hw->hibernate)
clk_sel = MDIO_CTRL_CLK_25_128;
if (ext) {
val = FIELDX(MDIO_EXTN_DEVAD, dev) | FIELDX(MDIO_EXTN_REG, reg);
AT_WRITE_REG(hw, REG_MDIO_EXTN, val);
val = MDIO_CTRL_SPRES_PRMBL |
FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
MDIO_CTRL_START |
MDIO_CTRL_MODE_EXT |
MDIO_CTRL_OP_READ;
} else {
val = MDIO_CTRL_SPRES_PRMBL |
FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
FIELDX(MDIO_CTRL_REG, reg) |
MDIO_CTRL_START |
MDIO_CTRL_OP_READ;
}
AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
if (!atl1c_wait_mdio_idle(hw))
return -1;
AT_READ_REG(hw, REG_MDIO_CTRL, &val);
*phy_data = (u16)FIELD_GETX(val, MDIO_CTRL_DATA);
atl1c_start_phy_polling(hw, clk_sel);
return 0;
}
/*
* atl1c_write_phy_core
* core function to write to register in PHY via MDIO control register.
* ext: extension register (see IEEE 802.3)
* dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0)
* reg: reg to write
*/
int atl1c_write_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
u16 reg, u16 phy_data)
{
u32 val;
u16 clk_sel = MDIO_CTRL_CLK_25_4;
atl1c_stop_phy_polling(hw);
/* only l2c_b2 & l1d_2 could use slow clock */
if ((hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) &&
hw->hibernate)
clk_sel = MDIO_CTRL_CLK_25_128;
if (ext) {
val = FIELDX(MDIO_EXTN_DEVAD, dev) | FIELDX(MDIO_EXTN_REG, reg);
AT_WRITE_REG(hw, REG_MDIO_EXTN, val);
val = MDIO_CTRL_SPRES_PRMBL |
FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
FIELDX(MDIO_CTRL_DATA, phy_data) |
MDIO_CTRL_START |
MDIO_CTRL_MODE_EXT;
} else {
val = MDIO_CTRL_SPRES_PRMBL |
FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
FIELDX(MDIO_CTRL_DATA, phy_data) |
FIELDX(MDIO_CTRL_REG, reg) |
MDIO_CTRL_START;
}
AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
if (!atl1c_wait_mdio_idle(hw))
return -1;
atl1c_start_phy_polling(hw, clk_sel);
return 0;
}
/*
* Reads the value from a PHY register
* hw - Struct containing variables accessed by shared code
* reg_addr - address of the PHY register to read
*/
int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
{
return atl1c_read_phy_core(hw, false, 0, reg_addr, phy_data);
}
/*
* Writes a value to a PHY register
* hw - Struct containing variables accessed by shared code
* reg_addr - address of the PHY register to write
* data - data to write to the PHY
*/
int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data)
{
return atl1c_write_phy_core(hw, false, 0, reg_addr, phy_data);
}
/* read from PHY extension register */
int atl1c_read_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
u16 reg_addr, u16 *phy_data)
{
return atl1c_read_phy_core(hw, true, dev_addr, reg_addr, phy_data);
}
/* write to PHY extension register */
int atl1c_write_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
u16 reg_addr, u16 phy_data)
{
return atl1c_write_phy_core(hw, true, dev_addr, reg_addr, phy_data);
}
int atl1c_read_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
{
int err;
err = atl1c_write_phy_reg(hw, MII_DBG_ADDR, reg_addr);
if (unlikely(err))
return err;
else
err = atl1c_read_phy_reg(hw, MII_DBG_DATA, phy_data);
return err;
}
int atl1c_write_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 phy_data)
{
int err;
err = atl1c_write_phy_reg(hw, MII_DBG_ADDR, reg_addr);
if (unlikely(err))
return err;
else
err = atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
return err;
}
/*
* Configures PHY autoneg and flow control advertisement settings
*
* hw - Struct containing variables accessed by shared code
*/
static int atl1c_phy_setup_adv(struct atl1c_hw *hw)
{
u16 mii_adv_data = ADVERTISE_DEFAULT_CAP & ~ADVERTISE_ALL;
u16 mii_giga_ctrl_data = GIGA_CR_1000T_DEFAULT_CAP &
~GIGA_CR_1000T_SPEED_MASK;
if (hw->autoneg_advertised & ADVERTISED_10baseT_Half)
mii_adv_data |= ADVERTISE_10HALF;
if (hw->autoneg_advertised & ADVERTISED_10baseT_Full)
mii_adv_data |= ADVERTISE_10FULL;
if (hw->autoneg_advertised & ADVERTISED_100baseT_Half)
mii_adv_data |= ADVERTISE_100HALF;
if (hw->autoneg_advertised & ADVERTISED_100baseT_Full)
mii_adv_data |= ADVERTISE_100FULL;
if (hw->autoneg_advertised & ADVERTISED_Autoneg)
mii_adv_data |= ADVERTISE_10HALF | ADVERTISE_10FULL |
ADVERTISE_100HALF | ADVERTISE_100FULL;
if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M) {
if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half)
mii_giga_ctrl_data |= ADVERTISE_1000HALF;
if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full)
mii_giga_ctrl_data |= ADVERTISE_1000FULL;
if (hw->autoneg_advertised & ADVERTISED_Autoneg)
mii_giga_ctrl_data |= ADVERTISE_1000HALF |
ADVERTISE_1000FULL;
}
if (atl1c_write_phy_reg(hw, MII_ADVERTISE, mii_adv_data) != 0 ||
atl1c_write_phy_reg(hw, MII_CTRL1000, mii_giga_ctrl_data) != 0)
return -1;
return 0;
}
void atl1c_phy_disable(struct atl1c_hw *hw)
{
atl1c_power_saving(hw, 0);
}
int atl1c_phy_reset(struct atl1c_hw *hw)
{
struct atl1c_adapter *adapter = hw->adapter;
struct pci_dev *pdev = adapter->pdev;
u16 phy_data;
u32 phy_ctrl_data, lpi_ctrl;
int err;
/* reset PHY core */
AT_READ_REG(hw, REG_GPHY_CTRL, &phy_ctrl_data);
phy_ctrl_data &= ~(GPHY_CTRL_EXT_RESET | GPHY_CTRL_PHY_IDDQ |
GPHY_CTRL_GATE_25M_EN | GPHY_CTRL_PWDOWN_HW | GPHY_CTRL_CLS);
phy_ctrl_data |= GPHY_CTRL_SEL_ANA_RST;
if (!(hw->ctrl_flags & ATL1C_HIB_DISABLE))
phy_ctrl_data |= (GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE);
else
phy_ctrl_data &= ~(GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE);
AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
AT_WRITE_FLUSH(hw);
udelay(10);
AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data | GPHY_CTRL_EXT_RESET);
AT_WRITE_FLUSH(hw);
udelay(10 * GPHY_CTRL_EXT_RST_TO); /* delay 800us */
/* switch clock */
if (hw->nic_type == athr_l2c_b) {
atl1c_read_phy_dbg(hw, MIIDBG_CFGLPSPD, &phy_data);
atl1c_write_phy_dbg(hw, MIIDBG_CFGLPSPD,
phy_data & ~CFGLPSPD_RSTCNT_CLK125SW);
}
/* tx-half amplitude issue fix */
if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
atl1c_read_phy_dbg(hw, MIIDBG_CABLE1TH_DET, &phy_data);
phy_data |= CABLE1TH_DET_EN;
atl1c_write_phy_dbg(hw, MIIDBG_CABLE1TH_DET, phy_data);
}
/* clear bit3 of dbgport 3B to lower voltage */
if (!(hw->ctrl_flags & ATL1C_HIB_DISABLE)) {
if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
phy_data &= ~VOLT_CTRL_SWLOWEST;
atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
}
/* power saving config */
phy_data =
hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2 ?
L1D_LEGCYPS_DEF : L1C_LEGCYPS_DEF;
atl1c_write_phy_dbg(hw, MIIDBG_LEGCYPS, phy_data);
/* hib */
atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
SYSMODCTRL_IECHOADJ_DEF);
} else {
/* disable pws */
atl1c_read_phy_dbg(hw, MIIDBG_LEGCYPS, &phy_data);
atl1c_write_phy_dbg(hw, MIIDBG_LEGCYPS,
phy_data & ~LEGCYPS_EN);
/* disable hibernate */
atl1c_read_phy_dbg(hw, MIIDBG_HIBNEG, &phy_data);
atl1c_write_phy_dbg(hw, MIIDBG_HIBNEG,
phy_data & HIBNEG_PSHIB_EN);
}
/* disable AZ(EEE) by default */
if (hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2 ||
hw->nic_type == athr_l2c_b2) {
AT_READ_REG(hw, REG_LPI_CTRL, &lpi_ctrl);
AT_WRITE_REG(hw, REG_LPI_CTRL, lpi_ctrl & ~LPI_CTRL_EN);
atl1c_write_phy_ext(hw, MIIEXT_ANEG, MIIEXT_LOCAL_EEEADV, 0);
atl1c_write_phy_ext(hw, MIIEXT_PCS, MIIEXT_CLDCTRL3,
L2CB_CLDCTRL3);
}
/* other debug port to set */
atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, ANACTRL_DEF);
atl1c_write_phy_dbg(hw, MIIDBG_SRDSYSMOD, SRDSYSMOD_DEF);
atl1c_write_phy_dbg(hw, MIIDBG_TST10BTCFG, TST10BTCFG_DEF);
/* UNH-IOL test issue, set bit7 */
atl1c_write_phy_dbg(hw, MIIDBG_TST100BTCFG,
TST100BTCFG_DEF | TST100BTCFG_LITCH_EN);
/* set phy interrupt mask */
phy_data = IER_LINK_UP | IER_LINK_DOWN;
err = atl1c_write_phy_reg(hw, MII_IER, phy_data);
if (err) {
if (netif_msg_hw(adapter))
dev_err(&pdev->dev,
"Error enable PHY linkChange Interrupt\n");
return err;
}
return 0;
}
int atl1c_phy_init(struct atl1c_hw *hw)
{
struct atl1c_adapter *adapter = hw->adapter;
struct pci_dev *pdev = adapter->pdev;
int ret_val;
u16 mii_bmcr_data = BMCR_RESET;
if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &hw->phy_id1) != 0) ||
(atl1c_read_phy_reg(hw, MII_PHYSID2, &hw->phy_id2) != 0)) {
dev_err(&pdev->dev, "Error get phy ID\n");
return -1;
}
switch (hw->media_type) {
case MEDIA_TYPE_AUTO_SENSOR:
ret_val = atl1c_phy_setup_adv(hw);
if (ret_val) {
if (netif_msg_link(adapter))
dev_err(&pdev->dev,
"Error Setting up Auto-Negotiation\n");
return ret_val;
}
mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART;
break;
case MEDIA_TYPE_100M_FULL:
mii_bmcr_data |= BMCR_SPEED100 | BMCR_FULLDPLX;
break;
case MEDIA_TYPE_100M_HALF:
mii_bmcr_data |= BMCR_SPEED100;
break;
case MEDIA_TYPE_10M_FULL:
mii_bmcr_data |= BMCR_FULLDPLX;
break;
case MEDIA_TYPE_10M_HALF:
break;
default:
if (netif_msg_link(adapter))
dev_err(&pdev->dev, "Wrong Media type %d\n",
hw->media_type);
return -1;
}
ret_val = atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
if (ret_val)
return ret_val;
hw->phy_configured = true;
return 0;
}
/*
* Detects the current speed and duplex settings of the hardware.
*
* hw - Struct containing variables accessed by shared code
* speed - Speed of the connection
* duplex - Duplex setting of the connection
*/
int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex)
{
int err;
u16 phy_data;
/* Read PHY Specific Status Register (17) */
err = atl1c_read_phy_reg(hw, MII_GIGA_PSSR, &phy_data);
if (err)
return err;
if (!(phy_data & GIGA_PSSR_SPD_DPLX_RESOLVED))
return -1;
switch (phy_data & GIGA_PSSR_SPEED) {
case GIGA_PSSR_1000MBS:
*speed = SPEED_1000;
break;
case GIGA_PSSR_100MBS:
*speed = SPEED_100;
break;
case GIGA_PSSR_10MBS:
*speed = SPEED_10;
break;
default:
return -1;
}
if (phy_data & GIGA_PSSR_DPLX)
*duplex = FULL_DUPLEX;
else
*duplex = HALF_DUPLEX;
return 0;
}
/* select one link mode to get lower power consumption */
int atl1c_phy_to_ps_link(struct atl1c_hw *hw)
{
struct atl1c_adapter *adapter = hw->adapter;
struct pci_dev *pdev = adapter->pdev;
int ret = 0;
u16 autoneg_advertised = ADVERTISED_10baseT_Half;
u16 save_autoneg_advertised;
u16 phy_data;
u16 mii_lpa_data;
u16 speed = SPEED_0;
u16 duplex = FULL_DUPLEX;
int i;
atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
if (phy_data & BMSR_LSTATUS) {
atl1c_read_phy_reg(hw, MII_LPA, &mii_lpa_data);
if (mii_lpa_data & LPA_10FULL)
autoneg_advertised = ADVERTISED_10baseT_Full;
else if (mii_lpa_data & LPA_10HALF)
autoneg_advertised = ADVERTISED_10baseT_Half;
else if (mii_lpa_data & LPA_100HALF)
autoneg_advertised = ADVERTISED_100baseT_Half;
else if (mii_lpa_data & LPA_100FULL)
autoneg_advertised = ADVERTISED_100baseT_Full;
save_autoneg_advertised = hw->autoneg_advertised;
hw->phy_configured = false;
hw->autoneg_advertised = autoneg_advertised;
if (atl1c_restart_autoneg(hw) != 0) {
dev_dbg(&pdev->dev, "phy autoneg failed\n");
ret = -1;
}
hw->autoneg_advertised = save_autoneg_advertised;
if (mii_lpa_data) {
for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
mdelay(100);
atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
if (phy_data & BMSR_LSTATUS) {
if (atl1c_get_speed_and_duplex(hw, &speed,
&duplex) != 0)
dev_dbg(&pdev->dev,
"get speed and duplex failed\n");
break;
}
}
}
} else {
speed = SPEED_10;
duplex = HALF_DUPLEX;
}
adapter->link_speed = speed;
adapter->link_duplex = duplex;
return ret;
}
int atl1c_restart_autoneg(struct atl1c_hw *hw)
{
int err = 0;
u16 mii_bmcr_data = BMCR_RESET;
err = atl1c_phy_setup_adv(hw);
if (err)
return err;
mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART;
return atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
}
int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc)
{
struct atl1c_adapter *adapter = hw->adapter;
struct pci_dev *pdev = adapter->pdev;
u32 master_ctrl, mac_ctrl, phy_ctrl;
u32 wol_ctrl, speed;
u16 phy_data;
wol_ctrl = 0;
speed = adapter->link_speed == SPEED_1000 ?
MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100;
AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl);
AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl);
AT_READ_REG(hw, REG_GPHY_CTRL, &phy_ctrl);
master_ctrl &= ~MASTER_CTRL_CLK_SEL_DIS;
mac_ctrl = FIELD_SETX(mac_ctrl, MAC_CTRL_SPEED, speed);
mac_ctrl &= ~(MAC_CTRL_DUPLX | MAC_CTRL_RX_EN | MAC_CTRL_TX_EN);
if (adapter->link_duplex == FULL_DUPLEX)
mac_ctrl |= MAC_CTRL_DUPLX;
phy_ctrl &= ~(GPHY_CTRL_EXT_RESET | GPHY_CTRL_CLS);
phy_ctrl |= GPHY_CTRL_SEL_ANA_RST | GPHY_CTRL_HIB_PULSE |
GPHY_CTRL_HIB_EN;
if (!wufc) { /* without WoL */
master_ctrl |= MASTER_CTRL_CLK_SEL_DIS;
phy_ctrl |= GPHY_CTRL_PHY_IDDQ | GPHY_CTRL_PWDOWN_HW;
AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl);
AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl);
AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl);
AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
hw->phy_configured = false; /* re-init PHY when resume */
return 0;
}
phy_ctrl |= GPHY_CTRL_EXT_RESET;
if (wufc & AT_WUFC_MAG) {
mac_ctrl |= MAC_CTRL_RX_EN | MAC_CTRL_BC_EN;
wol_ctrl |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
if (hw->nic_type == athr_l2c_b && hw->revision_id == L2CB_V11)
wol_ctrl |= WOL_PATTERN_EN | WOL_PATTERN_PME_EN;
}
if (wufc & AT_WUFC_LNKC) {
wol_ctrl |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) {
dev_dbg(&pdev->dev, "%s: write phy MII_IER failed.\n",
atl1c_driver_name);
}
}
/* clear PHY interrupt */
atl1c_read_phy_reg(hw, MII_ISR, &phy_data);
dev_dbg(&pdev->dev, "%s: suspend MAC=%x,MASTER=%x,PHY=0x%x,WOL=%x\n",
atl1c_driver_name, mac_ctrl, master_ctrl, phy_ctrl, wol_ctrl);
AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl);
AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl);
AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl);
AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl);
return 0;
}
/* configure phy after Link change Event */
void atl1c_post_phy_linkchg(struct atl1c_hw *hw, u16 link_speed)
{
u16 phy_val;
bool adj_thresh = false;
if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2 ||
hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2)
adj_thresh = true;
if (link_speed != SPEED_0) { /* link up */
/* az with brcm, half-amp */
if (hw->nic_type == athr_l1d_2) {
atl1c_read_phy_ext(hw, MIIEXT_PCS, MIIEXT_CLDCTRL6,
&phy_val);
phy_val = FIELD_GETX(phy_val, CLDCTRL6_CAB_LEN);
phy_val = phy_val > CLDCTRL6_CAB_LEN_SHORT ?
AZ_ANADECT_LONG : AZ_ANADECT_DEF;
atl1c_write_phy_dbg(hw, MIIDBG_AZ_ANADECT, phy_val);
}
/* threshold adjust */
if (adj_thresh && link_speed == SPEED_100 && hw->msi_lnkpatch) {
atl1c_write_phy_dbg(hw, MIIDBG_MSE16DB, L1D_MSE16DB_UP);
atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
L1D_SYSMODCTRL_IECHOADJ_DEF);
}
} else { /* link down */
if (adj_thresh && hw->msi_lnkpatch) {
atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
SYSMODCTRL_IECHOADJ_DEF);
atl1c_write_phy_dbg(hw, MIIDBG_MSE16DB,
L1D_MSE16DB_DOWN);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +0,0 @@
if [ "${1}" = "rd" ]; then
echo "Installing module for Atheros L1E Gigabit Ethernet adapter"
${INSMOD} "/modules/atl1e.ko" ${PARAMS}
fi

Some files were not shown because too many files have changed in this diff Show More