Path: blob/master/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java
41137 views
/*1* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.nio.fs;2627import sun.nio.cs.UTF_8;2829import jdk.internal.util.StaticProperty;3031import java.nio.file.*;32import java.nio.file.attribute.*;33import java.nio.channels.*;34import java.util.*;35import java.io.IOException;36import java.security.AccessController;37import java.security.PrivilegedAction;3839/**40* Base implementation of FileStore for Unix/like implementations.41*/4243abstract class UnixFileStore44extends FileStore45{46// original path of file that identified file system47private final UnixPath file;4849// device ID50private final long dev;5152// entry in the mount tab53private final UnixMountEntry entry;5455// return the device ID where the given file resides56private static long devFor(UnixPath file) throws IOException {57try {58return UnixFileAttributes.get(file, true).dev();59} catch (UnixException x) {60x.rethrowAsIOException(file);61return 0L; // keep compiler happy62}63}6465UnixFileStore(UnixPath file) throws IOException {66this.file = file;67this.dev = devFor(file);68this.entry = findMountEntry();69}7071UnixFileStore(UnixFileSystem fs, UnixMountEntry entry) throws IOException {72this.file = new UnixPath(fs, entry.dir());73this.dev = (entry.dev() == 0L) ? devFor(this.file) : entry.dev();74this.entry = entry;75}7677/**78* Find the mount entry for the file store79*/80abstract UnixMountEntry findMountEntry() throws IOException;8182UnixPath file() {83return file;84}8586long dev() {87return dev;88}8990UnixMountEntry entry() {91return entry;92}9394@Override95public String name() {96return entry.name();97}9899@Override100public String type() {101return entry.fstype();102}103104@Override105public boolean isReadOnly() {106return entry.isReadOnly();107}108109// uses statvfs to read the file system information110private UnixFileStoreAttributes readAttributes() throws IOException {111try {112return UnixFileStoreAttributes.get(file);113} catch (UnixException x) {114x.rethrowAsIOException(file);115return null; // keep compile happy116}117}118119@Override120public long getTotalSpace() throws IOException {121UnixFileStoreAttributes attrs = readAttributes();122try {123return Math.multiplyExact(attrs.blockSize(), attrs.totalBlocks());124} catch (ArithmeticException ignore) {125return Long.MAX_VALUE;126}127}128129@Override130public long getUsableSpace() throws IOException {131UnixFileStoreAttributes attrs = readAttributes();132try {133return Math.multiplyExact(attrs.blockSize(), attrs.availableBlocks());134} catch (ArithmeticException ignore) {135return Long.MAX_VALUE;136}137}138139@Override140public long getUnallocatedSpace() throws IOException {141UnixFileStoreAttributes attrs = readAttributes();142try {143return Math.multiplyExact(attrs.blockSize(), attrs.freeBlocks());144} catch (ArithmeticException ignore) {145return Long.MAX_VALUE;146}147}148149@Override150public long getBlockSize() throws IOException {151UnixFileStoreAttributes attrs = readAttributes();152return attrs.blockSize();153}154155@Override156public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> view)157{158if (view == null)159throw new NullPointerException();160return (V) null;161}162163@Override164public Object getAttribute(String attribute) throws IOException {165if (attribute.equals("totalSpace"))166return getTotalSpace();167if (attribute.equals("usableSpace"))168return getUsableSpace();169if (attribute.equals("unallocatedSpace"))170return getUnallocatedSpace();171throw new UnsupportedOperationException("'" + attribute + "' not recognized");172}173174/**175* Checks whether extended attributes are enabled on the file system where the given file resides.176*177* @param path A path pointing to an existing node, such as the file system's root178* @return <code>true</code> if enabled, <code>false</code> if disabled or unable to determine179*/180protected boolean isExtendedAttributesEnabled(UnixPath path) {181if (!UnixNativeDispatcher.xattrSupported()) {182// avoid I/O if native code doesn't support xattr183return false;184}185186int fd = -1;187try {188fd = path.openForAttributeAccess(false);189190// fgetxattr returns size if called with size==0191byte[] name = Util.toBytes("user.java");192UnixNativeDispatcher.fgetxattr(fd, name, 0L, 0);193return true;194} catch (UnixException e) {195// attribute does not exist196if (e.errno() == UnixConstants.XATTR_NOT_FOUND)197return true;198} finally {199UnixNativeDispatcher.close(fd);200}201return false;202}203204@Override205public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {206if (type == null)207throw new NullPointerException();208if (type == BasicFileAttributeView.class)209return true;210if (type == PosixFileAttributeView.class ||211type == FileOwnerAttributeView.class)212{213// lookup fstypes.properties214FeatureStatus status = checkIfFeaturePresent("posix");215// assume supported if UNKNOWN216return (status != FeatureStatus.NOT_PRESENT);217}218return false;219}220221@Override222public boolean supportsFileAttributeView(String name) {223if (name.equals("basic") || name.equals("unix"))224return true;225if (name.equals("posix"))226return supportsFileAttributeView(PosixFileAttributeView.class);227if (name.equals("owner"))228return supportsFileAttributeView(FileOwnerAttributeView.class);229return false;230}231232@Override233public boolean equals(Object ob) {234if (ob == this)235return true;236if (!(ob instanceof UnixFileStore))237return false;238UnixFileStore other = (UnixFileStore)ob;239return (this.dev == other.dev) &&240Arrays.equals(this.entry.dir(), other.entry.dir()) &&241this.entry.name().equals(other.entry.name());242}243244@Override245public int hashCode() {246return (int)(dev ^ (dev >>> 32)) ^ Arrays.hashCode(entry.dir());247}248249@Override250public String toString() {251StringBuilder sb = new StringBuilder(Util.toString(entry.dir()));252sb.append(" (");253sb.append(entry.name());254sb.append(")");255return sb.toString();256}257258// -- fstypes.properties --259260private static final Object loadLock = new Object();261private static volatile Properties props;262263enum FeatureStatus {264PRESENT,265NOT_PRESENT,266UNKNOWN;267}268269/**270* Returns status to indicate if file system supports a given feature271*/272@SuppressWarnings("removal")273FeatureStatus checkIfFeaturePresent(String feature) {274if (props == null) {275synchronized (loadLock) {276if (props == null) {277props = AccessController.doPrivileged(278new PrivilegedAction<>() {279@Override280public Properties run() {281return loadProperties();282}});283}284}285}286287String value = props.getProperty(type());288if (value != null) {289String[] values = value.split("\\s");290for (String s: values) {291s = s.trim().toLowerCase();292if (s.equals(feature)) {293return FeatureStatus.PRESENT;294}295if (s.startsWith("no")) {296s = s.substring(2);297if (s.equals(feature)) {298return FeatureStatus.NOT_PRESENT;299}300}301}302}303return FeatureStatus.UNKNOWN;304}305306private static Properties loadProperties() {307Properties result = new Properties();308String fstypes = StaticProperty.javaHome() + "/lib/fstypes.properties";309Path file = Path.of(fstypes);310try {311try (ReadableByteChannel rbc = Files.newByteChannel(file)) {312result.load(Channels.newReader(rbc, UTF_8.INSTANCE));313}314} catch (IOException x) {315}316return result;317}318}319320321