jdk/src/solaris/classes/sun/nio/fs/UnixFileStore.java
changeset 2057 3acf8e5e2ca0
child 3065 452aaa2899fc
equal deleted inserted replaced
2056:115e09b7a004 2057:3acf8e5e2ca0
       
     1 /*
       
     2  * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package sun.nio.fs;
       
    27 
       
    28 import java.nio.file.*;
       
    29 import java.nio.file.attribute.*;
       
    30 import java.nio.channels.*;
       
    31 import java.util.*;
       
    32 import java.io.IOException;
       
    33 import java.security.AccessController;
       
    34 import java.security.PrivilegedAction;
       
    35 
       
    36 /**
       
    37  * Base implementation of FileStore for Unix/like implementations.
       
    38  */
       
    39 
       
    40 abstract class UnixFileStore
       
    41     extends FileStore
       
    42 {
       
    43     // original path of file that identified file system
       
    44     private final UnixPath file;
       
    45 
       
    46     // device ID
       
    47     private final long dev;
       
    48 
       
    49     // entry in the mount tab
       
    50     private final UnixMountEntry entry;
       
    51 
       
    52     // return the device ID where the given file resides
       
    53     private static long devFor(UnixPath file) throws IOException {
       
    54         try {
       
    55             return UnixFileAttributes.get(file, true).dev();
       
    56         } catch (UnixException x) {
       
    57             x.rethrowAsIOException(file);
       
    58             return 0L;  // keep compiler happy
       
    59         }
       
    60     }
       
    61 
       
    62     UnixFileStore(UnixPath file) throws IOException {
       
    63         this.file = file;
       
    64         this.dev = devFor(file);
       
    65         this.entry = findMountEntry();
       
    66     }
       
    67 
       
    68     UnixFileStore(UnixFileSystem fs, UnixMountEntry entry) throws IOException {
       
    69         this.file = new UnixPath(fs, entry.dir());
       
    70         this.dev = (entry.dev() == 0L) ? devFor(this.file) : entry.dev();
       
    71         this.entry = entry;
       
    72     }
       
    73 
       
    74     /**
       
    75      * Find the mount entry for the file store
       
    76      */
       
    77     abstract UnixMountEntry findMountEntry() throws IOException;
       
    78 
       
    79     /**
       
    80      * Returns true if this file store represents a loopback file system that
       
    81      * will have the same device ID as undelrying file system.
       
    82      */
       
    83     abstract boolean isLoopback();
       
    84 
       
    85     UnixPath file() {
       
    86         return file;
       
    87     }
       
    88 
       
    89     long dev() {
       
    90         return dev;
       
    91     }
       
    92 
       
    93     UnixMountEntry entry() {
       
    94         return entry;
       
    95     }
       
    96 
       
    97     @Override
       
    98     public String name() {
       
    99         return entry.name();
       
   100     }
       
   101 
       
   102     @Override
       
   103     public String type() {
       
   104         return entry.fstype();
       
   105     }
       
   106 
       
   107     @Override
       
   108     public boolean isReadOnly() {
       
   109         return entry.isReadOnly();
       
   110     }
       
   111 
       
   112     @Override
       
   113     @SuppressWarnings("unchecked")
       
   114     public <V extends FileStoreAttributeView> V getFileStoreAttributeView(Class<V> viewType)
       
   115     {
       
   116         if (viewType == FileStoreSpaceAttributeView.class)
       
   117             return (V) new UnixFileStoreSpaceAttributeView(this);
       
   118         return (V) null;
       
   119     }
       
   120 
       
   121     @Override
       
   122     public FileStoreAttributeView getFileStoreAttributeView(String name) {
       
   123         if (name.equals("space"))
       
   124             return new UnixFileStoreSpaceAttributeView(this);
       
   125         return  null;
       
   126     }
       
   127 
       
   128     @Override
       
   129     public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
       
   130         if (type == BasicFileAttributeView.class)
       
   131             return true;
       
   132         if (type == PosixFileAttributeView.class ||
       
   133             type == FileOwnerAttributeView.class)
       
   134         {
       
   135             // lookup fstypes.properties
       
   136             FeatureStatus status = checkIfFeaturePresent("posix");
       
   137             if (status == FeatureStatus.NOT_PRESENT)
       
   138                 return false;
       
   139             return true;
       
   140         }
       
   141         return false;
       
   142     }
       
   143 
       
   144     @Override
       
   145     public boolean supportsFileAttributeView(String name) {
       
   146         if (name.equals("basic") || name.equals("unix"))
       
   147             return true;
       
   148         if (name.equals("posix"))
       
   149             return supportsFileAttributeView(PosixFileAttributeView.class);
       
   150         if (name.equals("owner"))
       
   151             return supportsFileAttributeView(FileOwnerAttributeView.class);
       
   152         return false;
       
   153     }
       
   154 
       
   155     @Override
       
   156     public boolean equals(Object ob) {
       
   157         if (ob == this)
       
   158             return true;
       
   159         if (!(ob instanceof UnixFileStore))
       
   160             return false;
       
   161         UnixFileStore other = (UnixFileStore)ob;
       
   162         if (dev != other.dev)
       
   163             return false;
       
   164         // deviceIDs are equal but they may not be equal if one or both of
       
   165         // them is a loopback file system
       
   166         boolean thisIsLoopback = isLoopback();
       
   167         if (thisIsLoopback != other.isLoopback())
       
   168             return false;  // one, but not both, are lofs
       
   169         if (!thisIsLoopback)
       
   170             return true;    // neither is lofs
       
   171         // both are lofs so compare mount points
       
   172         return Arrays.equals(this.entry.dir(), other.entry.dir());
       
   173     }
       
   174 
       
   175     @Override
       
   176     public int hashCode() {
       
   177         return (int)(dev ^ (dev >>> 32));
       
   178     }
       
   179 
       
   180     @Override
       
   181     public String toString() {
       
   182         StringBuilder sb = new StringBuilder(new String(entry.dir()));
       
   183         sb.append(" (");
       
   184         sb.append(entry.name());
       
   185         sb.append(")");
       
   186         return sb.toString();
       
   187     }
       
   188 
       
   189     private static class UnixFileStoreSpaceAttributeView
       
   190         extends AbstractFileStoreSpaceAttributeView
       
   191     {
       
   192         private final UnixFileStore fs;
       
   193 
       
   194         UnixFileStoreSpaceAttributeView(UnixFileStore fs) {
       
   195             this.fs = fs;
       
   196         }
       
   197 
       
   198         @Override
       
   199         public FileStoreSpaceAttributes readAttributes()
       
   200             throws IOException
       
   201         {
       
   202             UnixPath file = fs.file();
       
   203             final UnixFileStoreAttributes attrs;
       
   204             try {
       
   205                 attrs = UnixFileStoreAttributes.get(file);
       
   206             } catch (UnixException x) {
       
   207                 x.rethrowAsIOException(file);
       
   208                 return null;    // keep compile happy
       
   209             }
       
   210 
       
   211             return new FileStoreSpaceAttributes() {
       
   212                 @Override
       
   213                 public long totalSpace() {
       
   214                     return attrs.blockSize() * attrs.totalBlocks();
       
   215                 }
       
   216                 @Override
       
   217                 public long usableSpace() {
       
   218                     return attrs.blockSize() * attrs.availableBlocks();
       
   219                 }
       
   220                 @Override
       
   221                 public long unallocatedSpace() {
       
   222                     return attrs.blockSize() * attrs.freeBlocks();
       
   223                 }
       
   224             };
       
   225         }
       
   226     }
       
   227 
       
   228     // -- fstypes.properties --
       
   229 
       
   230     private static final Object loadLock = new Object();
       
   231     private static volatile Properties props;
       
   232 
       
   233     enum FeatureStatus {
       
   234         PRESENT,
       
   235         NOT_PRESENT,
       
   236         UNKNOWN;
       
   237     }
       
   238 
       
   239     /**
       
   240      * Returns status to indicate if file system supports a given feature
       
   241      */
       
   242     FeatureStatus checkIfFeaturePresent(String feature) {
       
   243         if (props == null) {
       
   244             synchronized (loadLock) {
       
   245                 if (props == null) {
       
   246                     props = AccessController.doPrivileged(
       
   247                         new PrivilegedAction<Properties>() {
       
   248                             @Override
       
   249                             public Properties run() {
       
   250                                 return loadProperties();
       
   251                             }});
       
   252                 }
       
   253             }
       
   254         }
       
   255 
       
   256         String value = props.getProperty(type());
       
   257         if (value != null) {
       
   258             String[] values = value.split("\\s");
       
   259             for (String s: values) {
       
   260                 s = s.trim().toLowerCase();
       
   261                 if (s.equals(feature)) {
       
   262                     return FeatureStatus.PRESENT;
       
   263                 }
       
   264                 if (s.startsWith("no")) {
       
   265                     s = s.substring(2);
       
   266                     if (s.equals(feature)) {
       
   267                         return FeatureStatus.NOT_PRESENT;
       
   268                     }
       
   269                 }
       
   270             }
       
   271         }
       
   272         return FeatureStatus.UNKNOWN;
       
   273     }
       
   274 
       
   275     private static Properties loadProperties() {
       
   276         Properties result = new Properties();
       
   277         String fstypes = System.getProperty("java.home") + "/lib/fstypes.properties";
       
   278         FileRef file = Paths.get(fstypes);
       
   279         try {
       
   280             ReadableByteChannel rbc = file.newByteChannel();
       
   281             try {
       
   282                 result.load(Channels.newReader(rbc, "UTF-8"));
       
   283             } finally {
       
   284                 rbc.close();
       
   285             }
       
   286         } catch (IOException x) {
       
   287         }
       
   288         return result;
       
   289     }
       
   290 }