[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: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
481bed4542
commit
cc4e69dee4
4 changed files with 18 additions and 6 deletions
|
@ -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)
|
||||||
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)
|
||||||
|
|
10
fs/open.c
10
fs/open.c
|
@ -194,7 +194,7 @@ asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz, struct statfs64 __user
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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,
|
||||||
#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 {
|
||||||
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)
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
Loading…
Reference in a new issue