Home | History | Annotate | Download | only in fs
      1 /*
      2  * Copyright (c) 2008, 2013, Oracle and/or its affiliates. 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.  Oracle designates this
      8  * particular file as subject to the "Classpath" exception as provided
      9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     22  * or visit www.oracle.com if you need additional information or have any
     23  * questions.
     24  */
     25 
     26 package sun.nio.fs;
     27 
     28 import java.nio.file.attribute.*;
     29 import java.util.*;
     30 import java.io.IOException;
     31 
     32 /**
     33  * Linux implementation of FileStore
     34  */
     35 
     36 class LinuxFileStore
     37     extends UnixFileStore
     38 {
     39     // used when checking if extended attributes are enabled or not
     40     private volatile boolean xattrChecked;
     41     private volatile boolean xattrEnabled;
     42 
     43     LinuxFileStore(UnixPath file) throws IOException {
     44         super(file);
     45     }
     46 
     47     LinuxFileStore(UnixFileSystem fs, UnixMountEntry entry) throws IOException {
     48         super(fs, entry);
     49     }
     50 
     51     /**
     52      * Finds, and returns, the mount entry for the file system where the file
     53      * resides.
     54      */
     55     @Override
     56     UnixMountEntry findMountEntry() throws IOException {
     57         LinuxFileSystem fs = (LinuxFileSystem)file().getFileSystem();
     58 
     59         // step 1: get realpath
     60         UnixPath path = null;
     61         try {
     62             byte[] rp = UnixNativeDispatcher.realpath(file());
     63             path = new UnixPath(fs, rp);
     64         } catch (UnixException x) {
     65             x.rethrowAsIOException(file());
     66         }
     67 
     68         // step 2: find mount point
     69         UnixPath parent = path.getParent();
     70         while (parent != null) {
     71             UnixFileAttributes attrs = null;
     72             try {
     73                 attrs = UnixFileAttributes.get(parent, true);
     74             } catch (UnixException x) {
     75                 x.rethrowAsIOException(parent);
     76             }
     77             if (attrs.dev() != dev())
     78                 break;
     79             path = parent;
     80             parent = parent.getParent();
     81         }
     82 
     83         // step 3: lookup mounted file systems (use /proc/mounts to ensure we
     84         // find the file system even when not in /etc/mtab)
     85         byte[] dir = path.asByteArray();
     86         for (UnixMountEntry entry: fs.getMountEntries("/proc/mounts")) {
     87             if (Arrays.equals(dir, entry.dir()))
     88                 return entry;
     89         }
     90 
     91         throw new IOException("Mount point not found");
     92     }
     93 
     94     // returns true if extended attributes enabled on file system where given
     95     // file resides, returns false if disabled or unable to determine.
     96     private boolean isExtendedAttributesEnabled(UnixPath path) {
     97         try {
     98             int fd = path.openForAttributeAccess(false);
     99             try {
    100                 // fgetxattr returns size if called with size==0
    101                 byte[] name = Util.toBytes("user.java");
    102                 LinuxNativeDispatcher.fgetxattr(fd, name, 0L, 0);
    103                 return true;
    104             } catch (UnixException e) {
    105                 // attribute does not exist
    106                 if (e.errno() == UnixConstants.ENODATA)
    107                     return true;
    108             } finally {
    109                 UnixNativeDispatcher.close(fd);
    110             }
    111         } catch (IOException ignore) {
    112             // nothing we can do
    113         }
    114         return false;
    115     }
    116 
    117     @Override
    118     public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
    119         // support DosFileAttributeView and UserDefinedAttributeView if extended
    120         // attributes enabled
    121         if (type == DosFileAttributeView.class ||
    122             type == UserDefinedFileAttributeView.class)
    123         {
    124             // lookup fstypes.properties
    125             FeatureStatus status = checkIfFeaturePresent("user_xattr");
    126             if (status == FeatureStatus.PRESENT)
    127                 return true;
    128             if (status == FeatureStatus.NOT_PRESENT)
    129                 return false;
    130 
    131             // if file system is mounted with user_xattr option then assume
    132             // extended attributes are enabled
    133             if ((entry().hasOption("user_xattr")))
    134                 return true;
    135 
    136             // user_xattr option not present but we special-case ext3/4 as we
    137             // know that extended attributes are not enabled by default.
    138             if (entry().fstype().equals("ext3") || entry().fstype().equals("ext4"))
    139                 return false;
    140 
    141             // not ext3/4 so probe mount point
    142             if (!xattrChecked) {
    143                 UnixPath dir = new UnixPath(file().getFileSystem(), entry().dir());
    144                 xattrEnabled = isExtendedAttributesEnabled(dir);
    145                 xattrChecked = true;
    146             }
    147             return xattrEnabled;
    148         }
    149         // POSIX attributes not supported on FAT
    150         if (type == PosixFileAttributeView.class && entry().fstype().equals("vfat"))
    151             return false;
    152         return super.supportsFileAttributeView(type);
    153     }
    154 
    155     @Override
    156     public boolean supportsFileAttributeView(String name) {
    157         if (name.equals("dos"))
    158             return supportsFileAttributeView(DosFileAttributeView.class);
    159         if (name.equals("user"))
    160             return supportsFileAttributeView(UserDefinedFileAttributeView.class);
    161         return super.supportsFileAttributeView(name);
    162     }
    163 }
    164