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
|
// 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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user