diff options
Diffstat (limited to 'fs/jffs2/file.c')
| -rw-r--r-- | fs/jffs2/file.c | 98 | 
1 files changed, 58 insertions, 40 deletions
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c index 1c0a08d711a..64989ca9ba9 100644 --- a/fs/jffs2/file.c +++ b/fs/jffs2/file.c @@ -10,6 +10,8 @@   *   */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/kernel.h>  #include <linux/fs.h>  #include <linux/time.h> @@ -27,13 +29,20 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,  			struct page **pagep, void **fsdata);  static int jffs2_readpage (struct file *filp, struct page *pg); -int jffs2_fsync(struct file *filp, int datasync) +int jffs2_fsync(struct file *filp, loff_t start, loff_t end, int datasync)  {  	struct inode *inode = filp->f_mapping->host;  	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +	int ret; +	ret = filemap_write_and_wait_range(inode->i_mapping, start, end); +	if (ret) +		return ret; + +	mutex_lock(&inode->i_mutex);  	/* Trigger GC to flush any pending writes for this inode */  	jffs2_flush_wbuf_gc(c, inode->i_ino); +	mutex_unlock(&inode->i_mutex);  	return 0;  } @@ -42,10 +51,10 @@ const struct file_operations jffs2_file_operations =  {  	.llseek =	generic_file_llseek,  	.open =		generic_file_open, - 	.read =		do_sync_read, - 	.aio_read =	generic_file_aio_read, - 	.write =	do_sync_write, - 	.aio_write =	generic_file_aio_write, + 	.read =		new_sync_read, + 	.read_iter =	generic_file_read_iter, + 	.write =	new_sync_write, + 	.write_iter =	generic_file_write_iter,  	.unlocked_ioctl=jffs2_ioctl,  	.mmap =		generic_file_readonly_mmap,  	.fsync =	jffs2_fsync, @@ -56,7 +65,8 @@ const struct file_operations jffs2_file_operations =  const struct inode_operations jffs2_file_inode_operations =  { -	.check_acl =	jffs2_check_acl, +	.get_acl =	jffs2_get_acl, +	.set_acl =	jffs2_set_acl,  	.setattr =	jffs2_setattr,  	.setxattr =	jffs2_setxattr,  	.getxattr =	jffs2_getxattr, @@ -78,7 +88,8 @@ static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)  	unsigned char *pg_buf;  	int ret; -	D2(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT)); +	jffs2_dbg(2, "%s(): ino #%lu, page at offset 0x%lx\n", +		  __func__, inode->i_ino, pg->index << PAGE_CACHE_SHIFT);  	BUG_ON(!PageLocked(pg)); @@ -98,7 +109,7 @@ static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)  	flush_dcache_page(pg);  	kunmap(pg); -	D2(printk(KERN_DEBUG "readpage finished\n")); +	jffs2_dbg(2, "readpage finished\n");  	return ret;  } @@ -128,33 +139,39 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,  	struct page *pg;  	struct inode *inode = mapping->host;  	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); +	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); +	struct jffs2_raw_inode ri; +	uint32_t alloc_len = 0;  	pgoff_t index = pos >> PAGE_CACHE_SHIFT;  	uint32_t pageofs = index << PAGE_CACHE_SHIFT;  	int ret = 0; +	jffs2_dbg(1, "%s()\n", __func__); + +	if (pageofs > inode->i_size) { +		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, +					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); +		if (ret) +			return ret; +	} + +	mutex_lock(&f->sem);  	pg = grab_cache_page_write_begin(mapping, index, flags); -	if (!pg) +	if (!pg) { +		if (alloc_len) +			jffs2_complete_reservation(c); +		mutex_unlock(&f->sem);  		return -ENOMEM; +	}  	*pagep = pg; -	D1(printk(KERN_DEBUG "jffs2_write_begin()\n")); - -	if (pageofs > inode->i_size) { +	if (alloc_len) {  		/* Make new hole frag from old EOF to new page */ -		struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); -		struct jffs2_raw_inode ri;  		struct jffs2_full_dnode *fn; -		uint32_t alloc_len; -		D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", -			  (unsigned int)inode->i_size, pageofs)); +		jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", +			  (unsigned int)inode->i_size, pageofs); -		ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, -					  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); -		if (ret) -			goto out_page; - -		mutex_lock(&f->sem);  		memset(&ri, 0, sizeof(ri));  		ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); @@ -165,8 +182,8 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,  		ri.ino = cpu_to_je32(f->inocache->ino);  		ri.version = cpu_to_je32(++f->highest_version);  		ri.mode = cpu_to_jemode(inode->i_mode); -		ri.uid = cpu_to_je16(inode->i_uid); -		ri.gid = cpu_to_je16(inode->i_gid); +		ri.uid = cpu_to_je16(i_uid_read(inode)); +		ri.gid = cpu_to_je16(i_gid_read(inode));  		ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));  		ri.atime = ri.ctime = ri.mtime = cpu_to_je32(get_seconds());  		ri.offset = cpu_to_je32(inode->i_size); @@ -181,7 +198,6 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,  		if (IS_ERR(fn)) {  			ret = PTR_ERR(fn);  			jffs2_complete_reservation(c); -			mutex_unlock(&f->sem);  			goto out_page;  		}  		ret = jffs2_add_full_dnode_to_inode(c, f, fn); @@ -191,16 +207,15 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,  			f->metadata = NULL;  		}  		if (ret) { -			D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in write_begin, returned %d\n", ret)); +			jffs2_dbg(1, "Eep. add_full_dnode_to_inode() failed in write_begin, returned %d\n", +				  ret);  			jffs2_mark_node_obsolete(c, fn->raw);  			jffs2_free_full_dnode(fn);  			jffs2_complete_reservation(c); -			mutex_unlock(&f->sem);  			goto out_page;  		}  		jffs2_complete_reservation(c);  		inode->i_size = pageofs; -		mutex_unlock(&f->sem);  	}  	/* @@ -209,18 +224,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,  	 * case of a short-copy.  	 */  	if (!PageUptodate(pg)) { -		mutex_lock(&f->sem);  		ret = jffs2_do_readpage_nolock(inode, pg); -		mutex_unlock(&f->sem);  		if (ret)  			goto out_page;  	} -	D1(printk(KERN_DEBUG "end write_begin(). pg->flags %lx\n", pg->flags)); +	mutex_unlock(&f->sem); +	jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);  	return ret;  out_page:  	unlock_page(pg);  	page_cache_release(pg); +	mutex_unlock(&f->sem);  	return ret;  } @@ -241,8 +256,9 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,  	int ret = 0;  	uint32_t writtenlen = 0; -	D1(printk(KERN_DEBUG "jffs2_write_end(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", -		  inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags)); +	jffs2_dbg(1, "%s(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", +		  __func__, inode->i_ino, pg->index << PAGE_CACHE_SHIFT, +		  start, end, pg->flags);  	/* We need to avoid deadlock with page_cache_read() in  	   jffs2_garbage_collect_pass(). So the page must be @@ -261,7 +277,8 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,  	ri = jffs2_alloc_raw_inode();  	if (!ri) { -		D1(printk(KERN_DEBUG "jffs2_write_end(): Allocation of raw inode failed\n")); +		jffs2_dbg(1, "%s(): Allocation of raw inode failed\n", +			  __func__);  		unlock_page(pg);  		page_cache_release(pg);  		return -ENOMEM; @@ -270,8 +287,8 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,  	/* Set the fields that the generic jffs2_write_inode_range() code can't find */  	ri->ino = cpu_to_je32(inode->i_ino);  	ri->mode = cpu_to_jemode(inode->i_mode); -	ri->uid = cpu_to_je16(inode->i_uid); -	ri->gid = cpu_to_je16(inode->i_gid); +	ri->uid = cpu_to_je16(i_uid_read(inode)); +	ri->gid = cpu_to_je16(i_gid_read(inode));  	ri->isize = cpu_to_je32((uint32_t)inode->i_size);  	ri->atime = ri->ctime = ri->mtime = cpu_to_je32(get_seconds()); @@ -308,13 +325,14 @@ static int jffs2_write_end(struct file *filp, struct address_space *mapping,  		/* generic_file_write has written more to the page cache than we've  		   actually written to the medium. Mark the page !Uptodate so that  		   it gets reread */ -		D1(printk(KERN_DEBUG "jffs2_write_end(): Not all bytes written. Marking page !uptodate\n")); +		jffs2_dbg(1, "%s(): Not all bytes written. Marking page !uptodate\n", +			__func__);  		SetPageError(pg);  		ClearPageUptodate(pg);  	} -	D1(printk(KERN_DEBUG "jffs2_write_end() returning %d\n", -					writtenlen > 0 ? writtenlen : ret)); +	jffs2_dbg(1, "%s() returning %d\n", +		  __func__, writtenlen > 0 ? writtenlen : ret);  	unlock_page(pg);  	page_cache_release(pg);  	return writtenlen > 0 ? writtenlen : ret;  | 
