diff options
Diffstat (limited to 'fs/bfs')
| -rw-r--r-- | fs/bfs/Kconfig | 4 | ||||
| -rw-r--r-- | fs/bfs/dir.c | 47 | ||||
| -rw-r--r-- | fs/bfs/file.c | 24 | ||||
| -rw-r--r-- | fs/bfs/inode.c | 35 | 
4 files changed, 59 insertions, 51 deletions
diff --git a/fs/bfs/Kconfig b/fs/bfs/Kconfig index c2336c62024..3728a6479c6 100644 --- a/fs/bfs/Kconfig +++ b/fs/bfs/Kconfig @@ -1,6 +1,6 @@  config BFS_FS -	tristate "BFS file system support (EXPERIMENTAL)" -	depends on BLOCK && EXPERIMENTAL +	tristate "BFS file system support" +	depends on BLOCK  	help  	  Boot File System (BFS) is a file system used under SCO UnixWare to  	  allow the bootloader access to the kernel image and other important diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 685ecff3ab3..a399e6d9dc7 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c @@ -26,66 +26,59 @@ static struct buffer_head *bfs_find_entry(struct inode *dir,  				const unsigned char *name, int namelen,  				struct bfs_dirent **res_dir); -static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir) +static int bfs_readdir(struct file *f, struct dir_context *ctx)  { -	struct inode *dir = f->f_path.dentry->d_inode; +	struct inode *dir = file_inode(f);  	struct buffer_head *bh;  	struct bfs_dirent *de; -	struct bfs_sb_info *info = BFS_SB(dir->i_sb);  	unsigned int offset;  	int block; -	mutex_lock(&info->bfs_lock); - -	if (f->f_pos & (BFS_DIRENT_SIZE - 1)) { +	if (ctx->pos & (BFS_DIRENT_SIZE - 1)) {  		printf("Bad f_pos=%08lx for %s:%08lx\n", -					(unsigned long)f->f_pos, +					(unsigned long)ctx->pos,  					dir->i_sb->s_id, dir->i_ino); -		mutex_unlock(&info->bfs_lock); -		return -EBADF; +		return -EINVAL;  	} -	while (f->f_pos < dir->i_size) { -		offset = f->f_pos & (BFS_BSIZE - 1); -		block = BFS_I(dir)->i_sblock + (f->f_pos >> BFS_BSIZE_BITS); +	while (ctx->pos < dir->i_size) { +		offset = ctx->pos & (BFS_BSIZE - 1); +		block = BFS_I(dir)->i_sblock + (ctx->pos >> BFS_BSIZE_BITS);  		bh = sb_bread(dir->i_sb, block);  		if (!bh) { -			f->f_pos += BFS_BSIZE - offset; +			ctx->pos += BFS_BSIZE - offset;  			continue;  		}  		do {  			de = (struct bfs_dirent *)(bh->b_data + offset);  			if (de->ino) {  				int size = strnlen(de->name, BFS_NAMELEN); -				if (filldir(dirent, de->name, size, f->f_pos, +				if (!dir_emit(ctx, de->name, size,  						le16_to_cpu(de->ino), -						DT_UNKNOWN) < 0) { +						DT_UNKNOWN)) {  					brelse(bh); -					mutex_unlock(&info->bfs_lock);  					return 0;  				}  			}  			offset += BFS_DIRENT_SIZE; -			f->f_pos += BFS_DIRENT_SIZE; -		} while ((offset < BFS_BSIZE) && (f->f_pos < dir->i_size)); +			ctx->pos += BFS_DIRENT_SIZE; +		} while ((offset < BFS_BSIZE) && (ctx->pos < dir->i_size));  		brelse(bh);  	} - -	mutex_unlock(&info->bfs_lock); -	return 0;	 +	return 0;  }  const struct file_operations bfs_dir_operations = {  	.read		= generic_read_dir, -	.readdir	= bfs_readdir, +	.iterate	= bfs_readdir,  	.fsync		= generic_file_fsync,  	.llseek		= generic_file_llseek,  };  extern void dump_imap(const char *, struct super_block *); -static int bfs_create(struct inode *dir, struct dentry *dentry, int mode, -						struct nameidata *nd) +static int bfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, +						bool excl)  {  	int err;  	struct inode *inode; @@ -97,7 +90,7 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode,  	if (!inode)  		return -ENOSPC;  	mutex_lock(&info->bfs_lock); -	ino = find_first_zero_bit(info->si_imap, info->si_lasti); +	ino = find_first_zero_bit(info->si_imap, info->si_lasti + 1);  	if (ino > info->si_lasti) {  		mutex_unlock(&info->bfs_lock);  		iput(inode); @@ -133,7 +126,7 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode,  }  static struct dentry *bfs_lookup(struct inode *dir, struct dentry *dentry, -						struct nameidata *nd) +						unsigned int flags)  {  	struct inode *inode = NULL;  	struct buffer_head *bh; @@ -199,7 +192,7 @@ static int bfs_unlink(struct inode *dir, struct dentry *dentry)  		printf("unlinking non-existent file %s:%lu (nlink=%d)\n",  					inode->i_sb->s_id, inode->i_ino,  					inode->i_nlink); -		inode->i_nlink = 1; +		set_nlink(inode, 1);  	}  	de->ino = 0;  	mark_buffer_dirty_inode(bh, dir); diff --git a/fs/bfs/file.c b/fs/bfs/file.c index eb67edd0f8e..e7f88ace1a2 100644 --- a/fs/bfs/file.c +++ b/fs/bfs/file.c @@ -23,10 +23,10 @@  const struct file_operations bfs_file_operations = {  	.llseek 	= generic_file_llseek, -	.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,  	.mmap		= generic_file_mmap,  	.splice_read	= generic_file_splice_read,  }; @@ -161,6 +161,14 @@ static int bfs_readpage(struct file *file, struct page *page)  	return block_read_full_page(page, bfs_get_block);  } +static void bfs_write_failed(struct address_space *mapping, loff_t to) +{ +	struct inode *inode = mapping->host; + +	if (to > inode->i_size) +		truncate_pagecache(inode, inode->i_size); +} +  static int bfs_write_begin(struct file *file, struct address_space *mapping,  			loff_t pos, unsigned len, unsigned flags,  			struct page **pagep, void **fsdata) @@ -169,11 +177,8 @@ static int bfs_write_begin(struct file *file, struct address_space *mapping,  	ret = block_write_begin(mapping, pos, len, flags, pagep,  				bfs_get_block); -	if (unlikely(ret)) { -		loff_t isize = mapping->host->i_size; -		if (pos + len > isize) -			vmtruncate(mapping->host, isize); -	} +	if (unlikely(ret)) +		bfs_write_failed(mapping, pos + len);  	return ret;  } @@ -186,7 +191,6 @@ static sector_t bfs_bmap(struct address_space *mapping, sector_t block)  const struct address_space_operations bfs_aops = {  	.readpage	= bfs_readpage,  	.writepage	= bfs_writepage, -	.sync_page	= block_sync_page,  	.write_begin	= bfs_write_begin,  	.write_end	= generic_write_end,  	.bmap		= bfs_bmap, diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 76db6d7d49b..7041ac35ace 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -40,7 +40,7 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino)  	int block, off;  	inode = iget_locked(sb, ino); -	if (IS_ERR(inode)) +	if (!inode)  		return ERR_PTR(-ENOMEM);  	if (!(inode->i_state & I_NEW))  		return inode; @@ -76,9 +76,9 @@ struct inode *bfs_iget(struct super_block *sb, unsigned long ino)  	BFS_I(inode)->i_sblock =  le32_to_cpu(di->i_sblock);  	BFS_I(inode)->i_eblock =  le32_to_cpu(di->i_eblock);  	BFS_I(inode)->i_dsk_ino = le16_to_cpu(di->i_ino); -	inode->i_uid =  le32_to_cpu(di->i_uid); -	inode->i_gid =  le32_to_cpu(di->i_gid); -	inode->i_nlink =  le32_to_cpu(di->i_nlink); +	i_uid_write(inode, le32_to_cpu(di->i_uid)); +	i_gid_write(inode,  le32_to_cpu(di->i_gid)); +	set_nlink(inode, le32_to_cpu(di->i_nlink));  	inode->i_size = BFS_FILESIZE(di);  	inode->i_blocks = BFS_FILEBLOCKS(di);  	inode->i_atime.tv_sec =  le32_to_cpu(di->i_atime); @@ -139,8 +139,8 @@ static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc)  	di->i_ino = cpu_to_le16(ino);  	di->i_mode = cpu_to_le32(inode->i_mode); -	di->i_uid = cpu_to_le32(inode->i_uid); -	di->i_gid = cpu_to_le32(inode->i_gid); +	di->i_uid = cpu_to_le32(i_uid_read(inode)); +	di->i_gid = cpu_to_le32(i_gid_read(inode));  	di->i_nlink = cpu_to_le32(inode->i_nlink);  	di->i_atime = cpu_to_le32(inode->i_atime.tv_sec);  	di->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec); @@ -172,9 +172,9 @@ static void bfs_evict_inode(struct inode *inode)  	dprintf("ino=%08lx\n", ino); -	truncate_inode_pages(&inode->i_data, 0); +	truncate_inode_pages_final(&inode->i_data);  	invalidate_inode_buffers(inode); -	end_writeback(inode); +	clear_inode(inode);  	if (inode->i_nlink)  		return; @@ -248,11 +248,17 @@ static struct inode *bfs_alloc_inode(struct super_block *sb)  	return &bi->vfs_inode;  } -static void bfs_destroy_inode(struct inode *inode) +static void bfs_i_callback(struct rcu_head *head)  { +	struct inode *inode = container_of(head, struct inode, i_rcu);  	kmem_cache_free(bfs_inode_cachep, BFS_I(inode));  } +static void bfs_destroy_inode(struct inode *inode) +{ +	call_rcu(&inode->i_rcu, bfs_i_callback); +} +  static void init_once(void *foo)  {  	struct bfs_inode_info *bi = foo; @@ -260,7 +266,7 @@ static void init_once(void *foo)  	inode_init_once(&bi->vfs_inode);  } -static int init_inodecache(void) +static int __init init_inodecache(void)  {  	bfs_inode_cachep = kmem_cache_create("bfs_inode_cache",  					     sizeof(struct bfs_inode_info), @@ -274,6 +280,11 @@ static int init_inodecache(void)  static void destroy_inodecache(void)  { +	/* +	 * Make sure all delayed rcu free inodes are flushed before we +	 * destroy cache. +	 */ +	rcu_barrier();  	kmem_cache_destroy(bfs_inode_cachep);  } @@ -361,9 +372,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)  		ret = PTR_ERR(inode);  		goto out2;  	} -	s->s_root = d_alloc_root(inode); +	s->s_root = d_make_root(inode);  	if (!s->s_root) { -		iput(inode);  		ret = -ENOMEM;  		goto out2;  	} @@ -463,6 +473,7 @@ static struct file_system_type bfs_fs_type = {  	.kill_sb	= kill_block_super,  	.fs_flags	= FS_REQUIRES_DEV,  }; +MODULE_ALIAS_FS("bfs");  static int __init init_bfs_fs(void)  {  | 
