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:
parent
3597a35dba
commit
a130fd5520
@ -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;
|
||||
|
@ -477,7 +477,7 @@ Stream<Cache>::ReadAt(off_t pos,uint8 *buffer,size_t *_length)
|
||||
|
||||
template<class Cache>
|
||||
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;
|
||||
|
||||
@ -487,16 +487,18 @@ Stream<Cache>::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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user