Date: 1 Mar 1998 05:08:07 GMT2.1.89pre5
authorLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:14:50 +0000 (23 15:14 -0500)
committerLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:14:50 +0000 (23 15:14 -0500)
Subject: Re: INN doesn't work on pre-2.1.89-4 (mmap problem ?)
From: Linus Torvalds <torvalds@transmeta.com>

I fixed _one_ silly bug wrt writeback to shared files in pre-5

15 files changed:
fs/binfmt_elf.c
fs/coda/file.c
fs/dquot.c
fs/fat/mmap.c
fs/ncpfs/inode.c
fs/proc/array.c
fs/romfs/inode.c
fs/smbfs/inode.c
fs/smbfs/sock.c
include/linux/fs.h
include/linux/msdos_fs.h
include/linux/ufs_fs.h
kernel/acct.c
kernel/ksyms.c
mm/filemap.c

index aeac9e8..50f071f 100644 (file)
@@ -807,6+807,7 @@ do_load_elf_library(int fd)
        unsigned long elf_bss = 0, bss, len, k;
        int retval, error, i, j;
        struct elfhdr elf_ex;
+       loff_t offset = 0;
 
        error = -EACCES;
        file = fget(fd);
@@ -817,17+818,10 @@ do_load_elf_library(int fd)
 
        /* seek to the beginning of the file */
        error = -ENOEXEC;
-       if (file->f_op->llseek) {
-               retval = file->f_op->llseek(file, 0, 0);
-               if (retval != 0)
-                       goto out_putf;
-       } else
-               file->f_pos = 0;
 
        /* N.B. save current DS?? */
        set_fs(KERNEL_DS);
-       retval = file->f_op->read(file, (char *) &elf_ex,
-                                sizeof(elf_ex), &file->f_pos);
+       retval = file->f_op->read(file, (char *) &elf_ex, sizeof(elf_ex), &offset);
        set_fs(USER_DS);
        if (retval != sizeof(elf_ex))
                goto out_putf;
index a40771a..ca8a4a0 100644 (file)
 #include <linux/coda_cache.h>
 
 /* file operations */
-static int coda_readpage(struct dentry * dentry, struct page * page);
+static int coda_readpage(struct file *file, struct page * page);
 static ssize_t coda_file_read(struct file *f, char *buf, size_t count, loff_t *off);
 static ssize_t coda_file_write(struct file *f, const char *buf, size_t count, loff_t *off);
 static int coda_file_mmap(struct file * file, struct vm_area_struct * vma);
@@ -74,8+74,9 @@ struct file_operations coda_file_operations = {
 };
 
 /*  File file operations */
-static int coda_readpage(struct dentry *de, struct page * page)
+static int coda_readpage(struct file * file, struct page * page)
 {
+       struct dentry *de = file->f_dentry;
        struct inode *inode = de->d_inode;
        struct dentry cont_dentry;
         struct inode *cont_inode;
index 6dbdc56..2cb31a4 100644 (file)
@@ -938,7+938,7 @@ int quota_off(kdev_t dev, short type)
                vfsmnt->mnt_sb->dq_op = (struct dquot_operations *)NULL;
                reset_dquot_ptrs(dev, cnt);
                invalidate_dquots(dev, cnt);
-               close_fp(vfsmnt->mnt_quotas[cnt]);
+               fput(vfsmnt->mnt_quotas[cnt]);
                vfsmnt->mnt_quotas[cnt] = (struct file *)NULL;
                vfsmnt->mnt_iexp[cnt] = vfsmnt->mnt_bexp[cnt] = (time_t)NULL;
        }
index 886b20c..448437e 100644 (file)
@@ -119,8+119,9 @@ int fat_mmap(struct file * file, struct vm_area_struct * vma)
 }
 
 
-int fat_readpage(struct dentry * dentry, struct page * page)
+int fat_readpage(struct file *file, struct page * page)
 {
+       struct dentry * dentry = file->f_dentry;
        struct inode * inode = dentry->d_inode;
        if (MSDOS_SB(inode->i_sb)->cvf_format &&
            MSDOS_SB(inode->i_sb)->cvf_format->cvf_readpage)
index f70374e..3a98b65 100644 (file)
 #include <linux/ncp_fs.h>
 #include "ncplib_kernel.h"
 
-extern int close_fp(struct file *filp);
-
 static void ncp_read_inode(struct inode *);
 static void ncp_put_inode(struct inode *);
 static void ncp_delete_inode(struct inode *);
@@ -353,7+351,7 @@ static void ncp_put_super(struct super_block *sb)
        ncp_disconnect(server);
        ncp_unlock_server(server);
 
-       close_fp(server->ncp_filp);
+       fput(server->ncp_filp);
        kill_proc(server->m.wdog_pid, SIGTERM, 1);
 
        ncp_kfree_s(server->packet, server->packet_size);
index 530b21d..d88a3ce 100644 (file)
@@ -610,30+610,42 @@ static inline char * task_name(struct task_struct *p, char * buf)
        return buf+1;
 }
 
