Whamcloud - gitweb
b=21571 stacksize and locking fixes for loadgen patch from umka
[fs/lustre-release.git] / lustre / obdfilter / filter_io.c
index 5ed6c98..368842e 100644 (file)
@@ -198,9 +198,13 @@ restat:
 /* Calculate how much grant space to allocate to this client, based on how
  * much space is currently free and how much of that is already granted.
  *
+ * if @conservative != 0, we limit the maximum grant to FILTER_GRANT_CHUNK;
+ * otherwise we'll satisfy the requested amount as possible as we can, this
+ * is usually due to client reconnect.
+ *
  * Caller must hold obd_osfs_lock. */
 long filter_grant(struct obd_export *exp, obd_size current_grant,
-                  obd_size want, obd_size fs_space_left)
+                  obd_size want, obd_size fs_space_left, int conservative)
 {
         struct obd_device *obd = exp->exp_obd;
         struct filter_export_data *fed = &exp->exp_filter_data;
@@ -223,16 +227,11 @@ long filter_grant(struct obd_export *exp, obd_size current_grant,
                        obd->obd_name, exp->exp_client_uuid.uuid, exp, want);
         } else if (current_grant < want &&
                    current_grant < fed->fed_grant + FILTER_GRANT_CHUNK) {
-                grant = min((want >> blockbits),
-                            (fs_space_left >> blockbits) / 8);
-                grant <<= blockbits;
+                grant = min(want + (1 << blockbits) - 1, fs_space_left / 8);
+                grant &= ~((1ULL << blockbits) - 1);
 
                 if (grant) {
-                        /* Allow >FILTER_GRANT_CHUNK size when clients
-                         * reconnect due to a server reboot.
-                         */
-                        if ((grant > FILTER_GRANT_CHUNK) &&
-                            (!obd->obd_recovering))
+                        if (grant > FILTER_GRANT_CHUNK && conservative)
                                 grant = FILTER_GRANT_CHUNK;
 
                         obd->u.filter.fo_tot_granted += grant;
@@ -283,7 +282,7 @@ static struct page *filter_get_page(struct obd_device *obd,
 
         page = find_or_create_page(inode->i_mapping, offset >> CFS_PAGE_SHIFT,
                                    (localreq ? (GFP_NOFS | __GFP_HIGHMEM)
-                                             : (GFP_HIGHUSER | __GFP_NOMEMALLOC)));
+                                             : GFP_HIGHUSER));
         if (unlikely(page == NULL))
                 lprocfs_counter_add(obd->obd_stats, LPROC_FILTER_NO_PAGE, 1);
 
@@ -341,56 +340,30 @@ static int filter_map_remote_to_local(int objcount, struct obd_ioobj *obj,
 }
 
 /*
- * the function is used to free all pages used for request
- * just to mimic cacheless OSS which don't occupy much memory
- */
-void filter_invalidate_cache(struct obd_device *obd, struct obd_ioobj *obj,
-                             struct niobuf_remote *nb, struct inode *inode)
-{
-        struct niobuf_remote *rnb;
-        int i;
-
-        LASSERT(inode != NULL);
-
-        for (i = 0, rnb = nb; i < obj->ioo_bufcnt; i++, rnb++) {
-                obd_off start;
-                obd_off end;
-
-                start = rnb->offset >> CFS_PAGE_SHIFT;
-                end = (rnb->offset + rnb->len) >> CFS_PAGE_SHIFT;
-                invalidate_mapping_pages(inode->i_mapping, start, end);
-                /* just to avoid warnings */
-                start = 0;
-                end = 0;
-        }
-}
-
-/*
  * the invalidate above doesn't work during read because lnet pins pages.
  * The truncate is used here instead to drop pages from cache
  */
-void filter_truncate_cache(struct obd_device *obd, struct obd_ioobj *obj,
-                           struct niobuf_remote *nb, int pages,
-                           struct niobuf_local *res, struct inode *inode)
+void filter_release_cache(struct obd_device *obd, struct obd_ioobj *obj,
+                          struct niobuf_remote *rnb, struct inode *inode)
 {
-        struct niobuf_remote *rnb;
         int i;
 
         LASSERT(inode != NULL);
+        for (i = 0; i < obj->ioo_bufcnt; i++, rnb++) {
 #ifdef HAVE_TRUNCATE_RANGE
-        for (i = 0, rnb = nb; i < obj->ioo_bufcnt; i++, rnb++) {
                 /* remove pages in which range is fit */
                 truncate_inode_pages_range(inode->i_mapping,
                                            rnb->offset & CFS_PAGE_MASK,
                                            (rnb->offset + rnb->len - 1) |
                                            ~CFS_PAGE_MASK);
-        }
-#elif (defined HAVE_TRUNCATE_COMPLETE)
-        for (i = 0, lnb = res; i < pages; i++, lnb++)
-                truncate_complete_page(inode->i_mapping, lnb->page);
 #else
-#error "Nor truncate_inode_pages_range or truncate_complete_page are supported"
+                /* use invalidate for old kernels */
+                invalidate_mapping_pages(inode->i_mapping,
+                                         rnb->offset >> CFS_PAGE_SHIFT,
+                                         (rnb->offset + rnb->len) >>
+                                         CFS_PAGE_SHIFT);
 #endif
+        }
 }
 
 static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
@@ -757,7 +730,8 @@ static int filter_preprw_write(int cmd, struct obd_export *exp, struct obdo *oa,
         /* do not zero out oa->o_valid as it is used in filter_commitrw_write()
          * for setting UID/GID and fid EA in first write time. */
         if (oa->o_valid & OBD_MD_FLGRANT)
-                oa->o_grant = filter_grant(exp,oa->o_grant,oa->o_undirty,left);
+                oa->o_grant = filter_grant(exp, oa->o_grant, oa->o_undirty,
+                                           left, 1);
 
         spin_unlock(&obd->obd_osfs_lock);
         filter_fmd_put(exp, fmd);
@@ -924,7 +898,7 @@ static int filter_commitrw_read(struct obd_export *exp, struct obdo *oa,
 
                 if (resource != NULL) {
                         LDLM_RESOURCE_ADDREF(resource);
-                        ns->ns_lvbo->lvbo_update(resource, NULL, 0, 1);
+                        ns->ns_lvbo->lvbo_update(resource, NULL, 1);
                         LDLM_RESOURCE_DELREF(resource);
                         ldlm_resource_putref(resource);
                 }
@@ -933,17 +907,15 @@ static int filter_commitrw_read(struct obd_export *exp, struct obdo *oa,
         if (res->dentry != NULL)
                 inode = res->dentry->d_inode;
 
-        for (i = 0, lnb = res; i < npages; i++, lnb++)
-                if (lnb->page != NULL)
+        for (i = 0, lnb = res; i < npages; i++, lnb++) {
+                if (lnb->page != NULL) {
                         page_cache_release(lnb->page);
-
+                        lnb->page = NULL;
+                }
+        }
         if (inode && (fo->fo_read_cache == 0 ||
                       i_size_read(inode) > fo->fo_readcache_max_filesize))
-                filter_truncate_cache(exp->exp_obd, obj, rnb, npages, res,
-                                      inode);
-
-        for (i = 0, lnb = res; i < npages; i++, lnb++)
-                lnb->page = NULL;
+                filter_release_cache(exp->exp_obd, obj, rnb, inode);
 
         if (res->dentry != NULL)
                 f_dput(res->dentry);