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
This commit is contained in:
Axel Dörfler 2002-09-08 15:25:23 +00:00
parent 3597a35dba
commit a130fd5520
3 changed files with 42 additions and 29 deletions

View File

@ -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 // update the last modification time in memory, it will be written
// back to the inode, and the index when the file is closed // 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; Node()->last_modified_time = (bigtime_t)time(NULL) << INODE_TIME_SHIFT;
if (Flags() & INODE_NO_CACHE) if (Flags() & INODE_NO_CACHE)
@ -1460,7 +1461,9 @@ Inode::ShrinkStream(Transaction *transaction, off_t size)
status_t status_t
Inode::SetFileSize(Transaction *transaction, off_t size) 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; return B_BAD_VALUE;
off_t oldSize = Node()->data.size; off_t oldSize = Node()->data.size;

View File

@ -477,7 +477,7 @@ Stream<Cache>::ReadAt(off_t pos,uint8 *buffer,size_t *_length)
template<class Cache> template<class Cache>
status_t status_t
Stream<Cache>::WriteAt(Transaction *transaction,off_t pos,const uint8 *buffer,size_t *_length) Stream<Cache>::WriteAt(Transaction *transaction, off_t pos, const uint8 *buffer, size_t *_length)
{ {
size_t length = *_length; size_t length = *_length;
@ -487,16 +487,18 @@ Stream<Cache>::WriteAt(Transaction *transaction,off_t pos,const uint8 *buffer,si
else if (pos + length > Node()->data.size) { else if (pos + length > Node()->data.size) {
off_t oldSize = 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) if (Flags() & INODE_NO_CACHE)
return B_BAD_VALUE; return B_BAD_VALUE;
// the transaction doesn't have to be started already // the transaction doesn't have to be started already
if ((Flags() & INODE_NO_TRANSACTION) == 0) if ((Flags() & INODE_NO_TRANSACTION) == 0)
transaction->Start(fVolume,BlockNumber()); transaction->Start(fVolume, BlockNumber());
// let's grow the data stream to the size needed // 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) { if (status < B_OK) {
*_length = 0; *_length = 0;
RETURN_ERROR(status); RETURN_ERROR(status);

View File

@ -205,7 +205,10 @@ vnode_ops fs_entry = {
&bfs_read_query // read query &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; 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 // 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 // of BeOS R5), or just comment out the line, it won't do any harm and is
// used only for debugging purposes. // used only for debugging purposes.
load_driver_symbols("obfs"); load_driver_symbols(BFS_NAME);
#endif #endif
Volume *volume = new Volume(nsid); 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); strncpy(info->volume_name, volume->Name(), sizeof(info->volume_name) - 1);
info->volume_name[sizeof(info->volume_name) - 1] = '\0'; info->volume_name[sizeof(info->volume_name) - 1] = '\0';
// File system name (ToDo: has to change to "bfs" later) // File system name
strcpy(info->fsh_name,"obfs"); strcpy(info->fsh_name,BFS_NAME);
return B_NO_ERROR; 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()); Transaction transaction(volume,inode->BlockNumber());
bfs_inode *node = inode->Node(); 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) { 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; 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) if (mask & WSTAT_GID)
node->gid = stat->st_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) { if (mask & WSTAT_MTIME) {
// Index::UpdateLastModified() will set the new time in the inode // Index::UpdateLastModified() will set the new time in the inode
Index index(volume); Index index(volume);