diff -uprN ceph-14.2.8/src/common/cohort_lru.h ceph-14.2.8_newfile/src/common/cohort_lru.h
--- ceph-14.2.8/src/common/cohort_lru.h	2020-03-02 17:49:20.000000000 +0000
+++ ceph-14.2.8_newfile/src/common/cohort_lru.h	2022-01-29 08:25:39.565717379 +0000
@@ -42,6 +42,8 @@ namespace cohort {
 
     typedef bi::link_mode<bi::safe_link> link_mode;
 
+    class ObjectFactory; // Forward declaration
+
     class Object
     {
     private:
@@ -70,7 +72,9 @@ namespace cohort {
 
       uint32_t get_refcnt() const { return lru_refcnt; }
 
-      virtual bool reclaim() = 0;
+      virtual bool reclaim(const ObjectFactory* newobj_fac) = 0;
+
+      virtual bool remove() = 0;
 
       virtual ~Object() {}
 
@@ -132,20 +136,20 @@ namespace cohort {
 		(!(o->lru_flags & FLAG_EVICTING)));
       }
 
-      Object* evict_block() {
+      Object* evict_block(const ObjectFactory* newobj_fac) {
 	uint32_t lane_ix = next_evict_lane();
 	for (int ix = 0; ix < n_lanes; ++ix,
 	       lane_ix = next_evict_lane()) {
 	  Lane& lane = qlane[lane_ix];
-	  lane.lock.lock();
+	  std::unique_lock lane_lock{lane.lock};
 	  /* if object at LRU has refcnt==1, it may be reclaimable */
 	  Object* o = &(lane.q.back());
 	  if (can_reclaim(o)) {
 	    ++(o->lru_refcnt);
 	    o->lru_flags |= FLAG_EVICTING;
-	    lane.lock.unlock();
-	    if (o->reclaim()) {
-	      lane.lock.lock();
+	    lane_lock.unlock();
+	    if (o->reclaim(newobj_fac)) {
+	      lane_lock.lock();
 	      --(o->lru_refcnt);
 	      /* assertions that o state has not changed across
 	       * relock */
@@ -154,16 +158,13 @@ namespace cohort {
 	      Object::Queue::iterator it =
 		Object::Queue::s_iterator_to(*o);
 	      lane.q.erase(it);
-	      lane.lock.unlock();
 	      return o;
 	    } else {
-	      // XXX can't make unreachable (means what?)
 	      --(o->lru_refcnt);
 	      o->lru_flags &= ~FLAG_EVICTING;
 	      /* unlock in next block */
 	    }
 	  } /* can_reclaim(o) */
-	  lane.lock.unlock();
 	} /* each lane */
 	return nullptr;
       } /* evict_block */
@@ -208,6 +209,7 @@ namespace cohort {
 	      Object::Queue::s_iterator_to(*o);
 	    lane.q.erase(it);
 	    tdo = o;
+	    tdo->remove();
 	  }
 	  lane.lock.unlock();
 	} else if (unlikely(refcnt == SENTINEL_REFCNT)) {
@@ -222,6 +224,7 @@ namespace cohort {
 	    /* hiwat check */
 	    if (lane.q.size() > lane_hiwat) {
 	      tdo = o;
+	      tdo->remove();
 	    } else {
 	      lane.q.push_back(*o);
 	    }
@@ -236,7 +239,7 @@ namespace cohort {
       Object* insert(ObjectFactory* fac, Edge edge, uint32_t& flags) {
 	/* use supplied functor to re-use an evicted object, or
 	 * allocate a new one of the descendant type */
-	Object* o = evict_block();
+	Object* o = evict_block(fac);
 	if (o) {
 	  fac->recycle(o); /* recycle existing object */
 	  flags |= FLAG_RECYCLE;
@@ -425,6 +428,10 @@ namespace cohort {
 	  lat.lock->unlock();
 	return v;
       } /* find_latch */
+      
+      bool is_same_partition(uint64_t lhs, uint64_t rhs) {
+        return ((lhs % n_part) == (rhs % n_part));
+      }
 
       void insert_latched(T* v, Latch& lat, uint32_t flags) {
 	(void) lat.p->tr.insert_unique_commit(*v, lat.commit_data);
diff -uprN ceph-14.2.8/src/common/legacy_config_opts.h ceph-14.2.8_newfile/src/common/legacy_config_opts.h
--- ceph-14.2.8/src/common/legacy_config_opts.h	2020-03-02 17:49:20.000000000 +0000
+++ ceph-14.2.8_newfile/src/common/legacy_config_opts.h	2022-01-29 08:25:31.177717289 +0000
@@ -1276,6 +1276,7 @@ OPTION(rgw_max_attr_name_len, OPT_SIZE)
 OPTION(rgw_max_attr_size, OPT_SIZE)
 OPTION(rgw_max_attrs_num_in_req, OPT_U64)
 
+OPTION(rgw_obj_prefetch_size, OPT_INT)
 OPTION(rgw_max_chunk_size, OPT_INT)
 OPTION(rgw_put_obj_min_window_size, OPT_INT)
 OPTION(rgw_put_obj_max_window_size, OPT_INT)
diff -uprN ceph-14.2.8/src/common/options.cc ceph-14.2.8_newfile/src/common/options.cc
--- ceph-14.2.8/src/common/options.cc	2020-03-02 17:49:20.000000000 +0000
+++ ceph-14.2.8_newfile/src/common/options.cc	2022-01-29 08:25:31.177717289 +0000
@@ -5616,6 +5616,10 @@ std::vector<Option> get_rgw_options() {
     .set_default(false)
     .set_description("true if LTTng-UST tracepoints should be enabled"),
 
+    Option("rgw_obj_prefetch_size", Option::TYPE_SIZE, Option::LEVEL_ADVANCED)
+    .set_default(4_M)
+    .set_description("Set RGW obj prefetch size"),
+
     Option("rgw_max_chunk_size", Option::TYPE_SIZE, Option::LEVEL_ADVANCED)
     .set_default(4_M)
     .set_description("Set RGW max chunk size")
diff -uprN ceph-14.2.8/src/global/signal_handler.cc ceph-14.2.8_newfile/src/global/signal_handler.cc
--- ceph-14.2.8/src/global/signal_handler.cc	2020-03-02 17:49:20.000000000 +0000
+++ ceph-14.2.8_newfile/src/global/signal_handler.cc	2022-01-29 08:25:31.181717289 +0000
@@ -329,6 +329,7 @@ static void handle_fatal_signal(int sign
 
 void install_standard_sighandlers(void)
 {
+/*
   install_sighandler(SIGSEGV, handle_fatal_signal, SA_RESETHAND | SA_NODEFER);
   install_sighandler(SIGABRT, handle_fatal_signal, SA_RESETHAND | SA_NODEFER);
   install_sighandler(SIGBUS, handle_fatal_signal, SA_RESETHAND | SA_NODEFER);
@@ -336,7 +337,8 @@ void install_standard_sighandlers(void)
   install_sighandler(SIGFPE, handle_fatal_signal, SA_RESETHAND | SA_NODEFER);
   install_sighandler(SIGXCPU, handle_fatal_signal, SA_RESETHAND | SA_NODEFER);
   install_sighandler(SIGXFSZ, handle_fatal_signal, SA_RESETHAND | SA_NODEFER);
-  install_sighandler(SIGSYS, handle_fatal_signal, SA_RESETHAND | SA_NODEFER);
+  install_sighandler(SIGSYS, handle_fatal_signal, SA_RESETHAND | SA_NODEFER); */
+  ;
 }
 
 
diff -uprN ceph-14.2.8/src/rgw/rgw_file.cc ceph-14.2.8_newfile/src/rgw/rgw_file.cc
--- ceph-14.2.8/src/rgw/rgw_file.cc	2020-03-02 17:49:20.000000000 +0000
+++ ceph-14.2.8_newfile/src/rgw/rgw_file.cc	2022-01-29 08:25:39.565717379 +0000
@@ -293,7 +293,7 @@ namespace rgw {
 
     int rc = rgwlib.get_fe()->execute_req(&req);
     if ((rc == 0) &&
-	(req.get_ret() == 0)) {
+	((rc = req.get_ret()) == 0)) {
       lock_guard guard(rgw_fh->mtx);
       rgw_fh->set_atime(real_clock::to_timespec(real_clock::now()));
       *bytes_read = req.nread;
@@ -316,7 +316,7 @@ namespace rgw {
 
     int rc = rgwlib.get_fe()->execute_req(&req);
     if ((rc == 0) &&
-        (req.get_ret() == 0)) {
+        ((rc = req.get_ret()) == 0)) {
       lock_guard(rgw_fh->mtx);
       rgw_fh->set_atime(real_clock::to_timespec(real_clock::now()));
       *bytes_read = req.nread;
@@ -1157,7 +1157,7 @@ namespace rgw {
        * no unsafe iterators reaching it either--n.b., this constraint
        * is binding oncode which may in future attempt to e.g.,
        * cause the eviction of objects in LRU order */
-      (void) get_fs()->unref(parent);
+      (void) get_fs()->unref(parent, RGWFileHandle::FLAG_NONE);
     }
   }
 
@@ -1201,10 +1201,19 @@ namespace rgw {
     return dar;
   } /* RGWFileHandle::decode_attrs */
 
-  bool RGWFileHandle::reclaim() {
+  bool RGWFileHandle::reclaim(const cohort::lru::ObjectFactory* newobj_fac) {
     lsubdout(fs->get_context(), rgw, 17)
       << __func__ << " " << *this
       << dendl;
+    auto factory = dynamic_cast<const RGWFileHandle::Factory*>(newobj_fac);
+    if (factory == nullptr) {
+      return false;
+    }
+    /* make sure the reclaiming object is the same partiton with newobject factory,
+     * then we can recycle the object, and replace with newobject */
+    if (!fs->fh_cache.is_same_partition(factory->fhk.fh_hk.object, fh.fh_hk.object)) {
+      return false;
+    }
     /* in the non-delete case, handle may still be in handle table */
     if (fh_hook.is_linked()) {
       /* in this case, we are being called from a context which holds
@@ -1214,6 +1223,20 @@ namespace rgw {
     return true;
   } /* RGWFileHandle::reclaim */
 
+  bool RGWFileHandle::remove() {
+    lsubdout(fs->get_context(), rgw, 17)
+      << __func__ << " " << *this
+      << dendl;
+    /* in the non-delete case, handle may still be in handle table */
+    if (fh_hook.is_linked()) {
+      /* in this case, we are being called from a context which holds
+       * the partition lock */
+      //this->flags |= RGWFileHandle::FLAG_DELETED;
+      fs->fh_cache.remove(fh.fh_hk.object, this, FHCache::FLAG_NONE);
+    }
+    return true;
+  } /* RGWFileHandle::remove */
+
   bool RGWFileHandle::has_children() const
   {
     if (unlikely(! is_dir()))
diff -uprN ceph-14.2.8/src/rgw/rgw_file.h ceph-14.2.8_newfile/src/rgw/rgw_file.h
--- ceph-14.2.8/src/rgw/rgw_file.h	2020-03-02 17:49:20.000000000 +0000
+++ ceph-14.2.8_newfile/src/rgw/rgw_file.h	2022-01-29 08:25:39.565717379 +0000
@@ -721,7 +721,9 @@ namespace rgw {
 
     void invalidate();
 
-    bool reclaim() override;
+    bool reclaim(const cohort::lru::ObjectFactory* newobj_fac) override;
+
+    bool remove() override;
 
     typedef cohort::lru::LRU<std::mutex> FhLRU;
 
@@ -1159,9 +1161,21 @@ namespace rgw {
       return fhr;
     } /*  lookup_fh(RGWFileHandle*, const char *, const uint32_t) */
 
-    inline void unref(RGWFileHandle* fh) {
+    inline void unref(RGWFileHandle* fh, uint32_t flags = RGWFileHandle::FLAG_LOCK) {
       if (likely(! fh->is_mount())) {
+	RGWFileHandle::FHCache::Latch lat;
+	lat.p = &(fh->fs->fh_cache.partition_of_scalar(fh->fh.fh_hk.object));
+
+	if (flags & RGWFileHandle::FLAG_LOCK) {
+	  lat.lock = &lat.p->lock;
+	  lat.lock->lock();
+	}
+
 	(void) fh_lru.unref(fh, cohort::lru::FLAG_NONE);
+
+	if ( flags & RGWFileHandle::FLAG_LOCK) {
+	  lat.lock->unlock();
+	}
       }
     }
 
diff -uprN ceph-14.2.8/src/rgw/rgw_rados.cc ceph-14.2.8_newfile/src/rgw/rgw_rados.cc
--- ceph-14.2.8/src/rgw/rgw_rados.cc	2020-03-02 17:49:20.000000000 +0000
+++ ceph-14.2.8_newfile/src/rgw/rgw_rados.cc	2022-01-29 08:25:31.185717289 +0000
@@ -7940,7 +7940,7 @@ int RGWRados::raw_obj_stat(rgw_raw_obj&
     op.stat2(&size, &mtime_ts, NULL);
   }
   if (first_chunk) {
-    op.read(0, cct->_conf->rgw_max_chunk_size, first_chunk, NULL);
+    op.read(0, cct->_conf->rgw_obj_prefetch_size, first_chunk, NULL);
   }
   bufferlist outbl;
   r = ref.ioctx.operate(ref.obj.oid, &op, &outbl);

