aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/fs/open.c b/fs/open.c
index f53a5b9ffb7d..8e20c1f32563 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -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
197int do_truncate(struct dentry *dentry, loff_t length, struct file *filp) 198int 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
219static inline long do_sys_truncate(const char __user * path, loff_t length) 221static 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
285static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small) 287static 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);
322out_putf: 324out_putf:
323 fput(file); 325 fput(file);
324out: 326out:
@@ -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);
403dput_and_out: 405dput_and_out:
404 path_release(&nd); 406 path_release(&nd);
405out: 407out:
@@ -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);
456dput_and_out: 458dput_and_out:
457 path_release(&nd); 459 path_release(&nd);
458out: 460out:
@@ -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
630out_putf: 632out_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
664dput_and_out: 666dput_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);
701out: 703out:
702 return error; 704 return error;
703} 705}
@@ -970,7 +972,7 @@ out:
970 972
971EXPORT_SYMBOL(get_unused_fd); 973EXPORT_SYMBOL(get_unused_fd);
972 974
973static inline void __put_unused_fd(struct files_struct *files, unsigned int fd) 975static 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);