if (!list_empty(&fl->fl_link))
panic("Attempting to free lock on active lock list");
+ if (fl->fl_ops) {
+ if (fl->fl_ops->fl_release_private)
+ fl->fl_ops->fl_release_private(fl);
+ fl->fl_ops = NULL;
+ }
+ fl->fl_lmops = NULL;
+
kmem_cache_free(filelock_cache, fl);
}
fl->fl_notify = NULL;
fl->fl_insert = NULL;
fl->fl_remove = NULL;
+ fl->fl_ops = NULL;
+ fl->fl_lmops = NULL;
}
EXPORT_SYMBOL(locks_init_lock);
new->fl_notify = fl->fl_notify;
new->fl_insert = fl->fl_insert;
new->fl_remove = fl->fl_remove;
- new->fl_u = fl->fl_u;
+ new->fl_ops = fl->fl_ops;
+ new->fl_lmops = fl->fl_lmops;
+ if (fl->fl_ops && fl->fl_ops->fl_copy_lock)
+ fl->fl_ops->fl_copy_lock(new, fl);
}
EXPORT_SYMBOL(locks_copy_lock);
fl->fl_notify = NULL;
fl->fl_insert = NULL;
fl->fl_remove = NULL;
+ fl->fl_ops = NULL;
+ fl->fl_lmops = NULL;
return assign_type(fl, l->l_type);
}
fl->fl_notify = NULL;
fl->fl_insert = NULL;
fl->fl_remove = NULL;
+ fl->fl_ops = NULL;
+ fl->fl_lmops = NULL;
switch (l->l_type) {
case F_RDLCK:
fl->fl_notify = NULL;
fl->fl_insert = NULL;
fl->fl_remove = NULL;
+ fl->fl_ops = NULL;
+ fl->fl_lmops = NULL;
*flp = fl;
return 0;
static inline int
posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
{
- /* FIXME: Replace this sort of thing with struct file_lock_operations */
- if ((fl1->fl_type | fl2->fl_type) & FL_LOCKD)
- return fl1->fl_owner == fl2->fl_owner &&
- fl1->fl_pid == fl2->fl_pid;
+ if (fl1->fl_lmops && fl1->fl_lmops->fl_compare_owner)
+ return fl2->fl_lmops == fl1->fl_lmops &&
+ fl1->fl_lmops->fl_compare_owner(fl1, fl2);
return fl1->fl_owner == fl2->fl_owner;
}
error = -EFAULT;
if (!copy_to_user(l, &flock, sizeof(flock)))
error = 0;
-
out:
return error;
}
lock.fl_owner = owner;
lock.fl_pid = current->tgid;
lock.fl_file = filp;
+ lock.fl_ops = NULL;
+ lock.fl_lmops = NULL;
if (filp->f_op && filp->f_op->lock != NULL) {
filp->f_op->lock(filp, F_SETLK, &lock);
before = &fl->fl_next;
}
unlock_kernel();
+ if (lock.fl_ops && lock.fl_ops->fl_release_private)
+ lock.fl_ops->fl_release_private(&lock);
}
EXPORT_SYMBOL(locks_remove_posix);
*/
typedef struct files_struct *fl_owner_t;
+struct file_lock_operations {
+ void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
+ void (*fl_release_private)(struct file_lock *);
+};
+
+struct lock_manager_operations {
+ int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
+};
+
/* that will die - we need it for nfs_lock_info */
#include <linux/nfs_fs_i.h>
struct fasync_struct * fl_fasync; /* for lease break notifications */
unsigned long fl_break_time; /* for nonblocking lease breaks */
+ struct file_lock_operations *fl_ops; /* Callbacks for filesystems */
+ struct lock_manager_operations *fl_lmops; /* Callbacks for lockmanagers */
union {
struct nfs_lock_info nfs_fl;
} fl_u;