Allow file systems to manage file locks
Haiku implements file locking at vfs level. That would not work for remote and shared file systems, since they need to negotiate locks with peers. This patch introduces three additional hooks in fs_interface that allow file system module to take over the management of file locks.
This commit is contained in:
parent
55899460db
commit
d764d148b1
@ -242,6 +242,14 @@ struct fs_vnode_ops {
|
|||||||
fs_vnode* _superVnode, ino_t* _nodeID);
|
fs_vnode* _superVnode, ino_t* _nodeID);
|
||||||
status_t (*get_super_vnode)(fs_volume* volume, fs_vnode* vnode,
|
status_t (*get_super_vnode)(fs_volume* volume, fs_vnode* vnode,
|
||||||
fs_volume* superVolume, fs_vnode* superVnode);
|
fs_volume* superVolume, fs_vnode* superVnode);
|
||||||
|
|
||||||
|
/* lock operations */
|
||||||
|
status_t (*test_lock)(fs_volume* volume, fs_vnode* vnode, void* cookie,
|
||||||
|
struct flock* lock);
|
||||||
|
status_t (*acquire_lock)(fs_volume* volume, fs_vnode* vnode, void* cookie,
|
||||||
|
const struct flock* lock, bool wait);
|
||||||
|
status_t (*release_lock)(fs_volume* volume, fs_vnode* vnode, void* cookie,
|
||||||
|
const struct flock* lock);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct file_system_module_info {
|
struct file_system_module_info {
|
||||||
|
@ -5475,7 +5475,10 @@ file_close(struct file_descriptor* descriptor)
|
|||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// remove all outstanding locks for this team
|
// remove all outstanding locks for this team
|
||||||
release_advisory_lock(vnode, NULL);
|
if (HAS_FS_CALL(vnode, release_lock))
|
||||||
|
status = FS_CALL(vnode, release_lock, descriptor->cookie, NULL);
|
||||||
|
else
|
||||||
|
status = release_advisory_lock(vnode, NULL);
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -6006,7 +6009,11 @@ common_fcntl(int fd, int op, uint32 argument, bool kernel)
|
|||||||
|
|
||||||
case F_GETLK:
|
case F_GETLK:
|
||||||
if (vnode != NULL) {
|
if (vnode != NULL) {
|
||||||
status = get_advisory_lock(vnode, &flock);
|
if (HAS_FS_CALL(vnode, test_lock)) {
|
||||||
|
status = FS_CALL(vnode, test_lock, descriptor->cookie,
|
||||||
|
&flock);
|
||||||
|
} else
|
||||||
|
status = get_advisory_lock(vnode, &flock);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// copy back flock structure
|
// copy back flock structure
|
||||||
status = user_memcpy((struct flock*)argument, &flock,
|
status = user_memcpy((struct flock*)argument, &flock,
|
||||||
@ -6025,7 +6032,11 @@ common_fcntl(int fd, int op, uint32 argument, bool kernel)
|
|||||||
if (vnode == NULL) {
|
if (vnode == NULL) {
|
||||||
status = B_BAD_VALUE;
|
status = B_BAD_VALUE;
|
||||||
} else if (flock.l_type == F_UNLCK) {
|
} else if (flock.l_type == F_UNLCK) {
|
||||||
status = release_advisory_lock(vnode, &flock);
|
if (HAS_FS_CALL(vnode, release_lock)) {
|
||||||
|
status = FS_CALL(vnode, release_lock, descriptor->cookie,
|
||||||
|
&flock);
|
||||||
|
} else
|
||||||
|
status = release_advisory_lock(vnode, &flock);
|
||||||
} else {
|
} else {
|
||||||
// the open mode must match the lock type
|
// the open mode must match the lock type
|
||||||
if (((descriptor->open_mode & O_RWMASK) == O_RDONLY
|
if (((descriptor->open_mode & O_RWMASK) == O_RDONLY
|
||||||
@ -6034,8 +6045,13 @@ common_fcntl(int fd, int op, uint32 argument, bool kernel)
|
|||||||
&& flock.l_type == F_RDLCK))
|
&& flock.l_type == F_RDLCK))
|
||||||
status = B_FILE_ERROR;
|
status = B_FILE_ERROR;
|
||||||
else {
|
else {
|
||||||
status = acquire_advisory_lock(vnode, -1,
|
if (HAS_FS_CALL(vnode, acquire_lock)) {
|
||||||
&flock, op == F_SETLKW);
|
status = FS_CALL(vnode, acquire_lock,
|
||||||
|
descriptor->cookie, &flock, op == F_SETLKW);
|
||||||
|
} else {
|
||||||
|
status = acquire_advisory_lock(vnode, -1,
|
||||||
|
&flock, op == F_SETLKW);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user