acct: switch to __kernel_write()
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 19 Apr 2014 18:37:20 +0000 (14:37 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 7 Aug 2014 18:40:07 +0000 (14:40 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/internal.h
include/linux/fs.h
kernel/acct.c

index 4657424..9a2edba 100644 (file)
@@ -131,7 +131,6 @@ extern long prune_dcache_sb(struct super_block *sb, unsigned long nr_to_scan,
 /*
  * read_write.c
  */
-extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
 extern int rw_verify_area(int, struct file *, const loff_t *, size_t);
 
 /*
index e11d60c..4b7d57c 100644 (file)
@@ -2335,6 +2335,7 @@ extern int do_pipe_flags(int *, int);
 
 extern int kernel_read(struct file *, loff_t, char *, unsigned long);
 extern ssize_t kernel_write(struct file *, const char *, size_t, loff_t);
+extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
 extern struct file * open_exec(const char *);
  
 /* fs/dcache.c -- generic fs support functions */
index 807ebc5..8082d98 100644 (file)
@@ -456,12 +456,16 @@ static void do_acct_process(struct bsd_acct_struct *acct,
 {
        struct pacct_struct *pacct = &current->signal->pacct;
        acct_t ac;
-       mm_segment_t fs;
        unsigned long flim;
        u64 elapsed, run_time;
        struct tty_struct *tty;
        const struct cred *orig_cred;
 
+       /*
+        * Accounting records are not subject to resource limits.
+        */
+       flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
+       current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
        /* Perform file operations on behalf of whoever enabled accounting */
        orig_cred = override_creds(file->f_cred);
 
@@ -536,25 +540,14 @@ static void do_acct_process(struct bsd_acct_struct *acct,
         * Get freeze protection. If the fs is frozen, just skip the write
         * as we could deadlock the system otherwise.
         */
-       if (!file_start_write_trylock(file))
-               goto out;
-       /*
-        * Kernel segment override to datasegment and write it
-        * to the accounting file.
-        */
-       fs = get_fs();
-       set_fs(KERNEL_DS);
-       /*
-        * Accounting records are not subject to resource limits.
-        */
-       flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
-       current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
-       file->f_op->write(file, (char *)&ac,
-                              sizeof(acct_t), &file->f_pos);
-       current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
-       set_fs(fs);
-       file_end_write(file);
+       if (file_start_write_trylock(file)) {
+               /* it's been opened O_APPEND, so position is irrelevant */
+               loff_t pos = 0;
+               __kernel_write(file, (char *)&ac, sizeof(acct_t), &pos);
+               file_end_write(file);
+       }
 out:
+       current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
        revert_creds(orig_cred);
 }