aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cachefiles/interface.c20
-rw-r--r--fs/cachefiles/rdwr.c23
-rw-r--r--include/linux/fscache-cache.h3
3 files changed, 39 insertions, 7 deletions
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index dd7f852746cb..8e67abf05985 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -404,12 +404,26 @@ static int cachefiles_attr_changed(struct fscache_object *_object)
404 if (oi_size == ni_size) 404 if (oi_size == ni_size)
405 return 0; 405 return 0;
406 406
407 newattrs.ia_size = ni_size;
408 newattrs.ia_valid = ATTR_SIZE;
409
410 cachefiles_begin_secure(cache, &saved_cred); 407 cachefiles_begin_secure(cache, &saved_cred);
411 mutex_lock(&object->backer->d_inode->i_mutex); 408 mutex_lock(&object->backer->d_inode->i_mutex);
409
410 /* if there's an extension to a partial page at the end of the backing
411 * file, we need to discard the partial page so that we pick up new
412 * data after it */
413 if (oi_size & ~PAGE_MASK && ni_size > oi_size) {
414 _debug("discard tail %llx", oi_size);
415 newattrs.ia_valid = ATTR_SIZE;
416 newattrs.ia_size = oi_size & PAGE_MASK;
417 ret = notify_change(object->backer, &newattrs);
418 if (ret < 0)
419 goto truncate_failed;
420 }
421
422 newattrs.ia_valid = ATTR_SIZE;
423 newattrs.ia_size = ni_size;
412 ret = notify_change(object->backer, &newattrs); 424 ret = notify_change(object->backer, &newattrs);
425
426truncate_failed:
413 mutex_unlock(&object->backer->d_inode->i_mutex); 427 mutex_unlock(&object->backer->d_inode->i_mutex);
414 cachefiles_end_secure(cache, saved_cred); 428 cachefiles_end_secure(cache, saved_cred);
415 429
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
index 3304646dae84..5a84fd7109ad 100644
--- a/fs/cachefiles/rdwr.c
+++ b/fs/cachefiles/rdwr.c
@@ -803,7 +803,8 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
803 struct cachefiles_cache *cache; 803 struct cachefiles_cache *cache;
804 mm_segment_t old_fs; 804 mm_segment_t old_fs;
805 struct file *file; 805 struct file *file;
806 loff_t pos; 806 loff_t pos, eof;
807 size_t len;
807 void *data; 808 void *data;
808 int ret; 809 int ret;
809 810
@@ -837,15 +838,29 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
837 ret = -EIO; 838 ret = -EIO;
838 if (file->f_op->write) { 839 if (file->f_op->write) {
839 pos = (loff_t) page->index << PAGE_SHIFT; 840 pos = (loff_t) page->index << PAGE_SHIFT;
841
842 /* we mustn't write more data than we have, so we have
843 * to beware of a partial page at EOF */
844 eof = object->fscache.store_limit_l;
845 len = PAGE_SIZE;
846 if (eof & ~PAGE_MASK) {
847 ASSERTCMP(pos, <, eof);
848 if (eof - pos < PAGE_SIZE) {
849 _debug("cut short %llx to %llx",
850 pos, eof);
851 len = eof - pos;
852 ASSERTCMP(pos + len, ==, eof);
853 }
854 }
855
840 data = kmap(page); 856 data = kmap(page);
841 old_fs = get_fs(); 857 old_fs = get_fs();
842 set_fs(KERNEL_DS); 858 set_fs(KERNEL_DS);
843 ret = file->f_op->write( 859 ret = file->f_op->write(
844 file, (const void __user *) data, PAGE_SIZE, 860 file, (const void __user *) data, len, &pos);
845 &pos);
846 set_fs(old_fs); 861 set_fs(old_fs);
847 kunmap(page); 862 kunmap(page);
848 if (ret != PAGE_SIZE) 863 if (ret != len)
849 ret = -EIO; 864 ret = -EIO;
850 } 865 }
851 fput(file); 866 fput(file);
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++;