diff options
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 19 |
1 files changed, 15 insertions, 4 deletions
@@ -194,7 +194,7 @@ out: | |||
194 | return error; | 194 | return error; |
195 | } | 195 | } |
196 | 196 | ||
197 | int do_truncate(struct dentry *dentry, loff_t length) | 197 | int do_truncate(struct dentry *dentry, loff_t length, struct file *filp) |
198 | { | 198 | { |
199 | int err; | 199 | int err; |
200 | struct iattr newattrs; | 200 | struct iattr newattrs; |
@@ -205,6 +205,10 @@ int do_truncate(struct dentry *dentry, loff_t length) | |||
205 | 205 | ||
206 | newattrs.ia_size = length; | 206 | newattrs.ia_size = length; |
207 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; | 207 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; |
208 | if (filp) { | ||
209 | newattrs.ia_file = filp; | ||
210 | newattrs.ia_valid |= ATTR_FILE; | ||
211 | } | ||
208 | 212 | ||
209 | down(&dentry->d_inode->i_sem); | 213 | down(&dentry->d_inode->i_sem); |
210 | err = notify_change(dentry, &newattrs); | 214 | err = notify_change(dentry, &newattrs); |
@@ -262,7 +266,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length) | |||
262 | error = locks_verify_truncate(inode, NULL, length); | 266 | error = locks_verify_truncate(inode, NULL, length); |
263 | if (!error) { | 267 | if (!error) { |
264 | DQUOT_INIT(inode); | 268 | DQUOT_INIT(inode); |
265 | error = do_truncate(nd.dentry, length); | 269 | error = do_truncate(nd.dentry, length, NULL); |
266 | } | 270 | } |
267 | put_write_access(inode); | 271 | put_write_access(inode); |
268 | 272 | ||
@@ -314,7 +318,7 @@ static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small) | |||
314 | 318 | ||
315 | error = locks_verify_truncate(inode, file, length); | 319 | error = locks_verify_truncate(inode, file, length); |
316 | if (!error) | 320 | if (!error) |
317 | error = do_truncate(dentry, length); | 321 | error = do_truncate(dentry, length, file); |
318 | out_putf: | 322 | out_putf: |
319 | fput(file); | 323 | fput(file); |
320 | out: | 324 | out: |
@@ -887,6 +891,10 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags) | |||
887 | return filp; | 891 | return filp; |
888 | } | 892 | } |
889 | 893 | ||
894 | /* | ||
895 | * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an | ||
896 | * error. | ||
897 | */ | ||
890 | struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) | 898 | struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) |
891 | { | 899 | { |
892 | int error; | 900 | int error; |
@@ -894,8 +902,11 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) | |||
894 | 902 | ||
895 | error = -ENFILE; | 903 | error = -ENFILE; |
896 | f = get_empty_filp(); | 904 | f = get_empty_filp(); |
897 | if (f == NULL) | 905 | if (f == NULL) { |
906 | dput(dentry); | ||
907 | mntput(mnt); | ||
898 | return ERR_PTR(error); | 908 | return ERR_PTR(error); |
909 | } | ||
899 | 910 | ||
900 | return __dentry_open(dentry, mnt, flags, f, NULL); | 911 | return __dentry_open(dentry, mnt, flags, f, NULL); |
901 | } | 912 | } |