diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index 38ef6a552c344c659e158ccbde77cfddeaa7774f..2e86b3b275f716c5ed57a84b14434461852aca1d 100644
--- a/lustre/ChangeLog
+++ b/lustre/ChangeLog
@@ -1540,11 +1540,6 @@ Bugzilla   : 16450
 Description: Kill unused ldlm_handle2lock_ns() function.
 Details    : Kill unused ldlm_handle2lock_ns() function.
 
-Severity   : minor
-Bugzilla   : 16450
-Description: Kill unused ldlm_handle2lock_ns() function.
-Details    : Kill unused ldlm_handle2lock_ns() function.
-
 Severity   : normal
 Bugzilla   : 16450
 Description: Add lu_ref support to ldlm_lock
@@ -1573,6 +1568,13 @@ Details    : Introduce ldlm_lock_addref_try() function (used by CLIO) that
 	     attempts to addref a lock that might be being canceled
 	     concurrently.
 
+Severity   : normal
+Bugzilla   : 16450
+Description: Add ldlm_weigh_callback().
+Details    : Add new ->l_weigh_ast() call-back to ldlm_lock. It is called 
+        by ldlm_cancel_shrink_policy() to estimate lock "value", instead of
+        hard-coded `number of pages' logic.
+
 --------------------------------------------------------------------------------
 
 2007-08-10         Cluster File Systems, Inc. <info@clusterfs.com>
diff --git a/lustre/include/lustre_dlm.h b/lustre/include/lustre_dlm.h
index be73ac012c5089393a472750f756f0705db6ab63..368ee2105f23f71eba8bf6654cd2cd22078e9837 100644
--- a/lustre/include/lustre_dlm.h
+++ b/lustre/include/lustre_dlm.h
@@ -440,7 +440,7 @@ struct ldlm_namespace {
         /**
          * Lower limit to number of pages in lock to keep it in cache.
          */
-        unsigned int           ns_shrink_thumb;
+        unsigned long          ns_shrink_thumb;
 
         /**
          * Next debug dump, jiffies.
@@ -525,6 +525,7 @@ typedef int (*ldlm_blocking_callback)(struct ldlm_lock *lock,
 typedef int (*ldlm_completion_callback)(struct ldlm_lock *lock, int flags,
                                         void *data);
 typedef int (*ldlm_glimpse_callback)(struct ldlm_lock *lock, void *data);
+typedef unsigned long (*ldlm_weigh_callback)(struct ldlm_lock *lock);
 
 /* Interval node data for each LDLM_EXTENT lock */
 struct ldlm_interval {
@@ -598,6 +599,7 @@ struct ldlm_lock {
          * Lock glimpse handler.
          */
         ldlm_glimpse_callback    l_glimpse_ast;
+        ldlm_weigh_callback      l_weigh_ast;
 
         /**
          * Lock export.
@@ -755,6 +757,7 @@ struct ldlm_enqueue_info {
         void *ei_cb_bl;  /* blocking lock callback */
         void *ei_cb_cp;  /* lock completion callback */
         void *ei_cb_gl;  /* lock glimpse callback */
+        void *ei_cb_wg;  /* lock weigh callback */
         void *ei_cbdata; /* Data to be passed into callbacks. */
         short ei_async:1; /* async request */
 };
diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c
index 0d15a158f377eaeec726cf69462ff572e5e41c73..045b77982fd630ef2a2378562d17d325527e60cb 100644
--- a/lustre/ldlm/ldlm_request.c
+++ b/lustre/ldlm/ldlm_request.c
@@ -1290,6 +1290,13 @@ static ldlm_policy_res_t ldlm_cancel_shrink_policy(struct ldlm_namespace *ns,
                 return LDLM_POLICY_KEEP_LOCK;
 
         if (lock->l_resource->lr_type == LDLM_EXTENT) {
+                if (lock->l_weigh_ast) {
+                        /*
+                         * For liblustre, l_weigh_ast should return 0 since it
+                         * don't cache pages
+                         */
+                        page_nr = lock->l_weigh_ast(lock);
+                } else {
                 struct ldlm_extent *l_extent;
 
                 /* 
@@ -1297,22 +1304,9 @@ static ldlm_policy_res_t ldlm_cancel_shrink_policy(struct ldlm_namespace *ns,
                  * their extent. 
                  */
                 l_extent = &lock->l_policy_data.l_extent;
-                page_nr = (l_extent->end - l_extent->start);
+                        page_nr = l_extent->end - l_extent->start;
                 do_div(page_nr, CFS_PAGE_SIZE);
-
-#ifdef __KERNEL__
-                /* 
-                 * XXX: In fact this is evil hack, we can't access inode
-                 * here. For doing it right we need somehow to have number
-                 * of covered by lock. This should be fixed later when 10718 
-                 * is landed. 
-                 */
-                if (lock->l_ast_data != NULL) {
-                        struct inode *inode = lock->l_ast_data;
-                        if (page_nr > inode->i_mapping->nrpages)
-                                page_nr = inode->i_mapping->nrpages;
                 }
-#endif
                 lock_cost = 1 + page_nr;
         } else {
                 /* 
diff --git a/lustre/liblustre/dir.c b/lustre/liblustre/dir.c
index b45bc8925ad04e1fc68082fc2b7489938cef27e4..57960a2319e83bbb50a4d1005ef3ddb7eac84427 100644
--- a/lustre/liblustre/dir.c
+++ b/lustre/liblustre/dir.c
@@ -94,7 +94,8 @@ static int llu_dir_do_readpage(struct inode *inode, struct page *page)
                            &lli->lli_fid, LDLM_IBITS, &policy, LCK_CR, &lockh);
         if (!rc) {
                 struct ldlm_enqueue_info einfo = {LDLM_IBITS, LCK_CR,
-                        llu_md_blocking_ast, ldlm_completion_ast, NULL, inode};
+                        llu_md_blocking_ast, ldlm_completion_ast, NULL, NULL,
+                        inode};
 
                 llu_prep_md_op_data(&op_data, inode, NULL, NULL, 0, 0,
                                     LUSTRE_OPC_ANY);
diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c
index f5b1b4ef702f0c87adc9657c4a02cde899f759ac..ccc19b2f9486141daed20273b01d28a27d3ddcde 100644
--- a/lustre/liblustre/super.c
+++ b/lustre/liblustre/super.c
@@ -1393,7 +1393,7 @@ static int llu_file_flock(struct inode *ino,
                            fid_ver(&lli->lli_fid),
                            LDLM_FLOCK} };
         struct ldlm_enqueue_info einfo = { LDLM_FLOCK, 0, NULL,
-                ldlm_flock_completion_ast, NULL, file_lock };
+                ldlm_flock_completion_ast, NULL, NULL, file_lock };
 
         struct lustre_handle lockh = {0};
         ldlm_policy_data_t flock;
@@ -1773,7 +1773,7 @@ static int llu_lov_setstripe_ea_info(struct inode *ino, int flags,
         struct lov_stripe_md *lsm;
         struct lookup_intent oit = {.it_op = IT_OPEN, .it_flags = flags};
         struct ldlm_enqueue_info einfo = { LDLM_IBITS, LCK_CR,
-                llu_md_blocking_ast, ldlm_completion_ast, NULL, NULL };
+                llu_md_blocking_ast, ldlm_completion_ast, NULL, NULL, NULL };
 
         struct ptlrpc_request *req = NULL;
         struct lustre_md md;
diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c
index 930bd26b2419f0d67de8c9e144e8d34d1225cab4..b38e42906f95d5532d86e105b0b3f098695c445c 100644
--- a/lustre/llite/dir.c
+++ b/lustre/llite/dir.c
@@ -281,7 +281,8 @@ struct page *ll_get_dir_page(struct inode *dir, __u64 hash, int exact,
                            ll_inode2fid(dir), LDLM_IBITS, &policy, mode, &lockh);
         if (!rc) {
                 struct ldlm_enqueue_info einfo = { LDLM_IBITS, mode,
-                       ll_md_blocking_ast, ldlm_completion_ast, NULL, dir };
+                       ll_md_blocking_ast, ldlm_completion_ast,
+                       NULL, NULL, dir };
                 struct lookup_intent it = { .it_op = IT_READDIR };
                 struct ptlrpc_request *request;
                 struct md_op_data *op_data;
diff --git a/lustre/llite/file.c b/lustre/llite/file.c
index 75bf05990ce08adbc186cc813f62940b9ce732bd..63f790aaf672b072b2a3431b34ac212b555c28d1 100644
--- a/lustre/llite/file.c
+++ b/lustre/llite/file.c
@@ -2343,7 +2343,7 @@ static int join_file(struct inode *head_inode, struct file *head_filp,
         struct lookup_intent oit = {.it_op = IT_OPEN,
                                    .it_flags = head_filp->f_flags|O_JOIN_FILE};
         struct ldlm_enqueue_info einfo = { LDLM_IBITS, LCK_CW,
-                ll_md_blocking_ast, ldlm_completion_ast, NULL, NULL };
+                ll_md_blocking_ast, ldlm_completion_ast, NULL, NULL, NULL };
 
         struct lustre_handle lockh;
         struct md_op_data *op_data;
diff --git a/lustre/mdc/mdc_locks.c b/lustre/mdc/mdc_locks.c
index 1c47ca0c88a925d9114f37796aa14ed75b6fbc86..a21992c5dfe50535f072842f8dfc16a4b1b7730e 100644
--- a/lustre/mdc/mdc_locks.c
+++ b/lustre/mdc/mdc_locks.c
@@ -914,7 +914,7 @@ int mdc_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
         if (!it_disposition(it, DISP_ENQ_COMPLETE)) {
                 struct ldlm_enqueue_info einfo =
                         { LDLM_IBITS, it_to_lock_mode(it), cb_blocking,
-                          ldlm_completion_ast, NULL, NULL };
+                          ldlm_completion_ast, NULL, NULL, NULL };
 
                 /* For case if upper layer did not alloc fid, do it now. */
                 if (!fid_is_sane(&op_data->op_fid2) && it->it_op & IT_CREAT) {
diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c
index fefcf74b6e1e43f18ec748c12b652246dde91f99..222c9ba3e854bb6a6a454b8b1a31ceba26dd1a86 100644
--- a/lustre/mdt/mdt_reint.c
+++ b/lustre/mdt/mdt_reint.c
@@ -754,7 +754,7 @@ static int mdt_rename_lock(struct mdt_thread_info *info,
                                             NULL, lh);
         } else {
                 struct ldlm_enqueue_info einfo = { LDLM_IBITS, LCK_EX,
-                        ldlm_blocking_ast, ldlm_completion_ast, NULL, NULL };
+                     ldlm_blocking_ast, ldlm_completion_ast, NULL, NULL, NULL };
                 int flags = 0;
 
                 /*
diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c
index 9985007b47d14733f0fd6b57d658a20328835c52..a78460c3fa21077ed7bcf0b1396d10c112039198 100644
--- a/lustre/mgc/mgc_request.c
+++ b/lustre/mgc/mgc_request.c
@@ -661,7 +661,7 @@ static int mgc_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm,
 {
         struct config_llog_data *cld = (struct config_llog_data *)data;
         struct ldlm_enqueue_info einfo = { type, mode, mgc_blocking_ast,
-                ldlm_completion_ast, NULL, data};
+                         ldlm_completion_ast, NULL, NULL, data};
 
         int rc;
         ENTRY;