blob: e377cc9f49c30e2246439a61bae456b86ff71d2f [file] [log] [blame]
khenaidood948f772021-08-11 17:49:24 -04001// Copyright 2020 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build zos && s390x
6// +build zos,s390x
7
8package unix
9
10import (
11 "unsafe"
12)
13
14// This file simulates fstatfs on z/OS using fstatvfs and w_getmntent.
15
16func Fstatfs(fd int, stat *Statfs_t) (err error) {
17 var stat_v Statvfs_t
18 err = Fstatvfs(fd, &stat_v)
19 if err == nil {
20 // populate stat
21 stat.Type = 0
22 stat.Bsize = stat_v.Bsize
23 stat.Blocks = stat_v.Blocks
24 stat.Bfree = stat_v.Bfree
25 stat.Bavail = stat_v.Bavail
26 stat.Files = stat_v.Files
27 stat.Ffree = stat_v.Ffree
28 stat.Fsid = stat_v.Fsid
29 stat.Namelen = stat_v.Namemax
30 stat.Frsize = stat_v.Frsize
31 stat.Flags = stat_v.Flag
32 for passn := 0; passn < 5; passn++ {
33 switch passn {
34 case 0:
35 err = tryGetmntent64(stat)
36 break
37 case 1:
38 err = tryGetmntent128(stat)
39 break
40 case 2:
41 err = tryGetmntent256(stat)
42 break
43 case 3:
44 err = tryGetmntent512(stat)
45 break
46 case 4:
47 err = tryGetmntent1024(stat)
48 break
49 default:
50 break
51 }
52 //proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred)
53 if err == nil || err != nil && err != ERANGE {
54 break
55 }
56 }
57 }
58 return err
59}
60
61func tryGetmntent64(stat *Statfs_t) (err error) {
62 var mnt_ent_buffer struct {
63 header W_Mnth
64 filesys_info [64]W_Mntent
65 }
66 var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
67 fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
68 if err != nil {
69 return err
70 }
71 err = ERANGE //return ERANGE if no match is found in this batch
72 for i := 0; i < fs_count; i++ {
73 if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
74 stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
75 err = nil
76 break
77 }
78 }
79 return err
80}
81
82func tryGetmntent128(stat *Statfs_t) (err error) {
83 var mnt_ent_buffer struct {
84 header W_Mnth
85 filesys_info [128]W_Mntent
86 }
87 var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
88 fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
89 if err != nil {
90 return err
91 }
92 err = ERANGE //return ERANGE if no match is found in this batch
93 for i := 0; i < fs_count; i++ {
94 if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
95 stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
96 err = nil
97 break
98 }
99 }
100 return err
101}
102
103func tryGetmntent256(stat *Statfs_t) (err error) {
104 var mnt_ent_buffer struct {
105 header W_Mnth
106 filesys_info [256]W_Mntent
107 }
108 var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
109 fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
110 if err != nil {
111 return err
112 }
113 err = ERANGE //return ERANGE if no match is found in this batch
114 for i := 0; i < fs_count; i++ {
115 if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
116 stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
117 err = nil
118 break
119 }
120 }
121 return err
122}
123
124func tryGetmntent512(stat *Statfs_t) (err error) {
125 var mnt_ent_buffer struct {
126 header W_Mnth
127 filesys_info [512]W_Mntent
128 }
129 var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
130 fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
131 if err != nil {
132 return err
133 }
134 err = ERANGE //return ERANGE if no match is found in this batch
135 for i := 0; i < fs_count; i++ {
136 if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
137 stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
138 err = nil
139 break
140 }
141 }
142 return err
143}
144
145func tryGetmntent1024(stat *Statfs_t) (err error) {
146 var mnt_ent_buffer struct {
147 header W_Mnth
148 filesys_info [1024]W_Mntent
149 }
150 var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
151 fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
152 if err != nil {
153 return err
154 }
155 err = ERANGE //return ERANGE if no match is found in this batch
156 for i := 0; i < fs_count; i++ {
157 if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
158 stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
159 err = nil
160 break
161 }
162 }
163 return err
164}