aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2009-11-19 13:11:52 -0500
committerDavid Howells <dhowells@redhat.com>2009-11-19 13:11:52 -0500
commita17754fb8c28af19cd70dcbec6d5b0773b94e0c1 (patch)
treed7c25b217c684153eadbac78ab9b1bbff08b75f6 /include
parent868411be3f445a83fafbd734f3e426400138add5 (diff)
CacheFiles: Don't write a full page if there's only a partial page to cache
cachefiles_write_page() writes a full page to the backing file for the last page of the netfs file, even if the netfs file's last page is only a partial page. This causes the EOF on the backing file to be extended beyond the EOF of the netfs, and thus the backing file will be truncated by cachefiles_attr_changed() called from cachefiles_lookup_object(). So we need to limit the write we make to the backing file on that last page such that it doesn't push the EOF too far. Also, if a backing file that has a partial page at the end is expanded, we discard the partial page and refetch it on the basis that we then have a hole in the file with invalid data, and should the power go out... A better way to deal with this could be to record a note that the partial page contains invalid data until the correct data is written into it. This isn't a problem for netfs's that discard the whole backing file if the file size changes (such as NFS). Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/fscache-cache.h3
1 files changed, 3 insertions, 0 deletions
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index 907bb56c5888..5db50002f3b5 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -395,6 +395,7 @@ struct fscache_object {
395 struct rb_node objlist_link; /* link in global object list */ 395 struct rb_node objlist_link; /* link in global object list */
396#endif 396#endif
397 pgoff_t store_limit; /* current storage limit */ 397 pgoff_t store_limit; /* current storage limit */
398 loff_t store_limit_l; /* current storage limit */
398}; 399};
399 400
400extern const char *fscache_object_states[]; 401extern const char *fscache_object_states[];
@@ -439,6 +440,7 @@ void fscache_object_init(struct fscache_object *object,
439 object->events = object->event_mask = 0; 440 object->events = object->event_mask = 0;
440 object->flags = 0; 441 object->flags = 0;
441 object->store_limit = 0; 442 object->store_limit = 0;
443 object->store_limit_l = 0;
442 object->cache = cache; 444 object->cache = cache;
443 object->cookie = cookie; 445 object->cookie = cookie;
444 object->parent = NULL; 446 object->parent = NULL;
@@ -491,6 +493,7 @@ static inline void fscache_object_lookup_error(struct fscache_object *object)
491static inline 493static inline
492void fscache_set_store_limit(struct fscache_object *object, loff_t i_size) 494void fscache_set_store_limit(struct fscache_object *object, loff_t i_size)
493{ 495{
496 object->store_limit_l = i_size;
494 object->store_limit = i_size >> PAGE_SHIFT; 497 object->store_limit = i_size >> PAGE_SHIFT;
495 if (i_size & ~PAGE_MASK) 498 if (i_size & ~PAGE_MASK)
496 object->store_limit++; 499 object->store_limit++;