From 2cea148cdf3a47366fa5a15b1928dd4f37a9c91a Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Fri, 1 Nov 2019 13:16:50 -0700 Subject: [PATCH] 8162520: (fs) FileStore should support file stores with > Long.MAX_VALUE capacity Reviewed-by: alanb, darcy, rriggs --- .../classes/java/nio/file/FileStore.java | 49 ++++++++++--------- .../classes/sun/nio/fs/UnixFileStore.java | 32 ++++++++---- .../classes/sun/nio/fs/WindowsFileStore.java | 20 +++++--- 3 files changed, 61 insertions(+), 40 deletions(-) diff --git a/src/java.base/share/classes/java/nio/file/FileStore.java b/src/java.base/share/classes/java/nio/file/FileStore.java index 06d4f115bb9..75e0803c888 100644 --- a/src/java.base/share/classes/java/nio/file/FileStore.java +++ b/src/java.base/share/classes/java/nio/file/FileStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,7 +84,9 @@ public abstract class FileStore { public abstract boolean isReadOnly(); /** - * Returns the size, in bytes, of the file store. + * Returns the size, in bytes, of the file store. If the total number of + * bytes in the file store is greater than {@link Long#MAX_VALUE}, then + * {@code Long.MAX_VALUE} will be returned. * * @return the size of the file store, in bytes * @@ -95,7 +97,8 @@ public abstract class FileStore { /** * Returns the number of bytes available to this Java virtual machine on the - * file store. + * file store. If the number of bytes available is greater than + * {@link Long#MAX_VALUE}, then {@code Long.MAX_VALUE} will be returned. * *

The returned number of available bytes is a hint, but not a * guarantee, that it is possible to use most or any of these bytes. The @@ -111,6 +114,25 @@ public abstract class FileStore { */ public abstract long getUsableSpace() throws IOException; + /** + * Returns the number of unallocated bytes in the file store. + * If the number of unallocated bytes is greater than + * {@link Long#MAX_VALUE}, then {@code Long.MAX_VALUE} will be returned. + * + *

The returned number of unallocated bytes is a hint, but not a + * guarantee, that it is possible to use most or any of these bytes. The + * number of unallocated bytes is most likely to be accurate immediately + * after the space attributes are obtained. It is likely to be + * made inaccurate by any external I/O operations including those made on + * the system outside of this virtual machine. + * + * @return the number of unallocated bytes + * + * @throws IOException + * if an I/O error occurs + */ + public abstract long getUnallocatedSpace() throws IOException; + /** * Returns the number of bytes per block in this file store. * @@ -118,8 +140,8 @@ public abstract class FileStore { * called blocks. A block is the smallest storage unit of a file store. * Every read and write operation is performed on a multiple of blocks. * - * @implSpec The implementation in this class throws an - * {@code UnsupportedOperationException}. + * @implSpec The implementation in this class throws + * {@code UnsupportedOperationException}. * * @return a positive value representing the block size of this file store, * in bytes @@ -136,23 +158,6 @@ public abstract class FileStore { throw new UnsupportedOperationException(); } - /** - * Returns the number of unallocated bytes in the file store. - * - *

The returned number of unallocated bytes is a hint, but not a - * guarantee, that it is possible to use most or any of these bytes. The - * number of unallocated bytes is most likely to be accurate immediately - * after the space attributes are obtained. It is likely to be - * made inaccurate by any external I/O operations including those made on - * the system outside of this virtual machine. - * - * @return the number of unallocated bytes - * - * @throws IOException - * if an I/O error occurs - */ - public abstract long getUnallocatedSpace() throws IOException; - /** * Tells whether or not this file store supports the file attributes * identified by the given file attribute view. diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java b/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java index d4a6a8dd864..cde3e861e7d 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,13 +118,31 @@ abstract class UnixFileStore @Override public long getTotalSpace() throws IOException { UnixFileStoreAttributes attrs = readAttributes(); - return attrs.blockSize() * attrs.totalBlocks(); + try { + return Math.multiplyExact(attrs.blockSize(), attrs.totalBlocks()); + } catch (ArithmeticException ignore) { + return Long.MAX_VALUE; + } } @Override public long getUsableSpace() throws IOException { - UnixFileStoreAttributes attrs = readAttributes(); - return attrs.blockSize() * attrs.availableBlocks(); + UnixFileStoreAttributes attrs = readAttributes(); + try { + return Math.multiplyExact(attrs.blockSize(), attrs.availableBlocks()); + } catch (ArithmeticException ignore) { + return Long.MAX_VALUE; + } + } + + @Override + public long getUnallocatedSpace() throws IOException { + UnixFileStoreAttributes attrs = readAttributes(); + try { + return Math.multiplyExact(attrs.blockSize(), attrs.freeBlocks()); + } catch (ArithmeticException ignore) { + return Long.MAX_VALUE; + } } @Override @@ -133,12 +151,6 @@ abstract class UnixFileStore return attrs.blockSize(); } - @Override - public long getUnallocatedSpace() throws IOException { - UnixFileStoreAttributes attrs = readAttributes(); - return attrs.blockSize() * attrs.freeBlocks(); - } - @Override public V getFileStoreAttributeView(Class view) { diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileStore.java b/src/java.base/windows/classes/sun/nio/fs/WindowsFileStore.java index 4dd90c714da..acbb2c15f2a 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileStore.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -145,21 +145,25 @@ class WindowsFileStore @Override public long getTotalSpace() throws IOException { - return readDiskFreeSpaceEx().totalNumberOfBytes(); + long space = readDiskFreeSpaceEx().totalNumberOfBytes(); + return space >= 0 ? space : Long.MAX_VALUE; } @Override public long getUsableSpace() throws IOException { - return readDiskFreeSpaceEx().freeBytesAvailable(); - } - - public long getBlockSize() throws IOException { - return readDiskFreeSpace().bytesPerSector(); + long space = readDiskFreeSpaceEx().freeBytesAvailable(); + return space >= 0 ? space : Long.MAX_VALUE; } @Override public long getUnallocatedSpace() throws IOException { - return readDiskFreeSpaceEx().freeBytesAvailable(); + long space = readDiskFreeSpaceEx().freeBytesAvailable(); + return space >= 0 ? space : Long.MAX_VALUE; + } + + @Override + public long getBlockSize() throws IOException { + return readDiskFreeSpace().bytesPerSector(); } @Override