vfs: functions to change a vnode busy status and ID

The kernel version is only partially tested.

Change-Id: I9a2f6c78087154ab137eadbced99062a8a2dd688
Reviewed-on: https://review.haiku-os.org/c/918
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
ahenriksson
2019-02-19 18:44:43 +00:00
committed by waddlesplash
parent 518af33f33
commit 8497a2cc28
6 changed files with 96 additions and 0 deletions
+2
View File
@@ -330,6 +330,8 @@ extern status_t remove_vnode(fs_volume* volume, ino_t vnodeID);
extern status_t unremove_vnode(fs_volume* volume, ino_t vnodeID); extern status_t unremove_vnode(fs_volume* volume, ino_t vnodeID);
extern status_t get_vnode_removed(fs_volume* volume, ino_t vnodeID, extern status_t get_vnode_removed(fs_volume* volume, ino_t vnodeID,
bool* _removed); bool* _removed);
extern status_t mark_vnode_busy(fs_volume* volume, ino_t vnodeID, bool busy);
extern status_t change_vnode_id(fs_volume* volume, ino_t vnodeID, ino_t newID);
extern fs_volume* volume_for_vnode(fs_vnode* vnode); extern fs_volume* volume_for_vnode(fs_vnode* vnode);
extern status_t check_access_permissions(int accessMode, mode_t mode, extern status_t check_access_permissions(int accessMode, mode_t mode,
gid_t nodeGroupID, uid_t nodeUserID); gid_t nodeGroupID, uid_t nodeUserID);
@@ -944,6 +944,8 @@
#define remove_vnode fssh_remove_vnode #define remove_vnode fssh_remove_vnode
#define unremove_vnode fssh_unremove_vnode #define unremove_vnode fssh_unremove_vnode
#define get_vnode_removed fssh_get_vnode_removed #define get_vnode_removed fssh_get_vnode_removed
#define mark_vnode_busy fssh_mark_vnode_busy
#define change_vnode_id fssh_change_vnode_id
#define volume_for_vnode fssh_volume_for_vnode #define volume_for_vnode fssh_volume_for_vnode
#define check_access_permissions fssh_check_access_permissions #define check_access_permissions fssh_check_access_permissions
#define read_pages fssh_read_pages #define read_pages fssh_read_pages
@@ -360,6 +360,10 @@ extern fssh_status_t fssh_unremove_vnode(fssh_fs_volume *volume,
fssh_vnode_id vnodeID); fssh_vnode_id vnodeID);
extern fssh_status_t fssh_get_vnode_removed(fssh_fs_volume *volume, extern fssh_status_t fssh_get_vnode_removed(fssh_fs_volume *volume,
fssh_vnode_id vnodeID, bool* removed); fssh_vnode_id vnodeID, bool* removed);
extern fssh_status_t fssh_mark_vnode_busy(fssh_fs_volume* volume,
fssh_vnode_id vnodeID, bool busy);
extern fssh_status_t fssh_change_vnode_id(fssh_fs_volume* volume,
fssh_vnode_id vnodeID, fssh_vnode_id newID);
extern fssh_fs_volume* fssh_volume_for_vnode(fssh_fs_vnode *vnode); extern fssh_fs_volume* fssh_volume_for_vnode(fssh_fs_vnode *vnode);
extern fssh_status_t fssh_check_access_permissions(int accessMode, extern fssh_status_t fssh_check_access_permissions(int accessMode,
fssh_mode_t mode, fssh_gid_t nodeGroupID, fssh_mode_t mode, fssh_gid_t nodeGroupID,
+2
View File
@@ -52,6 +52,8 @@ public:
{ return fDevice; } { return fDevice; }
ino_t InodeId() const ino_t InodeId() const
{ return fInode; } { return fInode; }
void SetVnodeID(ino_t id)
{ fInode = id; }
protected: protected:
virtual void DeleteObject(); virtual void DeleteObject();
+41
View File
@@ -3981,6 +3981,47 @@ get_vnode_removed(fs_volume* volume, ino_t vnodeID, bool* _removed)
} }
extern "C" status_t
mark_vnode_busy(fs_volume* volume, ino_t vnodeID, bool busy)
{
ReadLocker locker(sVnodeLock);
struct vnode* vnode = lookup_vnode(volume->id, vnodeID);
if (vnode == NULL)
return B_ENTRY_NOT_FOUND;
// are we trying to mark an already busy node busy again?
if (busy && vnode->IsBusy())
return B_BUSY;
vnode->Lock();
vnode->SetBusy(busy);
vnode->Unlock();
return B_OK;
}
extern "C" status_t
change_vnode_id(fs_volume* volume, ino_t vnodeID, ino_t newID)
{
WriteLocker locker(sVnodeLock);
struct vnode* vnode = lookup_vnode(volume->id, vnodeID);
if (vnode == NULL)
return B_ENTRY_NOT_FOUND;
sVnodeTable->Remove(vnode);
vnode->id = newID;
sVnodeTable->Insert(vnode);
if (vnode->cache != NULL)
((VMVnodeCache*)vnode->cache)->SetVnodeID(newID);
return B_OK;
}
extern "C" fs_volume* extern "C" fs_volume*
volume_for_vnode(fs_vnode* _vnode) volume_for_vnode(fs_vnode* _vnode)
{ {
+45
View File
@@ -2117,6 +2117,51 @@ fssh_get_vnode_removed(fssh_fs_volume *volume, fssh_vnode_id vnodeID, bool* remo
} }
extern "C" fssh_status_t
fssh_mark_vnode_busy(fssh_fs_volume* volume, fssh_vnode_id vnodeID, bool busy)
{
fssh_mutex_lock(&sVnodeMutex);
struct vnode* vnode = lookup_vnode(volume->id, vnodeID);
if (vnode == NULL) {
fssh_mutex_unlock(&sVnodeMutex);
return FSSH_B_ENTRY_NOT_FOUND;
}
// are we trying to mark an already busy node busy again?
if (busy && vnode->busy) {
fssh_mutex_unlock(&sVnodeMutex);
return FSSH_B_BUSY;
}
vnode->busy = busy;
fssh_mutex_unlock(&sVnodeMutex);
return FSSH_B_OK;
}
extern "C" fssh_status_t
fssh_change_vnode_id(fssh_fs_volume* volume, fssh_vnode_id vnodeID,
fssh_vnode_id newID)
{
fssh_mutex_lock(&sVnodeMutex);
struct vnode* vnode = lookup_vnode(volume->id, vnodeID);
if (vnode == NULL) {
fssh_mutex_unlock(&sVnodeMutex);
return FSSH_B_ENTRY_NOT_FOUND;
}
hash_remove(sVnodeTable, vnode);
vnode->id = newID;
hash_insert(sVnodeTable, vnode);
fssh_mutex_unlock(&sVnodeMutex);
return FSSH_B_OK;
}
extern "C" fssh_fs_volume* extern "C" fssh_fs_volume*
fssh_volume_for_vnode(fssh_fs_vnode *_vnode) fssh_volume_for_vnode(fssh_fs_vnode *_vnode)
{ {