Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -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);
+1 −1
Original line number Original line Diff line number Diff line
@@ -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)
+7 −3
Original line number Original line Diff line number Diff line
@@ -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:
+9 −1
Original line number Original line Diff line number Diff line
@@ -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);