-static inline char * task_state(struct task_struct *p, char *buffer)
+static const char *task_state_array[] = {
+       ". Huh?",
+       "R (running)",
+       "S (sleeping)",
+       "D (disk sleep)",
+       "Z (zombie)",
+       "T (stopped)",
+       "W (paging)"
+};
+
+static inline const char * get_task_state(struct task_struct *tsk)
 {
-#define NR_STATES (sizeof(states)/sizeof(const char *))
-       unsigned int n = p->state;
-       static const char * states[] = {
-               "R (running)",
-               "S (sleeping)",
-               "D (disk sleep)",
-               "Z (zombie)",
-               "T (stopped)",
-               "W (paging)",
-               ". Huh?"
-       };
-
-       if (n >= NR_STATES)
-               n = NR_STATES-1;
+       unsigned int state = tsk->state & (TASK_RUNNING |
+                                          TASK_INTERRUPTIBLE |
+                                          TASK_UNINTERRUPTIBLE |
+                                          TASK_ZOMBIE |
+                                          TASK_STOPPED |
+                                          TASK_SWAPPING);
+       const char **p = &task_state_array[0];
+
+       while (state) {
+               p++;
+               state >>= 1;
+       }
+       return *p;
+}
 
+static inline char * task_state(struct task_struct *p, char *buffer)
+{
        buffer += sprintf(buffer,
                "State:\t%s\n"
                "Pid:\t%d\n"
                "PPid:\t%d\n"
                "Uid:\t%d\t%d\t%d\t%d\n"
                "Gid:\t%d\t%d\t%d\t%d\n",
-               states[n],
+               get_task_state(p),
                p->pid, p->p_pptr->pid,
                p->uid, p->euid, p->suid, p->fsuid,
                p->gid, p->egid, p->sgid, p->fsgid);
@@ -769,10+781,7 @@ static int get_stat(int pid, char * buffer)
 
        if (!tsk)
                return 0;
-       if (tsk->state < 0 || tsk->state > 5)
-               state = '.';
-       else
-               state = "RSDZTW"[tsk->state];
+       state = *get_task_state(tsk);
        vsize = eip = esp = 0;
        if (tsk->mm && tsk->mm != &init_mm) {
                struct vm_area_struct *vma = tsk->mm->mmap;
index 66f52d6..bc3a116 100644 (file)
@@ -390,8+390,9 @@ out:
  */
 
 static int
-romfs_readpage(struct dentry * dentry, struct page * page)
+romfs_readpage(struct file * file, struct page * page)
 {
+       struct dentry *dentry = file->f_dentry;
        struct inode *inode = dentry->d_inode;
        unsigned long buf;
        unsigned long offset, avail, readlen;
index 9648c11..0264cee 100644 (file)
 #include <linux/locks.h>
 #include <linux/malloc.h>
 #include <linux/init.h>
+#include <linux/file.h>
 #include <linux/dcache.h>
 
 #include <linux/smb_fs.h>
@@ -326,7+327,7 @@ smb_put_super(struct super_block *sb)
        if (server->sock_file) {
                smb_proc_disconnect(server);
                smb_dont_catch_keepalive(server);
-               close_fp(server->sock_file);
+               fput(server->sock_file);
        }
 
        if (server->conn_pid)
index 0803a48..5d8ddc9 100644 (file)
 #include <linux/errno.h>
 #include <linux/socket.h>
 #include <linux/fcntl.h>
+#include <linux/file.h>
 #include <linux/in.h>
 #include <linux/net.h>
 #include <linux/mm.h>
@@ -259,7+260,7 @@ if (server_sock(server)->sk->data_ready == smb_data_callback)
 printk("smb_close_socket: still catching keepalives!\n");
 #endif
                server->sock_file = NULL;
-               close_fp(file);
+               fput(file);
        }
 }
 
index dc1389a..25c4c60 100644 (file)
@@ -422,6+422,8 @@ extern int init_private_file(struct file *, struct dentry *, int);
  * The POSIX file lock owner is determined by
  * the "struct files_struct" in the thread group
  * (or NULL for no owner - BSD locks).
+ *
+ * Lockd stuffs a "host" pointer into this.
  */
 typedef struct files_struct *fl_owner_t;
 
index 24b39ab..bcf4d01 100644 (file)
@@ -255,7+255,7 @@ extern void fat_truncate(struct inode *inode);
 
 /* mmap.c */
 extern int fat_mmap(struct file *, struct vm_area_struct *);
-extern int fat_readpage(struct dentry *, struct page *);
+extern int fat_readpage(struct file *, struct page *);
 
 
 /* vfat.c */
index f14f479..78b3364 100644 (file)
@@ -294,12+294,12 @@ struct ufs_inode {
                } ui_addr;
                __u8    ui_symlink[4*(UFS_NDADDR+UFS_NINDIR)];/* 0x28 fast symlink */
        } ui_u2;
