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:
Pawel Dziepak 2012-06-27 18:36:07 +02:00
parent 55899460db
commit d764d148b1
2 changed files with 29 additions and 5 deletions

View File

@ -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 {

View File

@ -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;