diff options
Diffstat (limited to 'fs/udf')
-rw-r--r-- | fs/udf/dir.c | 2 | ||||
-rw-r--r-- | fs/udf/file.c | 45 | ||||
-rw-r--r-- | fs/udf/ialloc.c | 11 | ||||
-rw-r--r-- | fs/udf/namei.c | 10 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 3 |
5 files changed, 34 insertions, 37 deletions
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index f0f2a436251e..3a84455c2a77 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c @@ -209,6 +209,6 @@ static int udf_readdir(struct file *filp, void *dirent, filldir_t filldir) const struct file_operations udf_dir_operations = { .read = generic_read_dir, .readdir = udf_readdir, - .ioctl = udf_ioctl, + .unlocked_ioctl = udf_ioctl, .fsync = simple_fsync, }; diff --git a/fs/udf/file.c b/fs/udf/file.c index 4b6a46ccbf46..baae3a723946 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -37,6 +37,7 @@ #include <linux/quotaops.h> #include <linux/buffer_head.h> #include <linux/aio.h> +#include <linux/smp_lock.h> #include "udf_i.h" #include "udf_sb.h" @@ -144,50 +145,60 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, return retval; } -int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) +long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { + struct inode *inode = filp->f_dentry->d_inode; long old_block, new_block; int result = -EINVAL; + lock_kernel(); + if (file_permission(filp, MAY_READ) != 0) { - udf_debug("no permission to access inode %lu\n", - inode->i_ino); - return -EPERM; + udf_debug("no permission to access inode %lu\n", inode->i_ino); + result = -EPERM; + goto out; } if (!arg) { udf_debug("invalid argument to udf_ioctl\n"); - return -EINVAL; + result = -EINVAL; + goto out; } switch (cmd) { case UDF_GETVOLIDENT: if (copy_to_user((char __user *)arg, UDF_SB(inode->i_sb)->s_volume_ident, 32)) - return -EFAULT; + result = -EFAULT; else - return 0; + result = 0; + goto out; case UDF_RELOCATE_BLOCKS: - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; - if (get_user(old_block, (long __user *)arg)) - return -EFAULT; + if (!capable(CAP_SYS_ADMIN)) { + result = -EACCES; + goto out; + } + if (get_user(old_block, (long __user *)arg)) { + result = -EFAULT; + goto out; + } result = udf_relocate_blocks(inode->i_sb, old_block, &new_block); if (result == 0) result = put_user(new_block, (long __user *)arg); - return result; + goto out; case UDF_GETEASIZE: result = put_user(UDF_I(inode)->i_lenEAttr, (int __user *)arg); - break; + goto out; case UDF_GETEABLOCK: result = copy_to_user((char __user *)arg, UDF_I(inode)->i_ext.i_data, UDF_I(inode)->i_lenEAttr) ? -EFAULT : 0; - break; + goto out; } +out: + unlock_kernel(); return result; } @@ -207,7 +218,7 @@ static int udf_release_file(struct inode *inode, struct file *filp) const struct file_operations udf_file_operations = { .read = do_sync_read, .aio_read = generic_file_aio_read, - .ioctl = udf_ioctl, + .unlocked_ioctl = udf_ioctl, .open = dquot_file_open, .mmap = generic_file_mmap, .write = do_sync_write, @@ -227,7 +238,7 @@ int udf_setattr(struct dentry *dentry, struct iattr *iattr) if (error) return error; - if (iattr->ia_valid & ATTR_SIZE) + if (is_quota_modification(inode, iattr)) dquot_initialize(inode); if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index fb68c9cd0c3e..2b5586c7f02a 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c @@ -124,15 +124,8 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) udf_updated_lvid(sb); } mutex_unlock(&sbi->s_alloc_mutex); - inode->i_mode = mode; - inode->i_uid = current_fsuid(); - if (dir->i_mode & S_ISGID) { - inode->i_gid = dir->i_gid; - if (S_ISDIR(mode)) - mode |= S_ISGID; - } else { - inode->i_gid = current_fsgid(); - } + + inode_init_owner(inode, dir, mode); iinfo->i_location.logicalBlockNum = block; iinfo->i_location.partitionReferenceNum = diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 75816025f95f..585f733615dc 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -579,7 +579,6 @@ static int udf_create(struct inode *dir, struct dentry *dentry, int mode, inode->i_data.a_ops = &udf_aops; inode->i_op = &udf_file_inode_operations; inode->i_fop = &udf_file_operations; - inode->i_mode = mode; mark_inode_dirty(inode); fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); @@ -627,7 +626,6 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, goto out; iinfo = UDF_I(inode); - inode->i_uid = current_fsuid(); init_special_inode(inode, mode, rdev); fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); if (!fi) { @@ -674,7 +672,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) goto out; err = -EIO; - inode = udf_new_inode(dir, S_IFDIR, &err); + inode = udf_new_inode(dir, S_IFDIR | mode, &err); if (!inode) goto out; @@ -697,9 +695,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); brelse(fibh.sbh); - inode->i_mode = S_IFDIR | mode; - if (dir->i_mode & S_ISGID) - inode->i_mode |= S_ISGID; mark_inode_dirty(inode); fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); @@ -912,7 +907,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, dquot_initialize(dir); lock_kernel(); - inode = udf_new_inode(dir, S_IFLNK, &err); + inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); if (!inode) goto out; @@ -923,7 +918,6 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, } iinfo = UDF_I(inode); - inode->i_mode = S_IFLNK | S_IRWXUGO; inode->i_data.a_ops = &udf_symlink_aops; inode->i_op = &udf_symlink_inode_operations; diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 702a1148e702..9079ff7d6255 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h @@ -130,8 +130,7 @@ extern int udf_write_fi(struct inode *inode, struct fileIdentDesc *, uint8_t *, uint8_t *); /* file.c */ -extern int udf_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); +extern long udf_ioctl(struct file *, unsigned int, unsigned long); extern int udf_setattr(struct dentry *dentry, struct iattr *iattr); /* inode.c */ extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); |