[PATCH] VFS: pass file pointer to filesystem from ftruncate()
authorMiklos Szeredi <miklos@szeredi.hu>
Mon, 7 Nov 2005 08:59:49 +0000 (00:59 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 7 Nov 2005 15:53:42 +0000 (07:53 -0800)
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>
fs/exec.c
fs/namei.c
fs/open.c
include/linux/fs.h

index ce76b33..cd6c574 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1511,7 +1511,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
                goto close_fail;
        if (!file->f_op->write)
                goto close_fail;
-       if (do_truncate(file->f_dentry, 0) != 0)
+       if (do_truncate(file->f_dentry, 0, file) != 0)
                goto close_fail;
 
        retval = binfmt->core_dump(signr, regs, file);
index c5769c4..b3f8a19 100644 (file)
@@ -1459,7 +1459,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
                if (!error) {
                        DQUOT_INIT(inode);
                        
-                       error = do_truncate(dentry, 0);
+                       error = do_truncate(dentry, 0, NULL);
                }
                put_write_access(inode);
                if (error)
index 2835f09..6e81367 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -194,7 +194,7 @@ out:
        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;
        struct iattr newattrs;
@@ -205,6 +205,10 @@ int do_truncate(struct dentry *dentry, loff_t length)
 
        newattrs.ia_size = length;
        newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+       if (filp) {
+               newattrs.ia_file = filp;
+               newattrs.ia_valid |= ATTR_FILE;
+       }
 
        down(&dentry->d_inode->i_sem);
        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);
        if (!error) {
                DQUOT_INIT(inode);
-               error = do_truncate(nd.dentry, length);
+               error = do_truncate(nd.dentry, length, NULL);
        }
        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);
        if (!error)
-               error = do_truncate(dentry, length);
+               error = do_truncate(dentry, length, file);
 out_putf:
        fput(file);
 out:
index 6d62267..0c89fc9 100644 (file)
@@ -264,6 +264,7 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 #define ATTR_ATTR_FLAG 1024
 #define ATTR_KILL_SUID 2048
 #define ATTR_KILL_SGID 4096
+#define ATTR_FILE      8192
 
 /*
  * This is the Inode Attributes structure, used for notify_change().  It
@@ -283,6 +284,13 @@ struct iattr {
        struct timespec ia_atime;
        struct timespec ia_mtime;
        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 */
 
-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 struct file *filp_open(const char *, int, int);
 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);