mapping_gfp_mask(mapping));
 }
 
+/*
+ * Update i_size and estimate the update to i_blocks to reflect the additional
+ * data written into the pagecache until we can find out from the server what
+ * the values actually are.
+ */
+static void netfs_update_i_size(struct netfs_inode *ctx, struct inode *inode,
+                               loff_t i_size, loff_t pos, size_t copied)
+{
+       blkcnt_t add;
+       size_t gap;
+
+       if (ctx->ops->update_i_size) {
+               ctx->ops->update_i_size(inode, pos);
+               return;
+       }
+
+       i_size_write(inode, pos);
+#if IS_ENABLED(CONFIG_FSCACHE)
+       fscache_update_cookie(ctx->cache, NULL, &pos);
+#endif
+
+       gap = SECTOR_SIZE - (i_size & (SECTOR_SIZE - 1));
+       if (copied > gap) {
+               add = DIV_ROUND_UP(copied - gap, SECTOR_SIZE);
+
+               inode->i_blocks = min_t(blkcnt_t,
+                                       DIV_ROUND_UP(pos, SECTOR_SIZE),
+                                       inode->i_blocks + add);
+       }
+}
+
 /**
  * netfs_perform_write - Copy data into the pagecache.
  * @iocb: The operation parameters
                trace_netfs_folio(folio, trace);
 
                /* Update the inode size if we moved the EOF marker */
-               i_size = i_size_read(inode);
                pos += copied;
-               if (pos > i_size) {
-                       if (ctx->ops->update_i_size) {
-                               ctx->ops->update_i_size(inode, pos);
-                       } else {
-                               i_size_write(inode, pos);
-#if IS_ENABLED(CONFIG_FSCACHE)
-                               fscache_update_cookie(ctx->cache, NULL, &pos);
-#endif
-                       }
-               }
+               i_size = i_size_read(inode);
+               if (pos > i_size)
+                       netfs_update_i_size(ctx, inode, i_size, pos, copied);
                written += copied;
 
                if (likely(!wreq)) {