diff options
Diffstat (limited to 'fs/ext2')
| -rw-r--r-- | fs/ext2/dir.c | 27 | ||||
| -rw-r--r-- | fs/ext2/namei.c | 24 | 
2 files changed, 36 insertions, 15 deletions
| diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index 4237722bfd27..6e1d4ab09d72 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c @@ -287,17 +287,17 @@ static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode)  }  static int -ext2_readdir (struct file * filp, void * dirent, filldir_t filldir) +ext2_readdir(struct file *file, struct dir_context *ctx)  { -	loff_t pos = filp->f_pos; -	struct inode *inode = file_inode(filp); +	loff_t pos = ctx->pos; +	struct inode *inode = file_inode(file);  	struct super_block *sb = inode->i_sb;  	unsigned int offset = pos & ~PAGE_CACHE_MASK;  	unsigned long n = pos >> PAGE_CACHE_SHIFT;  	unsigned long npages = dir_pages(inode);  	unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);  	unsigned char *types = NULL; -	int need_revalidate = filp->f_version != inode->i_version; +	int need_revalidate = file->f_version != inode->i_version;  	if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))  		return 0; @@ -314,16 +314,16 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)  			ext2_error(sb, __func__,  				   "bad page in #%lu",  				   inode->i_ino); -			filp->f_pos += PAGE_CACHE_SIZE - offset; +			ctx->pos += PAGE_CACHE_SIZE - offset;  			return PTR_ERR(page);  		}  		kaddr = page_address(page);  		if (unlikely(need_revalidate)) {  			if (offset) {  				offset = ext2_validate_entry(kaddr, offset, chunk_mask); -				filp->f_pos = (n<<PAGE_CACHE_SHIFT) + offset; +				ctx->pos = (n<<PAGE_CACHE_SHIFT) + offset;  			} -			filp->f_version = inode->i_version; +			file->f_version = inode->i_version;  			need_revalidate = 0;  		}  		de = (ext2_dirent *)(kaddr+offset); @@ -336,22 +336,19 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)  				return -EIO;  			}  			if (de->inode) { -				int over;  				unsigned char d_type = DT_UNKNOWN;  				if (types && de->file_type < EXT2_FT_MAX)  					d_type = types[de->file_type]; -				offset = (char *)de - kaddr; -				over = filldir(dirent, de->name, de->name_len, -						(n<<PAGE_CACHE_SHIFT) | offset, -						le32_to_cpu(de->inode), d_type); -				if (over) { +				if (!dir_emit(ctx, de->name, de->name_len, +						le32_to_cpu(de->inode), +						d_type)) {  					ext2_put_page(page);  					return 0;  				}  			} -			filp->f_pos += ext2_rec_len_from_disk(de->rec_len); +			ctx->pos += ext2_rec_len_from_disk(de->rec_len);  		}  		ext2_put_page(page);  	} @@ -724,7 +721,7 @@ not_empty:  const struct file_operations ext2_dir_operations = {  	.llseek		= generic_file_llseek,  	.read		= generic_read_dir, -	.readdir	= ext2_readdir, +	.iterate	= ext2_readdir,  	.unlocked_ioctl = ext2_ioctl,  #ifdef CONFIG_COMPAT  	.compat_ioctl	= ext2_compat_ioctl, diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 73b0d9519836..256dd5f4c1c4 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -119,6 +119,29 @@ static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode  	return ext2_add_nondir(dentry, inode);  } +static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) +{ +	struct inode *inode = ext2_new_inode(dir, mode, NULL); +	if (IS_ERR(inode)) +		return PTR_ERR(inode); + +	inode->i_op = &ext2_file_inode_operations; +	if (ext2_use_xip(inode->i_sb)) { +		inode->i_mapping->a_ops = &ext2_aops_xip; +		inode->i_fop = &ext2_xip_file_operations; +	} else if (test_opt(inode->i_sb, NOBH)) { +		inode->i_mapping->a_ops = &ext2_nobh_aops; +		inode->i_fop = &ext2_file_operations; +	} else { +		inode->i_mapping->a_ops = &ext2_aops; +		inode->i_fop = &ext2_file_operations; +	} +	mark_inode_dirty(inode); +	d_tmpfile(dentry, inode); +	unlock_new_inode(inode); +	return 0; +} +  static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev)  {  	struct inode * inode; @@ -398,6 +421,7 @@ const struct inode_operations ext2_dir_inode_operations = {  #endif  	.setattr	= ext2_setattr,  	.get_acl	= ext2_get_acl, +	.tmpfile	= ext2_tmpfile,  };  const struct inode_operations ext2_special_inode_operations = { |