Whamcloud - gitweb
LU-14312 ldlm: don't change GROUP lock GID on client
[fs/lustre-release.git] / lustre / ldlm / ldlm_lockd.c
index faf7545..cbf9479 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/kthread.h>
 #include <linux/list.h>
 #include <libcfs/libcfs.h>
+#include <libcfs/linux/linux-mem.h>
 #include <lustre_errno.h>
 #include <lustre_dlm.h>
 #include <obd_class.h>
@@ -72,12 +73,12 @@ static struct ldlm_state *ldlm_state;
 /*
  * timeout for initial callback (AST) reply (bz10399)
  * Due to having to send a 32 bit time value over the
- * wire return it as time_t instead of time64_t
+ * wire return it as timeout_t instead of time64_t
  */
-static inline time_t ldlm_get_rq_timeout(void)
+static inline timeout_t ldlm_get_rq_timeout(void)
 {
        /* Non-AT value */
-       time_t timeout = min(ldlm_timeout, obd_timeout / 3);
+       timeout_t timeout = min(ldlm_timeout, obd_timeout / 3);
 
        return timeout < 1 ? 1 : timeout;
 }
@@ -152,8 +153,8 @@ static int expired_lock_dump;
 static LIST_HEAD(expired_lock_list);
 
 static int ldlm_lock_busy(struct ldlm_lock *lock);
-static int ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t timeout);
-static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t seconds);
+static int ldlm_add_waiting_lock(struct ldlm_lock *lock, timeout_t timeout);
+static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, timeout_t timeout);
 
 static inline int have_expired_locks(void)
 {
@@ -240,7 +241,7 @@ static int expired_lock_main(void *arg)
 
                        /* Check if we need to prolong timeout */
                        if (!OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_HPREQ_TIMEOUT) &&
-                           lock->l_callback_timeout != 0 && /* not AST error */
+                           lock->l_callback_timestamp != 0 && /* not AST error */
                            ldlm_lock_busy(lock)) {
                                LDLM_DEBUG(lock, "prolong the busy lock");
                                lock_res_and_lock(lock);
@@ -323,7 +324,7 @@ static void waiting_locks_callback(TIMER_DATA_TYPE unused)
        while (!list_empty(&waiting_locks_list)) {
                lock = list_entry(waiting_locks_list.next, struct ldlm_lock,
                                  l_pending_chain);
-               if (lock->l_callback_timeout > ktime_get_seconds() ||
+               if (lock->l_callback_timestamp > ktime_get_seconds() ||
                    lock->l_req_mode == LCK_GROUP)
                        break;
 
@@ -332,8 +333,7 @@ static void waiting_locks_callback(TIMER_DATA_TYPE unused)
                 * the waiting_locks_list and ldlm_add_waiting_lock()
                 * already grabbed a ref
                 */
-               list_del(&lock->l_pending_chain);
-               list_add(&lock->l_pending_chain, &expired_lock_list);
+               list_move(&lock->l_pending_chain, &expired_lock_list);
                need_dump = 1;
        }
 
@@ -350,12 +350,12 @@ static void waiting_locks_callback(TIMER_DATA_TYPE unused)
         */
        if (!list_empty(&waiting_locks_list)) {
                time64_t now = ktime_get_seconds();
-               time_t delta = 0;
+               timeout_t delta = 0;
 
                lock = list_entry(waiting_locks_list.next, struct ldlm_lock,
                                  l_pending_chain);
-               if (lock->l_callback_timeout - now > 0)
-                       delta = lock->l_callback_timeout - now;
+               if (lock->l_callback_timestamp - now > 0)
+                       delta = lock->l_callback_timestamp - now;
                mod_timer(&waiting_locks_timer,
                          jiffies + cfs_time_seconds(delta));
        }
@@ -374,26 +374,26 @@ static void waiting_locks_callback(TIMER_DATA_TYPE unused)
  *
  * Called with the namespace lock held.
  */
-static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t seconds)
+static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, timeout_t delay)
 {
        unsigned long timeout_jiffies = jiffies;
        time64_t now = ktime_get_seconds();
        time64_t deadline;
-       time_t timeout;
+       timeout_t timeout;
 
        if (!list_empty(&lock->l_pending_chain))
                return 0;
 
        if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_HPREQ_NOTIMEOUT) ||
            OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_HPREQ_TIMEOUT))
-               seconds = 1;
+               delay = 1;
 
-       deadline = now + seconds;
-       if (likely(deadline > lock->l_callback_timeout))
-               lock->l_callback_timeout = deadline;
+       deadline = now + delay;
+       if (likely(deadline > lock->l_callback_timestamp))
+               lock->l_callback_timestamp = deadline;
 
-       timeout = clamp_t(time_t, lock->l_callback_timeout - now,
-                         0, seconds);
+       timeout = clamp_t(timeout_t, lock->l_callback_timestamp - now,
+                         0, delay);
        timeout_jiffies += cfs_time_seconds(timeout);
 
        if (time_before(timeout_jiffies, waiting_locks_timer.expires) ||
@@ -433,7 +433,7 @@ static void ldlm_add_blocked_lock(struct ldlm_lock *lock)
                obd_stale_export_adjust(lock->l_export);
 }
 
-static int ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t timeout)
+static int ldlm_add_waiting_lock(struct ldlm_lock *lock, timeout_t timeout)
 {
        int ret;
 
@@ -482,7 +482,7 @@ static int ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t timeout)
        if (ret)
                ldlm_add_blocked_lock(lock);
 
-       LDLM_DEBUG(lock, "%sadding to wait list(timeout: %lld, AT: %s)",
+       LDLM_DEBUG(lock, "%sadding to wait list(timeout: %d, AT: %s)",
                   ret == 0 ? "not re-" : "", timeout,
                   AT_OFF ? "off" : "on");
        return ret;
@@ -513,12 +513,12 @@ static int __ldlm_del_waiting_lock(struct ldlm_lock *lock)
                } else {
                        time64_t now = ktime_get_seconds();
                        struct ldlm_lock *next;
-                       time_t delta = 0;
+                       timeout_t delta = 0;
 
                        next = list_entry(list_next, struct ldlm_lock,
                                          l_pending_chain);
-                       if (next->l_callback_timeout - now > 0)
-                               delta = lock->l_callback_timeout - now;
+                       if (next->l_callback_timestamp - now > 0)
+                               delta = lock->l_callback_timestamp - now;
 
                        mod_timer(&waiting_locks_timer,
                                  jiffies + cfs_time_seconds(delta));
@@ -566,7 +566,7 @@ int ldlm_del_waiting_lock(struct ldlm_lock *lock)
  *
  * Called with namespace lock held.
  */
-int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, time64_t timeout)
+int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, timeout_t timeout)
 {
        if (lock->l_export == NULL) {
                /* We don't have a "waiting locks list" on clients. */
@@ -608,7 +608,7 @@ int ldlm_del_waiting_lock(struct ldlm_lock *lock)
        RETURN(0);
 }
 
-int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, time64_t timeout)
+int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, timeout_t timeout)
 {
        RETURN(0);
 }
@@ -626,9 +626,9 @@ int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, time64_t timeout)
  *
  * \retval            timeout in seconds to wait for the client reply
  */
-time64_t ldlm_bl_timeout(struct ldlm_lock *lock)
+timeout_t ldlm_bl_timeout(struct ldlm_lock *lock)
 {
-       time64_t timeout;
+       timeout_t timeout;
 
        if (AT_OFF)
                return obd_timeout / 2;
@@ -640,7 +640,8 @@ time64_t ldlm_bl_timeout(struct ldlm_lock *lock)
         * lock callbacks too...
         */
        timeout = at_get(&lock->l_export->exp_bl_lock_at);
-       return max(timeout + (timeout >> 1), (time64_t)ldlm_enqueue_min);
+       return max_t(timeout_t, timeout + (timeout >> 1),
+                    (timeout_t)ldlm_enqueue_min);
 }
 EXPORT_SYMBOL(ldlm_bl_timeout);
 
