// Copyright 2020 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build zos && s390x // +build zos,s390x package unix import ( "unsafe" ) // This file simulates fstatfs on z/OS using fstatvfs and w_getmntent. func Fstatfs(fd int, stat *Statfs_t) (err error) { var stat_v Statvfs_t err = Fstatvfs(fd, &stat_v) if err == nil { // populate stat stat.Type = 0 stat.Bsize = stat_v.Bsize stat.Blocks = stat_v.Blocks stat.Bfree = stat_v.Bfree stat.Bavail = stat_v.Bavail stat.Files = stat_v.Files stat.Ffree = stat_v.Ffree stat.Fsid = stat_v.Fsid stat.Namelen = stat_v.Namemax stat.Frsize = stat_v.Frsize stat.Flags = stat_v.Flag for passn := 0; passn < 5; passn++ { switch passn { case 0: err = tryGetmntent64(stat) break case 1: err = tryGetmntent128(stat) break case 2: err = tryGetmntent256(stat) break case 3: err = tryGetmntent512(stat) break case 4: err = tryGetmntent1024(stat) break default: break } //proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred) if err == nil || err != nil && err != ERANGE { break } } } return err } func tryGetmntent64(stat *Statfs_t) (err error) { var mnt_ent_buffer struct { header W_Mnth filesys_info [64]W_Mntent } var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) if err != nil { return err } err = ERANGE //return ERANGE if no match is found in this batch for i := 0; i < fs_count; i++ { if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) err = nil break } } return err } func tryGetmntent128(stat *Statfs_t) (err error) { var mnt_ent_buffer struct { header W_Mnth filesys_info [128]W_Mntent } var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) if err != nil { return err } err = ERANGE //return ERANGE if no match is found in this batch for i := 0; i < fs_count; i++ { if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) err = nil break } } return err } func tryGetmntent256(stat *Statfs_t) (err error) { var mnt_ent_buffer struct { header W_Mnth filesys_info [256]W_Mntent } var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) if err != nil { return err } err = ERANGE //return ERANGE if no match is found in this batch for i := 0; i < fs_count; i++ { if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) err = nil break } } return err } func tryGetmntent512(stat *Statfs_t) (err error) { var mnt_ent_buffer struct { header W_Mnth filesys_info [512]W_Mntent } var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) if err != nil { return err } err = ERANGE //return ERANGE if no match is found in this batch for i := 0; i < fs_count; i++ { if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) err = nil break } } return err } func tryGetmntent1024(stat *Statfs_t) (err error) { var mnt_ent_buffer struct { header W_Mnth filesys_info [1024]W_Mntent } var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer)) fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size) if err != nil { return err } err = ERANGE //return ERANGE if no match is found in this batch for i := 0; i < fs_count; i++ { if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) { stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0]) err = nil break } } return err }