-struct ll_lock_tree_node * ll_node_from_inode(struct inode *inode, __u64 start,
- __u64 end, ldlm_mode_t mode)
-{
- struct ll_lock_tree_node *node;
-
- OBD_ALLOC(node, sizeof(*node));
- if (node == NULL)
- RETURN(ERR_PTR(-ENOMEM));
-
- node->lt_inode = inode;
- node->lt_oid = ll_i2info(inode)->lli_smd->lsm_object_id;
- node->lt_policy.l_extent.start = start;
- node->lt_policy.l_extent.end = end;
- memset(&node->lt_lockh, 0, sizeof(node->lt_lockh));
- INIT_LIST_HEAD(&node->lt_locked_item);
- node->lt_mode = mode;
-
- return node;
-}
-
-int lt_compare(struct ll_lock_tree_node *one, struct ll_lock_tree_node *two)
-{
- /* To avoid multiple fs deadlock */
- if (one->lt_inode->i_sb->s_dev < two->lt_inode->i_sb->s_dev)
- return -1;
- if (one->lt_inode->i_sb->s_dev > two->lt_inode->i_sb->s_dev)
- return 1;
-
- if (one->lt_oid < two->lt_oid)
- return -1;
- if (one->lt_oid > two->lt_oid)
- return 1;
-
- if (one->lt_policy.l_extent.end < two->lt_policy.l_extent.start)
- return -1;
- if (one->lt_policy.l_extent.start > two->lt_policy.l_extent.end)
- return 1;
-
- return 0; /* they are the same object and overlap */
-}
-
-static void lt_merge(struct ll_lock_tree_node *dst,
- struct ll_lock_tree_node *src)
-{
- dst->lt_policy.l_extent.start = min(dst->lt_policy.l_extent.start,
- src->lt_policy.l_extent.start);
- dst->lt_policy.l_extent.end = max(dst->lt_policy.l_extent.end,
- src->lt_policy.l_extent.end);
-
- /* XXX could be a real call to the dlm to find superset modes */
- if (src->lt_mode == LCK_PW && dst->lt_mode != LCK_PW)
- dst->lt_mode = LCK_PW;
-}
-
-static void lt_insert(struct ll_lock_tree *tree,
- struct ll_lock_tree_node *node)
-{
- struct ll_lock_tree_node *walk;
- rb_node_t **p, *parent;
- ENTRY;
-
-restart:
- p = &tree->lt_root.rb_node;
- parent = NULL;
- while (*p) {
- parent = *p;
- walk = rb_entry(parent, struct ll_lock_tree_node, lt_node);
- switch (lt_compare(node, walk)) {
- case -1:
- p = &(*p)->rb_left;
- break;
- case 1:
- p = &(*p)->rb_right;
- break;
- case 0:
- lt_merge(node, walk);
- rb_erase(&walk->lt_node, &tree->lt_root);
- OBD_FREE(walk, sizeof(*walk));
- goto restart;
- break;
- default:
- LBUG();
- break;
- }
- }
- rb_link_node(&node->lt_node, parent, p);
- rb_insert_color(&node->lt_node, &tree->lt_root);
- EXIT;
-}
-
-static struct ll_lock_tree_node *lt_least_node(struct ll_lock_tree *tree)
-{
- rb_node_t *rbnode;
- struct ll_lock_tree_node *node = NULL;
-
- for ( rbnode = tree->lt_root.rb_node; rbnode != NULL;
- rbnode = rbnode->rb_left) {
- if (rbnode->rb_left == NULL) {
- node = rb_entry(rbnode, struct ll_lock_tree_node,
- lt_node);
- break;
- }
- }
- RETURN(node);
-}
-
-int ll_tree_unlock(struct ll_lock_tree *tree)
-{
- struct ll_lock_tree_node *node;
- struct list_head *pos, *n;
- struct inode *inode;
- int rc = 0;
- ENTRY;
-
- list_for_each_safe(pos, n, &tree->lt_locked_list) {
- node = list_entry(pos, struct ll_lock_tree_node,
- lt_locked_item);
-
- inode = node->lt_inode;
- rc = ll_extent_unlock(tree->lt_fd, inode,
- ll_i2info(inode)->lli_smd, node->lt_mode,
- &node->lt_lockh);
- if (rc != 0) {
- /* XXX better message */
- CERROR("couldn't unlock %d\n", rc);
- }
- list_del(&node->lt_locked_item);
- OBD_FREE(node, sizeof(*node));
- }
-
- while ((node = lt_least_node(tree))) {
- rb_erase(&node->lt_node, &tree->lt_root);
- OBD_FREE(node, sizeof(*node));
- }
-
- RETURN(rc);
-}
-
-int ll_tree_lock(struct ll_lock_tree *tree,
- struct ll_lock_tree_node *first_node,
- const char *buf, size_t count, int ast_flags)
-{
- struct ll_lock_tree_node *node;
- int rc = 0;
- ENTRY;