@ -34,8 +34,12 @@ namespace {
static int open_read_only_file_limit = - 1 ;
static int open_read_only_file_limit = - 1 ;
static int mmap_limit = - 1 ;
static int mmap_limit = - 1 ;
static Status IOError ( const std : : string & context , int err_number ) {
return Status : : IOError ( context , strerror ( err_number ) ) ;
static Status PosixError ( const std : : string & context , int err_number ) {
if ( err_number = = ENOENT ) {
return Status : : NotFound ( context , strerror ( err_number ) ) ;
} else {
return Status : : IOError ( context , strerror ( err_number ) ) ;
}
}
}
// Helper class to limit resource usage to avoid exhaustion.
// Helper class to limit resource usage to avoid exhaustion.
@ -108,7 +112,7 @@ class PosixSequentialFile: public SequentialFile {
// We leave status as ok if we hit the end of the file
// We leave status as ok if we hit the end of the file
} else {
} else {
// A partial read with an error: return a non-ok status
// A partial read with an error: return a non-ok status
s = IO Error( filename_ , errno ) ;
s = Posix Error( filename_ , errno ) ;
}
}
}
}
return s ;
return s ;
@ -116,7 +120,7 @@ class PosixSequentialFile: public SequentialFile {
virtual Status Skip ( uint64_t n ) {
virtual Status Skip ( uint64_t n ) {
if ( fseek ( file_ , n , SEEK_CUR ) ) {
if ( fseek ( file_ , n , SEEK_CUR ) ) {
return IO Error( filename_ , errno ) ;
return Posix Error( filename_ , errno ) ;
}
}
return Status : : OK ( ) ;
return Status : : OK ( ) ;
}
}
@ -154,7 +158,7 @@ class PosixRandomAccessFile: public RandomAccessFile {
if ( temporary_fd_ ) {
if ( temporary_fd_ ) {
fd = open ( filename_ . c_str ( ) , O_RDONLY ) ;
fd = open ( filename_ . c_str ( ) , O_RDONLY ) ;
if ( fd < 0 ) {
if ( fd < 0 ) {
return IO Error( filename_ , errno ) ;
return Posix Error( filename_ , errno ) ;
}
}
}
}
@ -163,7 +167,7 @@ class PosixRandomAccessFile: public RandomAccessFile {
* result = Slice ( scratch , ( r < 0 ) ? 0 : r ) ;
* result = Slice ( scratch , ( r < 0 ) ? 0 : r ) ;
if ( r < 0 ) {
if ( r < 0 ) {
// An error: return a non-ok status
// An error: return a non-ok status
s = IO Error( filename_ , errno ) ;
s = Posix Error( filename_ , errno ) ;
}
}
if ( temporary_fd_ ) {
if ( temporary_fd_ ) {
// Close the temporary file descriptor opened earlier.
// Close the temporary file descriptor opened earlier.
@ -199,7 +203,7 @@ class PosixMmapReadableFile: public RandomAccessFile {
Status s ;
Status s ;
if ( offset + n > length_ ) {
if ( offset + n > length_ ) {
* result = Slice ( ) ;
* result = Slice ( ) ;
s = IO Error( filename_ , EINVAL ) ;
s = Posix Error( filename_ , EINVAL ) ;
} else {
} else {
* result = Slice ( reinterpret_cast < char * > ( mmapped_region_ ) + offset , n ) ;
* result = Slice ( reinterpret_cast < char * > ( mmapped_region_ ) + offset , n ) ;
}
}
@ -226,7 +230,7 @@ class PosixWritableFile : public WritableFile {
virtual Status Append ( const Slice & data ) {
virtual Status Append ( const Slice & data ) {
size_t r = fwrite_unlocked ( data . data ( ) , 1 , data . size ( ) , file_ ) ;
size_t r = fwrite_unlocked ( data . data ( ) , 1 , data . size ( ) , file_ ) ;
if ( r ! = data . size ( ) ) {
if ( r ! = data . size ( ) ) {
return IO Error( filename_ , errno ) ;
return Posix Error( filename_ , errno ) ;
}
}
return Status : : OK ( ) ;
return Status : : OK ( ) ;
}
}
@ -234,7 +238,7 @@ class PosixWritableFile : public WritableFile {
virtual Status Close ( ) {
virtual Status Close ( ) {
Status result ;
Status result ;
if ( fclose ( file_ ) ! = 0 ) {
if ( fclose ( file_ ) ! = 0 ) {
result = IO Error( filename_ , errno ) ;
result = Posix Error( filename_ , errno ) ;
}
}
file_ = NULL ;
file_ = NULL ;
return result ;
return result ;
@ -242,7 +246,7 @@ class PosixWritableFile : public WritableFile {
virtual Status Flush ( ) {
virtual Status Flush ( ) {
if ( fflush_unlocked ( file_ ) ! = 0 ) {
if ( fflush_unlocked ( file_ ) ! = 0 ) {
return IO Error( filename_ , errno ) ;
return Posix Error( filename_ , errno ) ;
}
}
return Status : : OK ( ) ;
return Status : : OK ( ) ;
}
}
@ -263,10 +267,10 @@ class PosixWritableFile : public WritableFile {
if ( basename . starts_with ( " MANIFEST " ) ) {
if ( basename . starts_with ( " MANIFEST " ) ) {
int fd = open ( dir . c_str ( ) , O_RDONLY ) ;
int fd = open ( dir . c_str ( ) , O_RDONLY ) ;
if ( fd < 0 ) {
if ( fd < 0 ) {
s = IO Error( dir , errno ) ;
s = Posix Error( dir , errno ) ;
} else {
} else {
if ( fsync ( fd ) < 0 ) {
if ( fsync ( fd ) < 0 ) {
s = IO Error( dir , errno ) ;
s = Posix Error( dir , errno ) ;
}
}
close ( fd ) ;
close ( fd ) ;
}
}
@ -337,7 +341,7 @@ class PosixEnv : public Env {
FILE * f = fopen ( fname . c_str ( ) , " r " ) ;
FILE * f = fopen ( fname . c_str ( ) , " r " ) ;
if ( f = = NULL ) {
if ( f = = NULL ) {
* result = NULL ;
* result = NULL ;
return IO Error( fname , errno ) ;
return Posix Error( fname , errno ) ;
} else {
} else {
* result = new PosixSequentialFile ( fname , f ) ;
* result = new PosixSequentialFile ( fname , f ) ;
return Status : : OK ( ) ;
return Status : : OK ( ) ;
@ -350,7 +354,7 @@ class PosixEnv : public Env {
Status s ;
Status s ;
int fd = open ( fname . c_str ( ) , O_RDONLY ) ;
int fd = open ( fname . c_str ( ) , O_RDONLY ) ;
if ( fd < 0 ) {
if ( fd < 0 ) {
s = IO Error( fname , errno ) ;
s = Posix Error( fname , errno ) ;
} else if ( mmap_limit_ . Acquire ( ) ) {
} else if ( mmap_limit_ . Acquire ( ) ) {
uint64_t size ;
uint64_t size ;
s = GetFileSize ( fname , & size ) ;
s = GetFileSize ( fname , & size ) ;
@ -359,7 +363,7 @@ class PosixEnv : public Env {
if ( base ! = MAP_FAILED ) {
if ( base ! = MAP_FAILED ) {
* result = new PosixMmapReadableFile ( fname , base , size , & mmap_limit_ ) ;
* result = new PosixMmapReadableFile ( fname , base , size , & mmap_limit_ ) ;
} else {
} else {
s = IO Error( fname , errno ) ;
s = Posix Error( fname , errno ) ;
}
}
}
}
close ( fd ) ;
close ( fd ) ;
@ -378,7 +382,7 @@ class PosixEnv : public Env {
FILE * f = fopen ( fname . c_str ( ) , " w " ) ;
FILE * f = fopen ( fname . c_str ( ) , " w " ) ;
if ( f = = NULL ) {
if ( f = = NULL ) {
* result = NULL ;
* result = NULL ;
s = IO Error( fname , errno ) ;
s = Posix Error( fname , errno ) ;
} else {
} else {
* result = new PosixWritableFile ( fname , f ) ;
* result = new PosixWritableFile ( fname , f ) ;
}
}
@ -391,7 +395,7 @@ class PosixEnv : public Env {
FILE * f = fopen ( fname . c_str ( ) , " a " ) ;
FILE * f = fopen ( fname . c_str ( ) , " a " ) ;
if ( f = = NULL ) {
if ( f = = NULL ) {
* result = NULL ;
* result = NULL ;
s = IO Error( fname , errno ) ;
s = Posix Error( fname , errno ) ;
} else {
} else {
* result = new PosixWritableFile ( fname , f ) ;
* result = new PosixWritableFile ( fname , f ) ;
}
}
@ -407,7 +411,7 @@ class PosixEnv : public Env {
result - > clear ( ) ;
result - > clear ( ) ;
DIR * d = opendir ( dir . c_str ( ) ) ;
DIR * d = opendir ( dir . c_str ( ) ) ;
if ( d = = NULL ) {
if ( d = = NULL ) {
return IO Error( dir , errno ) ;
return Posix Error( dir , errno ) ;
}
}
struct dirent * entry ;
struct dirent * entry ;
while ( ( entry = readdir ( d ) ) ! = NULL ) {
while ( ( entry = readdir ( d ) ) ! = NULL ) {
@ -420,7 +424,7 @@ class PosixEnv : public Env {
virtual Status DeleteFile ( const std : : string & fname ) {
virtual Status DeleteFile ( const std : : string & fname ) {
Status result ;
Status result ;
if ( unlink ( fname . c_str ( ) ) ! = 0 ) {
if ( unlink ( fname . c_str ( ) ) ! = 0 ) {
result = IO Error( fname , errno ) ;
result = Posix Error( fname , errno ) ;
}
}
return result ;
return result ;
}
}
@ -428,7 +432,7 @@ class PosixEnv : public Env {
virtual Status CreateDir ( const std : : string & name ) {
virtual Status CreateDir ( const std : : string & name ) {
Status result ;
Status result ;
if ( mkdir ( name . c_str ( ) , 0755 ) ! = 0 ) {
if ( mkdir ( name . c_str ( ) , 0755 ) ! = 0 ) {
result = IO Error( name , errno ) ;
result = Posix Error( name , errno ) ;
}
}
return result ;
return result ;
}
}
@ -436,7 +440,7 @@ class PosixEnv : public Env {
virtual Status DeleteDir ( const std : : string & name ) {
virtual Status DeleteDir ( const std : : string & name ) {
Status result ;
Status result ;
if ( rmdir ( name . c_str ( ) ) ! = 0 ) {
if ( rmdir ( name . c_str ( ) ) ! = 0 ) {
result = IO Error( name , errno ) ;
result = Posix Error( name , errno ) ;
}
}
return result ;
return result ;
}
}
@ -446,7 +450,7 @@ class PosixEnv : public Env {
struct stat sbuf ;
struct stat sbuf ;
if ( stat ( fname . c_str ( ) , & sbuf ) ! = 0 ) {
if ( stat ( fname . c_str ( ) , & sbuf ) ! = 0 ) {
* size = 0 ;
* size = 0 ;
s = IO Error( fname , errno ) ;
s = Posix Error( fname , errno ) ;
} else {
} else {
* size = sbuf . st_size ;
* size = sbuf . st_size ;
}
}
@ -456,7 +460,7 @@ class PosixEnv : public Env {
virtual Status RenameFile ( const std : : string & src , const std : : string & target ) {
virtual Status RenameFile ( const std : : string & src , const std : : string & target ) {
Status result ;
Status result ;
if ( rename ( src . c_str ( ) , target . c_str ( ) ) ! = 0 ) {
if ( rename ( src . c_str ( ) , target . c_str ( ) ) ! = 0 ) {
result = IO Error( src , errno ) ;
result = Posix Error( src , errno ) ;
}
}
return result ;
return result ;
}
}
@ -466,12 +470,12 @@ class PosixEnv : public Env {
Status result ;
Status result ;
int fd = open ( fname . c_str ( ) , O_RDWR | O_CREAT , 0644 ) ;
int fd = open ( fname . c_str ( ) , O_RDWR | O_CREAT , 0644 ) ;
if ( fd < 0 ) {
if ( fd < 0 ) {
result = IO Error( fname , errno ) ;
result = Posix Error( fname , errno ) ;
} else if ( ! locks_ . Insert ( fname ) ) {
} else if ( ! locks_ . Insert ( fname ) ) {
close ( fd ) ;
close ( fd ) ;
result = Status : : IOError ( " lock " + fname , " already held by process " ) ;
result = Status : : IOError ( " lock " + fname , " already held by process " ) ;
} else if ( LockOrUnlock ( fd , true ) = = - 1 ) {
} else if ( LockOrUnlock ( fd , true ) = = - 1 ) {
result = IO Error( " lock " + fname , errno ) ;
result = Posix Error( " lock " + fname , errno ) ;
close ( fd ) ;
close ( fd ) ;
locks_ . Remove ( fname ) ;
locks_ . Remove ( fname ) ;
} else {
} else {
@ -487,7 +491,7 @@ class PosixEnv : public Env {
PosixFileLock * my_lock = reinterpret_cast < PosixFileLock * > ( lock ) ;
PosixFileLock * my_lock = reinterpret_cast < PosixFileLock * > ( lock ) ;
Status result ;
Status result ;
if ( LockOrUnlock ( my_lock - > fd_ , false ) = = - 1 ) {
if ( LockOrUnlock ( my_lock - > fd_ , false ) = = - 1 ) {
result = IO Error( " unlock " , errno ) ;
result = Posix Error( " unlock " , errno ) ;
}
}
locks_ . Remove ( my_lock - > name_ ) ;
locks_ . Remove ( my_lock - > name_ ) ;
close ( my_lock - > fd_ ) ;
close ( my_lock - > fd_ ) ;
@ -524,7 +528,7 @@ class PosixEnv : public Env {
FILE * f = fopen ( fname . c_str ( ) , " w " ) ;
FILE * f = fopen ( fname . c_str ( ) , " w " ) ;
if ( f = = NULL ) {
if ( f = = NULL ) {
* result = NULL ;
* result = NULL ;
return IO Error( fname , errno ) ;
return Posix Error( fname , errno ) ;
} else {
} else {
* result = new PosixLogger ( f , & PosixEnv : : gettid ) ;
* result = new PosixLogger ( f , & PosixEnv : : gettid ) ;
return Status : : OK ( ) ;
return Status : : OK ( ) ;