-       __u32   ui_flags;               /* 0x64 unused -- "status flags (chflags)" ??? */
+       __u32   ui_flags;               /* 0x64 immutable, append-only... */
        __u32   ui_blocks;              /* 0x68 blocks in use */
-       __u32   ui_gen;                 /* 0x6c generation number XXX - what is this? */
+       __u32   ui_gen;                 /* 0x6c like ext2 i_version, for NFS support */
        union {
                struct {
-                       __u32   ui_shadow;/* 0x70 shadow inode XXX - what is this?*/
+                       __u32   ui_shadow;/* 0x70 shadow inode with security data */
                        __u32   ui_uid; /* 0x74 long EFT version of uid */
                        __u32   ui_gid; /* 0x78 long EFT version of gid */
                        __u32   ui_oeftflag;/* 0x7c reserved */
@@ -318,6+318,22 @@ struct ufs_inode {
                } ui_hurd;
        } ui_u3;
 };
+
+/* FreeBSD has these in sys/stat.h */
+/* ui_flags that can be set by a file owner */
+#define UFS_UF_SETTABLE   0x0000ffff
+#define UFS_UF_NODUMP     0x00000001  /* do not dump */
+#define UFS_UF_IMMUTABLE  0x00000002  /* immutable (can't "change") */
+#define UFS_UF_APPEND     0x00000004  /* append-only */
+#define UFS_UF_OPAQUE     0x00000008  /* directory is opaque (unionfs) */
+#define UFS_UF_NOUNLINK   0x00000010  /* can't be removed or renamed */
+/* ui_flags that only root can set */
+#define UFS_SF_SETTABLE   0xffff0000
+#define UFS_SF_ARCHIVED   0x00010000  /* archived */
+#define UFS_SF_IMMUTABLE  0x00020000  /* immutable (can't "change") */
+#define UFS_SF_APPEND     0x00040000  /* append-only */
+#define UFS_SF_NOUNLINK   0x00100000  /* can't be removed or renamed */
+    
  
 #ifdef __KERNEL__
 /*
index 08e8eb8..4229b9e 100644 (file)
 #include <linux/major.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/file.h>
 
 #include <asm/uaccess.h>
 
 /*
  * External references and all of the globals.
  */
-extern int close_fp(struct file *);
-
 void acct_timeout(unsigned long);
 
 static volatile int acct_active = 0;
@@ -129,7+128,7 @@ asmlinkage int sys_acct(const char *name)
                        del_timer(&acct_timer);
                        acct_active = 0;
                        acct_needcheck = 0;
-                       close_fp(acct_file);
+                       fput(acct_file);
                }
                error = 0;
                goto out;
index 3c7ba00..ea8f439 100644 (file)
@@ -154,7+154,6 @@ EXPORT_SYMBOL(__namei);
 EXPORT_SYMBOL(lookup_dentry);
 EXPORT_SYMBOL(open_namei);
 EXPORT_SYMBOL(sys_close);
-EXPORT_SYMBOL(close_fp);
 EXPORT_SYMBOL(d_alloc_root);
 EXPORT_SYMBOL(d_delete);
 EXPORT_SYMBOL(d_validate);
index 019a55c..ab3382f 100644 (file)
@@ -910,6+910,7 @@ static inline int do_write_page(struct inode * inode, struct file * file,
 {
        int retval;
        unsigned long size;
+       loff_t loff = offset;
        mm_segment_t old_fs;
 
        size = offset + PAGE_SIZE;
@@ -925,8+926,7 @@ static inline int do_write_page(struct inode * inode, struct file * file,
        old_fs = get_fs();
        set_fs(KERNEL_DS);
        retval = -EIO;
-       if (size == file->f_op->write(file, (const char *) page,
-                                     size, &file->f_pos))
+       if (size == file->f_op->write(file, (const char *) page, size, &loff))
                retval = 0;
        set_fs(old_fs);
        return retval;
close