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) | |||
| 209 | const struct file_operations udf_dir_operations = { | 209 | const struct file_operations udf_dir_operations = { |
| 210 | .read = generic_read_dir, | 210 | .read = generic_read_dir, |
| 211 | .readdir = udf_readdir, | 211 | .readdir = udf_readdir, |
| 212 | .ioctl = udf_ioctl, | 212 | .unlocked_ioctl = udf_ioctl, |
| 213 | .fsync = simple_fsync, | 213 | .fsync = simple_fsync, |
| 214 | }; | 214 | }; |
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 @@ | |||
| 37 | #include <linux/quotaops.h> | 37 | #include <linux/quotaops.h> |
| 38 | #include <linux/buffer_head.h> | 38 | #include <linux/buffer_head.h> |
| 39 | #include <linux/aio.h> | 39 | #include <linux/aio.h> |
| 40 | #include <linux/smp_lock.h> | ||
| 40 | 41 | ||
| 41 | #include "udf_i.h" | 42 | #include "udf_i.h" |
| 42 | #include "udf_sb.h" | 43 | #include "udf_sb.h" |
| @@ -144,50 +145,60 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 144 | return retval; | 145 | return retval; |
| 145 | } | 146 | } |
| 146 | 147 | ||
| 147 | int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, | 148 | long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
| 148 | unsigned long arg) | ||
| 149 | { | 149 | { |
| 150 | struct inode *inode = filp->f_dentry->d_inode; | ||
| 150 | long old_block, new_block; | 151 | long old_block, new_block; |
| 151 | int result = -EINVAL; | 152 | int result = -EINVAL; |
| 152 | 153 | ||
| 154 | lock_kernel(); | ||
| 155 | |||
| 153 | if (file_permission(filp, MAY_READ) != 0) { | 156 | if (file_permission(filp, MAY_READ) != 0) { |
| 154 | udf_debug("no permission to access inode %lu\n", | 157 | udf_debug("no permission to access inode %lu\n", inode->i_ino); |
| 155 | inode->i_ino); | 158 | result = -EPERM; |
| 156 | return -EPERM; | 159 | goto out; |
| 157 | } | 160 | } |
| 158 | 161 | ||
| 159 | if (!arg) { | 162 | if (!arg) { |
| 160 | udf_debug("invalid argument to udf_ioctl\n"); | 163 | udf_debug("invalid argument to udf_ioctl\n"); |
| 161 | return -EINVAL; | 164 | result = -EINVAL; |
| 165 | goto out; | ||
| 162 | } | 166 | } |
| 163 | 167 | ||
| 164 | switch (cmd) { | 168 | switch (cmd) { |
| 165 | case UDF_GETVOLIDENT: | 169 | case UDF_GETVOLIDENT: |
| 166 | if (copy_to_user((char __user *)arg, | 170 | if (copy_to_user((char __user *)arg, |
| 167 | UDF_SB(inode->i_sb)->s_volume_ident, 32)) | 171 | UDF_SB(inode->i_sb)->s_volume_ident, 32)) |
| 168 | return -EFAULT; | 172 | result = -EFAULT; |
| 169 | else | 173 | else |
| 170 | return 0; | 174 | result = 0; |
| 175 | goto out; | ||
| 171 | case UDF_RELOCATE_BLOCKS: | 176 | case UDF_RELOCATE_BLOCKS: |
| 172 | if (!capable(CAP_SYS_ADMIN)) | 177 | if (!capable(CAP_SYS_ADMIN)) { |
| 173 | return -EACCES; | 178 | result = -EACCES; |
| 174 | if (get_user(old_block, (long __user *)arg)) | 179 | goto out; |
| 175 | return -EFAULT; | 180 | } |
| 181 | if (get_user(old_block, (long __user *)arg)) { | ||
| 182 | result = -EFAULT; | ||
| 183 | goto out; | ||
| 184 | } | ||
| 176 | result = udf_relocate_blocks(inode->i_sb, | 185 | result = udf_relocate_blocks(inode->i_sb, |
| 177 | old_block, &new_block); | 186 | old_block, &new_block); |
| 178 | if (result == 0) | 187 | if (result == 0) |
| 179 | result = put_user(new_block, (long __user *)arg); | 188 | result = put_user(new_block, (long __user *)arg); |
| 180 | return result; | 189 | goto out; |
| 181 | case UDF_GETEASIZE: | 190 | case UDF_GETEASIZE: |
| 182 | result = put_user(UDF_I(inode)->i_lenEAttr, (int __user *)arg); | 191 | result = put_user(UDF_I(inode)->i_lenEAttr, (int __user *)arg); |
| 183 | break; | 192 | goto out; |
| 184 | case UDF_GETEABLOCK: | 193 | case UDF_GETEABLOCK: |
| 185 | result = copy_to_user((char __user *)arg, | 194 | result = copy_to_user((char __user *)arg, |
| 186 | UDF_I(inode)->i_ext.i_data, | 195 | UDF_I(inode)->i_ext.i_data, |
| 187 | UDF_I(inode)->i_lenEAttr) ? -EFAULT : 0; | 196 | UDF_I(inode)->i_lenEAttr) ? -EFAULT : 0; |
| 188 | break; | 197 | goto out; |
| 189 | } | 198 | } |
| 190 | 199 | ||
| 200 | out: | ||
| 201 | unlock_kernel(); | ||
| 191 | return result; | 202 | return result; |
| 192 | } | 203 | } |
| 193 | 204 | ||
| @@ -207,7 +218,7 @@ static int udf_release_file(struct inode *inode, struct file *filp) | |||
| 207 | const struct file_operations udf_file_operations = { | 218 | const struct file_operations udf_file_operations = { |
| 208 | .read = do_sync_read, | 219 | .read = do_sync_read, |
| 209 | .aio_read = generic_file_aio_read, | 220 | .aio_read = generic_file_aio_read, |
| 210 | .ioctl = udf_ioctl, | 221 | .unlocked_ioctl = udf_ioctl, |
| 211 | .open = dquot_file_open, | 222 | .open = dquot_file_open, |
| 212 | .mmap = generic_file_mmap, | 223 | .mmap = generic_file_mmap, |
| 213 | .write = do_sync_write, | 224 | .write = do_sync_write, |
| @@ -227,7 +238,7 @@ int udf_setattr(struct dentry *dentry, struct iattr *iattr) | |||
| 227 | if (error) | 238 | if (error) |
| 228 | return error; | 239 | return error; |
| 229 | 240 | ||
| 230 | if (iattr->ia_valid & ATTR_SIZE) | 241 | if (is_quota_modification(inode, iattr)) |
| 231 | dquot_initialize(inode); | 242 | dquot_initialize(inode); |
| 232 | 243 | ||
| 233 | if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || | 244 | 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) | |||
| 124 | udf_updated_lvid(sb); | 124 | udf_updated_lvid(sb); |
| 125 | } | 125 | } |
| 126 | mutex_unlock(&sbi->s_alloc_mutex); | 126 | mutex_unlock(&sbi->s_alloc_mutex); |
| 127 | inode->i_mode = mode; | 127 | |
| 128 | inode->i_uid = current_fsuid(); | 128 | inode_init_owner(inode, dir, mode); |
| 129 | if (dir->i_mode & S_ISGID) { | ||
| 130 | inode->i_gid = dir->i_gid; | ||
| 131 | if (S_ISDIR(mode)) | ||
| 132 | mode |= S_ISGID; | ||
| 133 | } else { | ||
| 134 | inode->i_gid = current_fsgid(); | ||
| 135 | } | ||
| 136 | 129 | ||
| 137 | iinfo->i_location.logicalBlockNum = block; | 130 | iinfo->i_location.logicalBlockNum = block; |
| 138 | iinfo->i_location.partitionReferenceNum = | 131 | 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, | |||
| 579 | inode->i_data.a_ops = &udf_aops; | 579 | inode->i_data.a_ops = &udf_aops; |
| 580 | inode->i_op = &udf_file_inode_operations; | 580 | inode->i_op = &udf_file_inode_operations; |
| 581 | inode->i_fop = &udf_file_operations; | 581 | inode->i_fop = &udf_file_operations; |
| 582 | inode->i_mode = mode; | ||
| 583 | mark_inode_dirty(inode); | 582 | mark_inode_dirty(inode); |
| 584 | 583 | ||
| 585 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 584 | 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, | |||
| 627 | goto out; | 626 | goto out; |
| 628 | 627 | ||
| 629 | iinfo = UDF_I(inode); | 628 | iinfo = UDF_I(inode); |
| 630 | inode->i_uid = current_fsuid(); | ||
| 631 | init_special_inode(inode, mode, rdev); | 629 | init_special_inode(inode, mode, rdev); |
| 632 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 630 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
| 633 | if (!fi) { | 631 | if (!fi) { |
| @@ -674,7 +672,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 674 | goto out; | 672 | goto out; |
| 675 | 673 | ||
| 676 | err = -EIO; | 674 | err = -EIO; |
| 677 | inode = udf_new_inode(dir, S_IFDIR, &err); | 675 | inode = udf_new_inode(dir, S_IFDIR | mode, &err); |
| 678 | if (!inode) | 676 | if (!inode) |
| 679 | goto out; | 677 | goto out; |
| 680 | 678 | ||
| @@ -697,9 +695,6 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 697 | FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; | 695 | FID_FILE_CHAR_DIRECTORY | FID_FILE_CHAR_PARENT; |
| 698 | udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); | 696 | udf_write_fi(inode, &cfi, fi, &fibh, NULL, NULL); |
| 699 | brelse(fibh.sbh); | 697 | brelse(fibh.sbh); |
| 700 | inode->i_mode = S_IFDIR | mode; | ||
| 701 | if (dir->i_mode & S_ISGID) | ||
| 702 | inode->i_mode |= S_ISGID; | ||
| 703 | mark_inode_dirty(inode); | 698 | mark_inode_dirty(inode); |
| 704 | 699 | ||
| 705 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 700 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
| @@ -912,7 +907,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
| 912 | dquot_initialize(dir); | 907 | dquot_initialize(dir); |
| 913 | 908 | ||
| 914 | lock_kernel(); | 909 | lock_kernel(); |
| 915 | inode = udf_new_inode(dir, S_IFLNK, &err); | 910 | inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err); |
| 916 | if (!inode) | 911 | if (!inode) |
| 917 | goto out; | 912 | goto out; |
| 918 | 913 | ||
| @@ -923,7 +918,6 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry, | |||
| 923 | } | 918 | } |
| 924 | 919 | ||
| 925 | iinfo = UDF_I(inode); | 920 | iinfo = UDF_I(inode); |
| 926 | inode->i_mode = S_IFLNK | S_IRWXUGO; | ||
| 927 | inode->i_data.a_ops = &udf_symlink_aops; | 921 | inode->i_data.a_ops = &udf_symlink_aops; |
| 928 | inode->i_op = &udf_symlink_inode_operations; | 922 | inode->i_op = &udf_symlink_inode_operations; |
| 929 | 923 | ||
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 *, | |||
| 130 | uint8_t *, uint8_t *); | 130 | uint8_t *, uint8_t *); |
| 131 | 131 | ||
| 132 | /* file.c */ | 132 | /* file.c */ |
| 133 | extern int udf_ioctl(struct inode *, struct file *, unsigned int, | 133 | extern long udf_ioctl(struct file *, unsigned int, unsigned long); |
| 134 | unsigned long); | ||
| 135 | extern int udf_setattr(struct dentry *dentry, struct iattr *iattr); | 134 | extern int udf_setattr(struct dentry *dentry, struct iattr *iattr); |
| 136 | /* inode.c */ | 135 | /* inode.c */ |
| 137 | extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); | 136 | extern struct inode *udf_iget(struct super_block *, struct kernel_lb_addr *); |
