diff options
Diffstat (limited to 'fs/hfsplus/dir.c')
| -rw-r--r-- | fs/hfsplus/dir.c | 57 | 
1 files changed, 41 insertions, 16 deletions
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 6b9f921ef2f..031c24e5052 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -15,6 +15,7 @@  #include "hfsplus_fs.h"  #include "hfsplus_raw.h" +#include "xattr.h"  static inline void hfsplus_instantiate(struct dentry *dentry,  				       struct inode *inode, u32 cnid) @@ -122,7 +123,7 @@ fail:  static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)  { -	struct inode *inode = filp->f_path.dentry->d_inode; +	struct inode *inode = file_inode(filp);  	struct super_block *sb = inode->i_sb;  	int len, err;  	char strbuf[HFSPLUS_MAX_STRLEN + 1]; @@ -138,7 +139,7 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir)  	if (err)  		return err;  	hfsplus_cat_build_key(sb, fd.search_key, inode->i_ino, NULL); -	err = hfs_brec_find(&fd); +	err = hfs_brec_find(&fd, hfs_find_rec_by_key);  	if (err)  		goto out; @@ -421,6 +422,15 @@ static int hfsplus_symlink(struct inode *dir, struct dentry *dentry,  	if (res)  		goto out_err; +	res = hfsplus_init_inode_security(inode, dir, &dentry->d_name); +	if (res == -EOPNOTSUPP) +		res = 0; /* Operation is not supported. */ +	else if (res) { +		/* Try to delete anyway without error analysis. */ +		hfsplus_delete_cat(inode->i_ino, dir, &dentry->d_name); +		goto out_err; +	} +  	hfsplus_instantiate(dentry, inode, inode->i_ino);  	mark_inode_dirty(inode);  	goto out; @@ -450,15 +460,26 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry,  		init_special_inode(inode, mode, rdev);  	res = hfsplus_create_cat(inode->i_ino, dir, &dentry->d_name, inode); -	if (res) { -		clear_nlink(inode); -		hfsplus_delete_inode(inode); -		iput(inode); -		goto out; +	if (res) +		goto failed_mknod; + +	res = hfsplus_init_inode_security(inode, dir, &dentry->d_name); +	if (res == -EOPNOTSUPP) +		res = 0; /* Operation is not supported. */ +	else if (res) { +		/* Try to delete anyway without error analysis. */ +		hfsplus_delete_cat(inode->i_ino, dir, &dentry->d_name); +		goto failed_mknod;  	}  	hfsplus_instantiate(dentry, inode, inode->i_ino);  	mark_inode_dirty(inode); +	goto out; + +failed_mknod: +	clear_nlink(inode); +	hfsplus_delete_inode(inode); +	iput(inode);  out:  	mutex_unlock(&sbi->vh_mutex);  	return res; @@ -499,15 +520,19 @@ static int hfsplus_rename(struct inode *old_dir, struct dentry *old_dentry,  }  const struct inode_operations hfsplus_dir_inode_operations = { -	.lookup		= hfsplus_lookup, -	.create		= hfsplus_create, -	.link		= hfsplus_link, -	.unlink		= hfsplus_unlink, -	.mkdir		= hfsplus_mkdir, -	.rmdir		= hfsplus_rmdir, -	.symlink	= hfsplus_symlink, -	.mknod		= hfsplus_mknod, -	.rename		= hfsplus_rename, +	.lookup			= hfsplus_lookup, +	.create			= hfsplus_create, +	.link			= hfsplus_link, +	.unlink			= hfsplus_unlink, +	.mkdir			= hfsplus_mkdir, +	.rmdir			= hfsplus_rmdir, +	.symlink		= hfsplus_symlink, +	.mknod			= hfsplus_mknod, +	.rename			= hfsplus_rename, +	.setxattr		= generic_setxattr, +	.getxattr		= generic_getxattr, +	.listxattr		= hfsplus_listxattr, +	.removexattr		= hfsplus_removexattr,  };  const struct file_operations hfsplus_dir_operations = {  |