@@ -664,7 +665,8 @@ static void ldlm_failed_ast(struct ldlm_lock *lock, int rc,
                 * the lock to the expired list
                 */
                LDLM_LOCK_GET(lock);
-       lock->l_callback_timeout = 0; /* differentiate it from expired locks */
+       /* differentiate it from expired locks */
+       lock->l_callback_timestamp = 0;
        list_add(&lock->l_pending_chain, &expired_lock_list);
        wake_up(&expired_lock_wait_queue);
        spin_unlock_bh(&waiting_locks_spinlock);
@@ -942,6 +944,7 @@ int ldlm_server_blocking_ast(struct ldlm_lock *lock,
 
        body = req_capsule_client_get(&req->rq_pill, &RMF_DLM_REQ);
        body->lock_handle[0] = lock->l_remote_handle;
+       body->lock_handle[1].cookie = lock->l_handle.h_cookie;
        body->lock_desc = *desc;
        body->lock_flags |= ldlm_flags_to_wire(lock->l_flags & LDLM_FL_AST_MASK);
 
@@ -1037,6 +1040,7 @@ int ldlm_server_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data)
        body = req_capsule_client_get(&req->rq_pill, &RMF_DLM_REQ);
 
        body->lock_handle[0] = lock->l_remote_handle;
+       body->lock_handle[1].cookie = lock->l_handle.h_cookie;
        body->lock_flags = ldlm_flags_to_wire(flags);
        ldlm_lock2desc(lock, &body->lock_desc);
        if (lvb_len > 0) {
@@ -1357,11 +1361,14 @@ int ldlm_handle_enqueue0(struct ldlm_namespace *ns,
                                     dlm_req->lock_desc.l_resource.lr_type,
                                     &dlm_req->lock_desc.l_policy_data,
                                     &lock->l_policy_data);
-       if (dlm_req->lock_desc.l_resource.lr_type == LDLM_EXTENT)
+       if (dlm_req->lock_desc.l_resource.lr_type == LDLM_EXTENT) {
                lock->l_req_extent = lock->l_policy_data.l_extent;
-       else if (dlm_req->lock_desc.l_resource.lr_type == LDLM_IBITS)
+       } else if (dlm_req->lock_desc.l_resource.lr_type == LDLM_IBITS) {
                lock->l_policy_data.l_inodebits.try_bits =
                        dlm_req->lock_desc.l_policy_data.l_inodebits.try_bits;
+               lock->l_policy_data.l_inodebits.li_gid =
+                       dlm_req->lock_desc.l_policy_data.l_inodebits.li_gid;
+       }
 
 existing_lock:
        cookie = req;
@@ -1743,11 +1750,14 @@ int ldlm_request_cancel(struct ptlrpc_request *req,
 
                if ((flags & LATF_STATS) && ldlm_is_ast_sent(lock) &&
                    lock->l_blast_sent != 0) {
-                       time64_t delay = ktime_get_real_seconds() -
-                                        lock->l_blast_sent;
+                       timeout_t delay = 0;
+
+                       if (ktime_get_real_seconds() > lock->l_blast_sent)
+                               delay = ktime_get_real_seconds() -
+                                       lock->l_blast_sent;
                        LDLM_DEBUG(lock,
-                                  "server cancels blocked lock after %llds",
-                                  (s64)delay);
+                                  "server cancels blocked lock after %ds",
+                                  delay);
                        at_measured(&lock->l_export->exp_bl_lock_at, delay);
                }
                ldlm_lock_cancel(lock);
@@ -1908,7 +1918,7 @@ static int ldlm_handle_cp_callback(struct ptlrpc_request *req,
                                     struct ldlm_request *dlm_req,
                                     struct ldlm_lock *lock)
 {
-       struct list_head ast_list;
+       LIST_HEAD(ast_list);
        int lvb_len;
        int rc = 0;
 
@@ -1916,15 +1926,13 @@ static int ldlm_handle_cp_callback(struct ptlrpc_request *req,
 
        LDLM_DEBUG(lock, "client completion callback handler START");
 
-       INIT_LIST_HEAD(&ast_list);
        if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_CANCEL_BL_CB_RACE)) {
                long to = cfs_time_seconds(1);
 
                ldlm_callback_reply(req, 0);
 
                while (to > 0) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(to);
+                       to = schedule_timeout_interruptible(to);
                        if (ldlm_is_granted(lock) ||
                            ldlm_is_destroyed(lock))
                                break;
@@ -2080,8 +2088,7 @@ static void ldlm_handle_gl_callback(struct ptlrpc_request *req,
        if (lock->l_granted_mode == LCK_PW &&
            !lock->l_readers && !lock->l_writers &&
            ktime_after(ktime_get(),
-                       ktime_add(lock->l_last_used,
-                                 ktime_set(ns->ns_dirty_age_limit, 0)))) {
+                       ktime_add(lock->l_last_used, ns->ns_dirty_age_limit))) {
                unlock_res_and_lock(lock);
 
                /* For MDS glimpse it is always DOM lock, set corresponding
@@ -2141,7 +2148,7 @@ static inline void init_blwi(struct ldlm_bl_work_item *blwi,
        init_completion(&blwi->blwi_comp);
        INIT_LIST_HEAD(&blwi->blwi_head);
 
-       if (memory_pressure_get())
+       if (current->flags & PF_MEMALLOC)
                blwi->blwi_mem_pressure = 1;
 
        blwi->blwi_ns = ns;
@@ -2149,8 +2156,7 @@ static inline void init_blwi(struct ldlm_bl_work_item *blwi,
        if (ld != NULL)
                blwi->blwi_ld = *ld;
        if (count) {
-               list_add(&blwi->blwi_head, cancels);
-               list_del_init(cancels);
+               list_splice_init(cancels, &blwi->blwi_head);
                blwi->blwi_count = count;
        } else {
                blwi->blwi_lock = lock;
@@ -2213,6 +2219,11 @@ int ldlm_bl_to_thread_list(struct ldlm_namespace *ns, struct ldlm_lock_desc *ld,
        return ldlm_bl_to_thread(ns, ld, NULL, cancels, count, cancel_flags);
 }
 
+int ldlm_bl_to_thread_ns(struct ldlm_namespace *ns)
+{
+       return ldlm_bl_to_thread(ns, NULL, NULL, NULL, 0, LCF_ASYNC);
+}
+
 int ldlm_bl_thread_wakeup(void)
 {
        wake_up(&ldlm_state->ldlm_bl_pool->blp_waitq);
@@ -2407,6 +2418,8 @@ static int ldlm_callback_handler(struct ptlrpc_request *req)
                ldlm_lock_remove_from_lru(lock);
                ldlm_set_bl_ast(lock);
        }
+       if (lock->l_remote_handle.cookie == 0)
+               lock->l_remote_handle = dlm_req->lock_handle[1];
        unlock_res_and_lock(lock);
 
        /*
@@ -2680,11 +2693,10 @@ static int ldlm_revoke_lock_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd,
 
 void ldlm_revoke_export_locks(struct obd_export *exp)
 {
-       struct list_head rpc_list;
+       LIST_HEAD(rpc_list);
 
        ENTRY;
 
-       INIT_LIST_HEAD(&rpc_list);
        cfs_hash_for_each_nolock(exp->exp_lock_hash,
                                 ldlm_revoke_lock_cb, &rpc_list, 0);
        ldlm_run_ast_work(exp->exp_obd->obd_namespace, &rpc_list,
@@ -2805,6 +2817,9 @@ static int ldlm_bl_thread_need_create(struct ldlm_bl_pool *blp,
 static int ldlm_bl_thread_blwi(struct ldlm_bl_pool *blp,
                               struct ldlm_bl_work_item *blwi)
 {
+       /* '1' for consistency with code that checks !mpflag to restore */
+       unsigned int mpflags = 1;
+
        ENTRY;
 
        if (blwi->blwi_ns == NULL)
@@ -2812,7 +2827,7 @@ static int ldlm_bl_thread_blwi(struct ldlm_bl_pool *blp,
                RETURN(LDLM_ITER_STOP);
 
        if (blwi->blwi_mem_pressure)
-               memory_pressure_set();
+               mpflags = memalloc_noreclaim_save();
 
        OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_PAUSE_CANCEL2, 4);
 
@@ -2829,12 +2844,19 @@ static int ldlm_bl_thread_blwi(struct ldlm_bl_pool *blp,
                                                   LCF_BL_AST);
                ldlm_cli_cancel_list(&blwi->blwi_head, count, NULL,
                                     blwi->blwi_flags);
-       } else {
+       } else if (blwi->blwi_lock) {
                ldlm_handle_bl_callback(blwi->blwi_ns, &blwi->blwi_ld,
                                        blwi->blwi_lock);
+       } else {
+               ldlm_pool_recalc(&blwi->blwi_ns->ns_pool, true);
+               spin_lock(&blwi->blwi_ns->ns_lock);
+               blwi->blwi_ns->ns_rpc_recalc = 0;
+               spin_unlock(&blwi->blwi_ns->ns_lock);
+               ldlm_namespace_put(blwi->blwi_ns);
        }
+
        if (blwi->blwi_mem_pressure)
-               memory_pressure_clr();
+               memalloc_noreclaim_restore(mpflags);
 
        if (blwi->blwi_flags & LCF_ASYNC)
                OBD_FREE(blwi, sizeof(*blwi));