Skip to content

JDK-8030048: (fs) Support UserDefinedFileAttributeView/extended attributes on OS X / HFS+ #2017

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions src/java.base/macosx/classes/sun/nio/fs/BsdFileStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,56 @@ UnixMountEntry findMountEntry() throws IOException {

throw new IOException("Mount point not found in fstab");
}

// returns true if extended attributes enabled on file system where given
// file resides, returns false if disabled or unable to determine.
private boolean isExtendedAttributesEnabled(UnixPath path) {
int fd = -1;
try {
fd = path.openForAttributeAccess(false);

// fgetxattr returns size if called with size==0
byte[] name = Util.toBytes("user.java");
BsdNativeDispatcher.fgetxattr(fd, name, 0L, 0);
return true;
} catch (UnixException e) {
// attribute does not exist
if (e.errno() == UnixConstants.ENOATTR)
return true;
} finally {
UnixNativeDispatcher.close(fd);
}
return false;
}

@Override
public boolean supportsFileAttributeView(Class<? extends FileAttributeView> type) {
// support UserDefinedAttributeView if extended attributes enabled
if (type == UserDefinedFileAttributeView.class) {
// lookup fstypes.properties
FeatureStatus status = checkIfFeaturePresent("user_xattr");
if (status == FeatureStatus.PRESENT)
return true;
if (status == FeatureStatus.NOT_PRESENT)
return false;

// typical macOS file system types that are known to support xattr
if (entry().fstype().equals("apfs")
|| entry().fstype().equals("hfs")) {
return true;
}

// probe file system capabilities
UnixPath dir = new UnixPath(file().getFileSystem(), entry().dir());
return isExtendedAttributesEnabled(dir);
}
return super.supportsFileAttributeView(type);
}

@Override
public boolean supportsFileAttributeView(String name) {
if (name.equals("user"))
return supportsFileAttributeView(UserDefinedFileAttributeView.class);
return super.supportsFileAttributeView(name);
}
}
2 changes: 2 additions & 0 deletions src/java.base/macosx/classes/sun/nio/fs/BsdFileSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ private static class SupportedFileFileAttributeViewsHolder {
private static Set<String> supportedFileAttributeViews() {
Set<String> result = new HashSet<String>();
result.addAll(standardFileAttributeViews());
// additional BSD-specific views
result.add("user");
return Collections.unmodifiableSet(result);
}
}
Expand Down
27 changes: 27 additions & 0 deletions src/java.base/macosx/classes/sun/nio/fs/BsdFileSystemProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

package sun.nio.fs;

import java.nio.file.*;
import java.nio.file.attribute.*;
import java.io.IOException;

/**
Expand All @@ -45,4 +47,29 @@ BsdFileSystem newFileSystem(String dir) {
BsdFileStore getFileStore(UnixPath path) throws IOException {
return new BsdFileStore(path);
}

@Override
@SuppressWarnings("unchecked")
public <V extends FileAttributeView> V getFileAttributeView(Path obj,
Class<V> type,
LinkOption... options)
{
if (type == UserDefinedFileAttributeView.class) {
return (V) new BsdUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
Util.followLinks(options));
}
return super.getFileAttributeView(obj, type, options);
}

@Override
public DynamicFileAttributeView getFileAttributeView(Path obj,
String name,
LinkOption... options)
{
if (name.equals("user")) {
return new BsdUserDefinedFileAttributeView(UnixPath.toUnixPath(obj),
Util.followLinks(options));
}
return super.getFileAttributeView(obj, name, options);
}
}
61 changes: 61 additions & 0 deletions src/java.base/macosx/classes/sun/nio/fs/BsdNativeDispatcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,67 @@ static byte[] getmntonname(UnixPath path) throws UnixException {
}
static native byte[] getmntonname0(long pathAddress) throws UnixException;

/**
* ssize_t fgetxattr(int fd, const char *name, void *value, size_t size,
* u_int32_t position, int options);
*/
static int fgetxattr(int fd, byte[] name, long valueAddress,
int valueLen) throws UnixException
{
NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
try {
return fgetxattr0(fd, buffer.address(), valueAddress, valueLen, 0L, 0);
} finally {
buffer.release();
}
}

private static native int fgetxattr0(int fd, long nameAddress,
long valueAddress, int valueLen, long position, int options) throws UnixException;

/**
* int fsetxattr(int fd, const char *name, void *value, size_t size,
* u_int32_t position, int options);
*/
static void fsetxattr(int fd, byte[] name, long valueAddress,
int valueLen) throws UnixException
{
NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
try {
fsetxattr0(fd, buffer.address(), valueAddress, valueLen, 0L, 0);
} finally {
buffer.release();
}
}

private static native void fsetxattr0(int fd, long nameAddress,
long valueAddress, int valueLen, long position, int options) throws UnixException;

/**
* int fremovexattr(int fd, const char *name, int options);
*/
static void fremovexattr(int fd, byte[] name) throws UnixException {
NativeBuffer buffer = NativeBuffers.asNativeBuffer(name);
try {
fremovexattr0(fd, buffer.address(), 0);
} finally {
buffer.release();
}
}

private static native void fremovexattr0(int fd, long nameAddress, int options)
throws UnixException;

/**
* ssize_t flistxattr(int fd, char *namebuf, size_t size, int options);
*/
static int flistxattr(int fd, long nameBufAddress, int size) throws UnixException {
return flistxattr0(fd, nameBufAddress, size, 0);
}

private static native int flistxattr0(int fd, long nameBufAddress, int size,
int options) throws UnixException;

// initialize field IDs
private static native void initIDs();

Expand Down
Loading