Commit cc4e69de authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Linus Torvalds

[PATCH] VFS: pass file pointer to filesystem from ftruncate()

This patch extends the iattr structure with a file pointer memeber, and adds
an ATTR_FILE validity flag for this member.

This is set if do_truncate() is invoked from ftruncate() or from
do_coredump().

The change is source and binary compatible.
Signed-off-by: default avatarMiklos Szeredi <miklos@szeredi.hu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 481bed45
...@@ -1511,7 +1511,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) ...@@ -1511,7 +1511,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
goto close_fail; goto close_fail;
if (!file->f_op->write) if (!file->f_op->write)
goto close_fail; goto close_fail;
if (do_truncate(file->f_dentry, 0) != 0) if (do_truncate(file->f_dentry, 0, file) != 0)
goto close_fail; goto close_fail;
retval = binfmt->core_dump(signr, regs, file); retval = binfmt->core_dump(signr, regs, file);
......
...@@ -1459,7 +1459,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) ...@@ -1459,7 +1459,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
if (!error) { if (!error) {
DQUOT_INIT(inode); DQUOT_INIT(inode);
error = do_truncate(dentry, 0); error = do_truncate(dentry, 0, NULL);
} }
put_write_access(inode); put_write_access(inode);
if (error) if (error)
......
...@@ -194,7 +194,7 @@ out: ...@@ -194,7 +194,7 @@ out:
return error; return error;
} }
int do_truncate(struct dentry *dentry, loff_t length) int do_truncate(struct dentry *dentry, loff_t length, struct file *filp)
{ {
int err; int err;
struct iattr newattrs; struct iattr newattrs;
...@@ -205,6 +205,10 @@ int do_truncate(struct dentry *dentry, loff_t length) ...@@ -205,6 +205,10 @@ int do_truncate(struct dentry *dentry, loff_t length)
newattrs.ia_size = length; newattrs.ia_size = length;
newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
if (filp) {
newattrs.ia_file = filp;
newattrs.ia_valid |= ATTR_FILE;
}
down(&dentry->d_inode->i_sem); down(&dentry->d_inode->i_sem);
err = notify_change(dentry, &newattrs); err = notify_change(dentry, &newattrs);
...@@ -262,7 +266,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length) ...@@ -262,7 +266,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length)
error = locks_verify_truncate(inode, NULL, length); error = locks_verify_truncate(inode, NULL, length);
if (!error) { if (!error) {
DQUOT_INIT(inode); DQUOT_INIT(inode);
error = do_truncate(nd.dentry, length); error = do_truncate(nd.dentry, length, NULL);
} }
put_write_access(inode); put_write_access(inode);
...@@ -314,7 +318,7 @@ static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small) ...@@ -314,7 +318,7 @@ static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
error = locks_verify_truncate(inode, file, length); error = locks_verify_truncate(inode, file, length);
if (!error) if (!error)
error = do_truncate(dentry, length); error = do_truncate(dentry, length, file);
out_putf: out_putf:
fput(file); fput(file);
out: out:
......
...@@ -264,6 +264,7 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, ...@@ -264,6 +264,7 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
#define ATTR_ATTR_FLAG 1024 #define ATTR_ATTR_FLAG 1024
#define ATTR_KILL_SUID 2048 #define ATTR_KILL_SUID 2048
#define ATTR_KILL_SGID 4096 #define ATTR_KILL_SGID 4096
#define ATTR_FILE 8192
/* /*
* This is the Inode Attributes structure, used for notify_change(). It * This is the Inode Attributes structure, used for notify_change(). It
...@@ -283,6 +284,13 @@ struct iattr { ...@@ -283,6 +284,13 @@ struct iattr {
struct timespec ia_atime; struct timespec ia_atime;
struct timespec ia_mtime; struct timespec ia_mtime;
struct timespec ia_ctime; struct timespec ia_ctime;
/*
* Not an attribute, but an auxilary info for filesystems wanting to
* implement an ftruncate() like method. NOTE: filesystem should
* check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL).
*/
struct file *ia_file;
}; };
/* /*
...@@ -1288,7 +1296,7 @@ static inline int break_lease(struct inode *inode, unsigned int mode) ...@@ -1288,7 +1296,7 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
/* fs/open.c */ /* fs/open.c */
extern int do_truncate(struct dentry *, loff_t start); extern int do_truncate(struct dentry *, loff_t start, struct file *filp);
extern long do_sys_open(const char __user *filename, int flags, int mode); extern long do_sys_open(const char __user *filename, int flags, int mode);
extern struct file *filp_open(const char *, int, int); extern struct file *filp_open(const char *, int, int);
extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment