blob: ecbaecf4ba5294c7286578d792076c7d63a5e6a8 [file] [log] [blame]
Lorenz Brun1d801752020-04-02 09:24:51 +02001// Copyright 2020 The Monogon Project Authors.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17package fsquota
18
19import (
20 "fmt"
21 "os"
22 "unsafe"
23
24 "golang.org/x/sys/unix"
25)
26
Serge Bazanski216fe7b2021-05-21 18:36:16 +020027// This requires fsinfo() support, which is not yet in any stable kernel. Our
28// kernel has that syscall backported. This would otherwise be an extremely
29// expensive operation and also involve lots of logic from our side.
Lorenz Brun1d801752020-04-02 09:24:51 +020030
31// From syscall_64.tbl
32const sys_fsinfo = 441
33
34// From uapi/linux/fsinfo.h
35const fsinfo_attr_source = 0x09
36const fsinfo_flags_query_path = 0x0000
37const fsinfo_flags_query_fd = 0x0001
38
39type fsinfoParams struct {
40 resolveFlags uint64
41 atFlags uint32
42 flags uint32
43 request uint32
44 nth uint32
45 mth uint32
46}
47
48func fsinfoGetSource(dir *os.File) (string, error) {
49 buf := make([]byte, 256)
50 params := fsinfoParams{
51 flags: fsinfo_flags_query_fd,
52 request: fsinfo_attr_source,
53 }
Lorenz Brun5999e922021-01-27 18:53:54 +010054 n, _, err := unix.Syscall6(sys_fsinfo, dir.Fd(), 0, uintptr(unsafe.Pointer(&params)), unsafe.Sizeof(params), uintptr(unsafe.Pointer(&buf[0])), 256)
Lorenz Brun1d801752020-04-02 09:24:51 +020055 if err != unix.Errno(0) {
56 return "", fmt.Errorf("failed to call fsinfo: %w", err)
57 }
Lorenz Brun5999e922021-01-27 18:53:54 +010058 return string(buf[:n-1]), nil
Lorenz Brun1d801752020-04-02 09:24:51 +020059}