X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/3e170ce000f1506b7b5d2c5c7faec85ceabb573d..a39ff7e25e19b3a8c3020042a3872ca9ec9659f1:/bsd/kern/kern_lockf.c?ds=sidebyside diff --git a/bsd/kern/kern_lockf.c b/bsd/kern/kern_lockf.c index 46c4f2e77..5284f060c 100644 --- a/bsd/kern/kern_lockf.c +++ b/bsd/kern/kern_lockf.c @@ -76,7 +76,7 @@ #include #include #include -#include +#include #include @@ -149,6 +149,7 @@ static void lf_hold_assertion(task_t, struct lockf *); static void lf_jump_to_queue_head(struct lockf *, struct lockf *); static void lf_drop_assertion(struct lockf *); static void lf_boost_blocking_proc(struct lockf *, struct lockf *); +static void lf_adjust_assertion(struct lockf *block); #endif /* IMPORTANCE_INHERITANCE */ /* @@ -329,6 +330,12 @@ lf_advlock(struct vnop_advlock_args *ap) FREE(lock, M_LOCKF); break; +#if CONFIG_EMBEDDED + case F_GETLKPID: + error = lf_getlock(lock, fl, fl->l_pid); + FREE(lock, M_LOCKF); + break; +#endif default: FREE(lock, M_LOCKF); @@ -665,6 +672,12 @@ lf_setlock(struct lockf *lock, struct timespec *timeout) * in the spurious case, which would create a cycle) */ TAILQ_REMOVE(&lock->lf_next->lf_blkhd, lock, lf_block); +#if IMPORTANCE_INHERITANCE + /* + * Adjust the boost on lf_next. + */ + lf_adjust_assertion(lock->lf_next); +#endif /* IMPORTANCE_INHERITANCE */ lock->lf_next = NULL; if (error == 0) { @@ -1432,7 +1445,7 @@ lf_printlist(const char *tag, struct lockf *lock) static void lf_hold_assertion(task_t block_task, struct lockf *block) { - if (task_importance_hold_file_lock_assertion(block_task, 1)) { + if (task_importance_hold_file_lock_assertion(block_task, 1) == 0) { block->lf_boosted = LF_BOOSTED; LOCKF_DEBUG(LF_DBG_IMPINH, "lf: importance hold file lock assert on pid %d lock %p\n", @@ -1483,6 +1496,50 @@ lf_drop_assertion(struct lockf *block) block->lf_boosted = LF_NOT_BOOSTED; } +/* + * lf_adjust_assertion + * + * Adjusts importance assertion of file lock. Goes through + * all the blocking locks and checks if the file lock needs + * to be boosted anymore. + * + * Parameters: block lockf structure which needs to be adjusted. + * + * Returns: + */ +static void +lf_adjust_assertion(struct lockf *block) +{ + boolean_t drop_boost = TRUE; + struct lockf *next; + + /* Return if the lock is not boosted */ + if (block->lf_boosted == LF_NOT_BOOSTED) { + return; + } + + TAILQ_FOREACH(next, &block->lf_blkhd, lf_block) { + /* Check if block and next are same type of locks */ + if (((block->lf_flags & next->lf_flags & F_POSIX) != 0) || + ((block->lf_flags & next->lf_flags & F_OFD_LOCK) && + (block->lf_owner != next->lf_owner) && + (NULL != block->lf_owner && NULL != next->lf_owner))) { + + /* Check if next would be boosting block */ + if (task_is_importance_donor(proc_task(next->lf_owner)) && + task_is_importance_receiver_type(proc_task(block->lf_owner))) { + /* Found a lock boosting block */ + drop_boost = FALSE; + break; + } + } + } + + if (drop_boost) { + lf_drop_assertion(block); + } +} + static void lf_boost_blocking_proc(struct lockf *lock, struct lockf *block) {