From a130fd552092e739e6d5540795f5e3cbaa5c3cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 8 Sep 2002 15:25:23 +0000 Subject: [PATCH] Inode::SetFileSize() now doesn't allow changing the file size of uncached files anymore (only Inode::WriteAt() denied it before). Introduced a BFS_NAME define to be able to switch easier between "obfs", and "bfs". bfs_write_stat() didn't return the error code if Inode::SetFileSize() failed; instead, it always reported success. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@995 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/file_systems/bfs/Inode.cpp | 5 +- src/add-ons/kernel/file_systems/bfs/Stream.h | 10 ++-- .../file_systems/bfs/kernel_interface.cpp | 56 +++++++++++-------- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index 1b309587ec..bad1daf940 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -886,6 +886,7 @@ Inode::WriteAt(Transaction *transaction,off_t pos,const uint8 *buffer,size_t *_l // update the last modification time in memory, it will be written // back to the inode, and the index when the file is closed + // ToDo: should update the internal last modified time only at this point! Node()->last_modified_time = (bigtime_t)time(NULL) << INODE_TIME_SHIFT; if (Flags() & INODE_NO_CACHE) @@ -1460,7 +1461,9 @@ Inode::ShrinkStream(Transaction *transaction, off_t size) status_t Inode::SetFileSize(Transaction *transaction, off_t size) { - if (size < 0) + if (size < 0 + // uncached files can't be resized + || Flags() & INODE_NO_CACHE) return B_BAD_VALUE; off_t oldSize = Node()->data.size; diff --git a/src/add-ons/kernel/file_systems/bfs/Stream.h b/src/add-ons/kernel/file_systems/bfs/Stream.h index 4685f801ed..fcccd490c7 100644 --- a/src/add-ons/kernel/file_systems/bfs/Stream.h +++ b/src/add-ons/kernel/file_systems/bfs/Stream.h @@ -477,7 +477,7 @@ Stream::ReadAt(off_t pos,uint8 *buffer,size_t *_length) template status_t -Stream::WriteAt(Transaction *transaction,off_t pos,const uint8 *buffer,size_t *_length) +Stream::WriteAt(Transaction *transaction, off_t pos, const uint8 *buffer, size_t *_length) { size_t length = *_length; @@ -487,16 +487,18 @@ Stream::WriteAt(Transaction *transaction,off_t pos,const uint8 *buffer,si else if (pos + length > Node()->data.size) { off_t oldSize = Size(); - // uncached files can't be resized + // uncached files can't be resized (Inode::SetFileSize() also + // doesn't allow this, but this way we don't have to start a + // transaction to find out). if (Flags() & INODE_NO_CACHE) return B_BAD_VALUE; // the transaction doesn't have to be started already if ((Flags() & INODE_NO_TRANSACTION) == 0) - transaction->Start(fVolume,BlockNumber()); + transaction->Start(fVolume, BlockNumber()); // let's grow the data stream to the size needed - status_t status = SetFileSize(transaction,pos + length); + status_t status = SetFileSize(transaction, pos + length); if (status < B_OK) { *_length = 0; RETURN_ERROR(status); diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index 0c3b0030ad..78dccf76d3 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -205,7 +205,10 @@ vnode_ops fs_entry = { &bfs_read_query // read query }; -#define BFS_IO_SIZE 65536 +#define BFS_IO_SIZE 65536 +#define BFS_NAME "obfs" + // ToDo: has to change to "bfs" later + int32 api_version = B_CUR_FS_API_VERSION; @@ -222,7 +225,7 @@ bfs_mount(nspace_id nsid, const char *device, ulong flags, void *parms, // to your KernelExport.h include (since it's missing there in some releases // of BeOS R5), or just comment out the line, it won't do any harm and is // used only for debugging purposes. - load_driver_symbols("obfs"); + load_driver_symbols(BFS_NAME); #endif Volume *volume = new Volume(nsid); @@ -282,8 +285,8 @@ bfs_read_fs_stat(void *_ns, struct fs_info *info) strncpy(info->volume_name, volume->Name(), sizeof(info->volume_name) - 1); info->volume_name[sizeof(info->volume_name) - 1] = '\0'; - // File system name (ToDo: has to change to "bfs" later) - strcpy(info->fsh_name,"obfs"); + // File system name + strcpy(info->fsh_name,BFS_NAME); return B_NO_ERROR; } @@ -683,9 +686,32 @@ bfs_write_stat(void *_ns, void *_node, struct stat *stat, long mask) Transaction transaction(volume,inode->BlockNumber()); bfs_inode *node = inode->Node(); - + + if (mask & WSTAT_SIZE) { + // Since WSTAT_SIZE is the only thing that can fail directly, we + // do it first, so that the inode state will still be consistent + // with the on-disk version + if (inode->IsDirectory()) + return B_IS_A_DIRECTORY; + + if (inode->Size() != stat->st_size) { + status = inode->SetFileSize(&transaction, stat->st_size); + if (status < B_OK) + return status; + + // fill the new blocks (if any) with zeros + inode->FillGapWithZeros(inode->OldSize(), inode->Size()); + + Index index(volume); + index.UpdateSize(&transaction, inode); + + if ((mask & WSTAT_MTIME) == 0) + index.UpdateLastModified(&transaction, inode); + } + } + if (mask & WSTAT_MODE) { - PRINT(("original mode = %ld, stat->st_mode = %ld\n",node->mode,stat->st_mode)); + PRINT(("original mode = %ld, stat->st_mode = %ld\n", node->mode, stat->st_mode)); node->mode = node->mode & ~S_IUMSK | stat->st_mode & S_IUMSK; } @@ -694,24 +720,6 @@ bfs_write_stat(void *_ns, void *_node, struct stat *stat, long mask) if (mask & WSTAT_GID) node->gid = stat->st_gid; - if (mask & WSTAT_SIZE) { - if (inode->IsDirectory()) - return B_IS_A_DIRECTORY; - - if (inode->Size() != stat->st_size) { - status = inode->SetFileSize(&transaction,stat->st_size); - - // fill the new blocks (if any) with zeros - inode->FillGapWithZeros(inode->OldSize(),inode->Size()); - - Index index(volume); - index.UpdateSize(&transaction,inode); - - if ((mask & WSTAT_MTIME) == 0) - index.UpdateLastModified(&transaction,inode); - } - } - if (mask & WSTAT_MTIME) { // Index::UpdateLastModified() will set the new time in the inode Index index(volume);