diff options
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 40 |
1 files changed, 21 insertions, 19 deletions
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/tty.h> | 16 | #include <linux/tty.h> |
17 | #include <linux/namei.h> | 17 | #include <linux/namei.h> |
18 | #include <linux/backing-dev.h> | 18 | #include <linux/backing-dev.h> |
19 | #include <linux/capability.h> | ||
19 | #include <linux/security.h> | 20 | #include <linux/security.h> |
20 | #include <linux/mount.h> | 21 | #include <linux/mount.h> |
21 | #include <linux/vfs.h> | 22 | #include <linux/vfs.h> |
@@ -194,7 +195,8 @@ out: | |||
194 | return error; | 195 | return error; |
195 | } | 196 | } |
196 | 197 | ||
197 | int do_truncate(struct dentry *dentry, loff_t length, struct file *filp) | 198 | int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, |
199 | struct file *filp) | ||
198 | { | 200 | { |
199 | int err; | 201 | int err; |
200 | struct iattr newattrs; | 202 | struct iattr newattrs; |
@@ -204,19 +206,19 @@ int do_truncate(struct dentry *dentry, loff_t length, struct file *filp) | |||
204 | return -EINVAL; | 206 | return -EINVAL; |
205 | 207 | ||
206 | newattrs.ia_size = length; | 208 | newattrs.ia_size = length; |
207 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; | 209 | newattrs.ia_valid = ATTR_SIZE | time_attrs; |
208 | if (filp) { | 210 | if (filp) { |
209 | newattrs.ia_file = filp; | 211 | newattrs.ia_file = filp; |
210 | newattrs.ia_valid |= ATTR_FILE; | 212 | newattrs.ia_valid |= ATTR_FILE; |
211 | } | 213 | } |
212 | 214 | ||
213 | down(&dentry->d_inode->i_sem); | 215 | mutex_lock(&dentry->d_inode->i_mutex); |
214 | err = notify_change(dentry, &newattrs); | 216 | err = notify_change(dentry, &newattrs); |
215 | up(&dentry->d_inode->i_sem); | 217 | mutex_unlock(&dentry->d_inode->i_mutex); |
216 | return err; | 218 | return err; |
217 | } | 219 | } |
218 | 220 | ||
219 | static inline long do_sys_truncate(const char __user * path, loff_t length) | 221 | static long do_sys_truncate(const char __user * path, loff_t length) |
220 | { | 222 | { |
221 | struct nameidata nd; | 223 | struct nameidata nd; |
222 | struct inode * inode; | 224 | struct inode * inode; |
@@ -266,7 +268,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length) | |||
266 | error = locks_verify_truncate(inode, NULL, length); | 268 | error = locks_verify_truncate(inode, NULL, length); |
267 | if (!error) { | 269 | if (!error) { |
268 | DQUOT_INIT(inode); | 270 | DQUOT_INIT(inode); |
269 | error = do_truncate(nd.dentry, length, NULL); | 271 | error = do_truncate(nd.dentry, length, 0, NULL); |
270 | } | 272 | } |
271 | put_write_access(inode); | 273 | put_write_access(inode); |
272 | 274 | ||
@@ -282,7 +284,7 @@ asmlinkage long sys_truncate(const char __user * path, unsigned long length) | |||
282 | return do_sys_truncate(path, (long)length); | 284 | return do_sys_truncate(path, (long)length); |
283 | } | 285 | } |
284 | 286 | ||
285 | static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small) | 287 | static long do_sys_ftruncate(unsigned int fd, loff_t length, int small) |
286 | { | 288 | { |
287 | struct inode * inode; | 289 | struct inode * inode; |
288 | struct dentry *dentry; | 290 | struct dentry *dentry; |
@@ -318,7 +320,7 @@ static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small) | |||
318 | 320 | ||
319 | error = locks_verify_truncate(inode, file, length); | 321 | error = locks_verify_truncate(inode, file, length); |
320 | if (!error) | 322 | if (!error) |
321 | error = do_truncate(dentry, length, file); | 323 | error = do_truncate(dentry, length, 0, file); |
322 | out_putf: | 324 | out_putf: |
323 | fput(file); | 325 | fput(file); |
324 | out: | 326 | out: |
@@ -397,9 +399,9 @@ asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times) | |||
397 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) | 399 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) |
398 | goto dput_and_out; | 400 | goto dput_and_out; |
399 | } | 401 | } |
400 | down(&inode->i_sem); | 402 | mutex_lock(&inode->i_mutex); |
401 | error = notify_change(nd.dentry, &newattrs); | 403 | error = notify_change(nd.dentry, &newattrs); |
402 | up(&inode->i_sem); | 404 | mutex_unlock(&inode->i_mutex); |
403 | dput_and_out: | 405 | dput_and_out: |
404 | path_release(&nd); | 406 | path_release(&nd); |
405 | out: | 407 | out: |
@@ -450,9 +452,9 @@ long do_utimes(char __user * filename, struct timeval * times) | |||
450 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) | 452 | (error = vfs_permission(&nd, MAY_WRITE)) != 0) |
451 | goto dput_and_out; | 453 | goto dput_and_out; |
452 | } | 454 | } |
453 | down(&inode->i_sem); | 455 | mutex_lock(&inode->i_mutex); |
454 | error = notify_change(nd.dentry, &newattrs); | 456 | error = notify_change(nd.dentry, &newattrs); |
455 | up(&inode->i_sem); | 457 | mutex_unlock(&inode->i_mutex); |
456 | dput_and_out: | 458 | dput_and_out: |
457 | path_release(&nd); | 459 | path_release(&nd); |
458 | out: | 460 | out: |
@@ -619,13 +621,13 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) | |||
619 | err = -EPERM; | 621 | err = -EPERM; |
620 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 622 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
621 | goto out_putf; | 623 | goto out_putf; |
622 | down(&inode->i_sem); | 624 | mutex_lock(&inode->i_mutex); |
623 | if (mode == (mode_t) -1) | 625 | if (mode == (mode_t) -1) |
624 | mode = inode->i_mode; | 626 | mode = inode->i_mode; |
625 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); | 627 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); |
626 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; | 628 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
627 | err = notify_change(dentry, &newattrs); | 629 | err = notify_change(dentry, &newattrs); |
628 | up(&inode->i_sem); | 630 | mutex_unlock(&inode->i_mutex); |
629 | 631 | ||
630 | out_putf: | 632 | out_putf: |
631 | fput(file); | 633 | fput(file); |
@@ -653,13 +655,13 @@ asmlinkage long sys_chmod(const char __user * filename, mode_t mode) | |||
653 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 655 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
654 | goto dput_and_out; | 656 | goto dput_and_out; |
655 | 657 | ||
656 | down(&inode->i_sem); | 658 | mutex_lock(&inode->i_mutex); |
657 | if (mode == (mode_t) -1) | 659 | if (mode == (mode_t) -1) |
658 | mode = inode->i_mode; | 660 | mode = inode->i_mode; |
659 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); | 661 | newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); |
660 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; | 662 | newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; |
661 | error = notify_change(nd.dentry, &newattrs); | 663 | error = notify_change(nd.dentry, &newattrs); |
662 | up(&inode->i_sem); | 664 | mutex_unlock(&inode->i_mutex); |
663 | 665 | ||
664 | dput_and_out: | 666 | dput_and_out: |
665 | path_release(&nd); | 667 | path_release(&nd); |
@@ -695,9 +697,9 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group) | |||
695 | } | 697 | } |
696 | if (!S_ISDIR(inode->i_mode)) | 698 | if (!S_ISDIR(inode->i_mode)) |
697 | newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID; | 699 | newattrs.ia_valid |= ATTR_KILL_SUID|ATTR_KILL_SGID; |
698 | down(&inode->i_sem); | 700 | mutex_lock(&inode->i_mutex); |
699 | error = notify_change(dentry, &newattrs); | 701 | error = notify_change(dentry, &newattrs); |
700 | up(&inode->i_sem); | 702 | mutex_unlock(&inode->i_mutex); |
701 | out: | 703 | out: |
702 | return error; | 704 | return error; |
703 | } | 705 | } |
@@ -970,7 +972,7 @@ out: | |||
970 | 972 | ||
971 | EXPORT_SYMBOL(get_unused_fd); | 973 | EXPORT_SYMBOL(get_unused_fd); |
972 | 974 | ||
973 | static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) | 975 | static void __put_unused_fd(struct files_struct *files, unsigned int fd) |
974 | { | 976 | { |
975 | struct fdtable *fdt = files_fdtable(files); | 977 | struct fdtable *fdt = files_fdtable(files); |
976 | __FD_CLR(fd, fdt->open_fds); | 978 | __FD_CLR(fd, fdt->open_fds); |