aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/exec.c2
-rw-r--r--fs/namei.c2
-rw-r--r--fs/open.c10
-rw-r--r--include/linux/fs.h10
4 files changed, 18 insertions, 6 deletions
diff --git a/fs/exec.c b/fs/exec.c
index ce76b33f25ac..cd6c574557dc 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1511,7 +1511,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
1511 goto close_fail; 1511 goto close_fail;
1512 if (!file->f_op->write) 1512 if (!file->f_op->write)
1513 goto close_fail; 1513 goto close_fail;
1514 if (do_truncate(file->f_dentry, 0) != 0) 1514 if (do_truncate(file->f_dentry, 0, file) != 0)
1515 goto close_fail; 1515 goto close_fail;
1516 1516
1517 retval = binfmt->core_dump(signr, regs, file); 1517 retval = binfmt->core_dump(signr, regs, file);
diff --git a/fs/namei.c b/fs/namei.c
index c5769c4fcab1..b3f8a1966c9c 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1459,7 +1459,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1459 if (!error) { 1459 if (!error) {
1460 DQUOT_INIT(inode); 1460 DQUOT_INIT(inode);
1461 1461
1462 error = do_truncate(dentry, 0); 1462 error = do_truncate(dentry, 0, NULL);
1463 } 1463 }
1464 put_write_access(inode); 1464 put_write_access(inode);
1465 if (error) 1465 if (error)
diff --git a/fs/open.c b/fs/open.c
index 2835f096c683..6e8136751e9a 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -194,7 +194,7 @@ out:
194 return error; 194 return error;
195} 195}
196 196
197int do_truncate(struct dentry *dentry, loff_t length) 197int 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);
318out_putf: 322out_putf:
319 fput(file); 323 fput(file);
320out: 324out:
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6d6226732c93..0c89fc9481a8 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -264,6 +264,7 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
264#define ATTR_ATTR_FLAG 1024 264#define ATTR_ATTR_FLAG 1024
265#define ATTR_KILL_SUID 2048 265#define ATTR_KILL_SUID 2048
266#define ATTR_KILL_SGID 4096 266#define ATTR_KILL_SGID 4096
267#define ATTR_FILE 8192
267 268
268/* 269/*
269 * This is the Inode Attributes structure, used for notify_change(). It 270 * This is the Inode Attributes structure, used for notify_change(). It
@@ -283,6 +284,13 @@ struct iattr {
283 struct timespec ia_atime; 284 struct timespec ia_atime;
284 struct timespec ia_mtime; 285 struct timespec ia_mtime;
285 struct timespec ia_ctime; 286 struct timespec ia_ctime;
287
288 /*
289 * Not an attribute, but an auxilary info for filesystems wanting to
290 * implement an ftruncate() like method. NOTE: filesystem should
291 * check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL).
292 */
293 struct file *ia_file;
286}; 294};
287 295
288/* 296/*
@@ -1288,7 +1296,7 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
1288 1296
1289/* fs/open.c */ 1297/* fs/open.c */
1290 1298
1291extern int do_truncate(struct dentry *, loff_t start); 1299extern int do_truncate(struct dentry *, loff_t start, struct file *filp);
1292extern long do_sys_open(const char __user *filename, int flags, int mode); 1300extern long do_sys_open(const char __user *filename, int flags, int mode);
1293extern struct file *filp_open(const char *, int, int); 1301extern struct file *filp_open(const char *, int, int);
1294extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); 1302extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);