]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.45pre7 2.1.45pre7
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:32 +0000 (15:13 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:32 +0000 (15:13 -0500)
fs/autofs/inode.c
fs/autofs/root.c
fs/dcache.c
fs/ext2/ialloc.c
fs/inode.c
fs/namei.c
fs/super.c
include/linux/dcache.h
include/linux/fs.h
kernel/ksyms.c

index 58997a0610bdc17c057bd00986d6359167917379..be152d06e1fd8ee6d26a86904e38880b49ed63bc 100644 (file)
@@ -173,7 +173,7 @@ struct super_block *autofs_read_super(struct super_block *s, void *data,
        }
 
        if ( parse_options(data,&pipefd,&s->s_root->d_inode->i_uid,&s->s_root->d_inode->i_gid,&sbi->oz_pgrp,&minproto,&maxproto) ) {
-               d_delete(s->s_root);
+               dput(s->s_root);
                s->s_dev = 0;
                kfree(sbi);
                printk("autofs: called with bogus options\n");
@@ -182,7 +182,7 @@ struct super_block *autofs_read_super(struct super_block *s, void *data,
        }
 
        if ( minproto > AUTOFS_PROTO_VERSION || maxproto < AUTOFS_PROTO_VERSION ) {
-               d_delete(s->s_root);
+               dput(s->s_root);
                s->s_dev = 0;
                kfree(sbi);
                printk("autofs: kernel does not match daemon version\n");
@@ -199,7 +199,7 @@ struct super_block *autofs_read_super(struct super_block *s, void *data,
                } else {
                        printk("autofs: could not open pipe file descriptor\n");
                }
-               d_delete(s->s_root);
+               dput(s->s_root);
                s->s_dev = 0;
                kfree(sbi);
                MOD_DEC_USE_COUNT;
index 5c2c42b08531c74659eb721aa2612460038b89c8..41104a9ea0c7d082f74028e1587abea01fcb5577 100644 (file)
@@ -213,6 +213,17 @@ static int autofs_root_symlink(struct inode *dir, struct dentry *dentry, const c
        return 0;
 }
 
+/*
+ * NOTE!
+ *
+ * Normal filesystems would do a "d_delete()" to tell the VFS dcache
+ * that the file no longer exists. However, doing that means that the
+ * VFS layer can turn the dentry into a negative dentry, which we
+ * obviously do not want (we're dropping the entry not because it
+ * doesn't exist, but because it has timed out).
+ *
+ * Also see autofs_root_rmdir()..
+ */
 static int autofs_root_unlink(struct inode *dir, struct dentry *dentry)
 {
        struct autofs_sb_info *sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
@@ -234,7 +245,7 @@ static int autofs_root_unlink(struct inode *dir, struct dentry *dentry)
        autofs_hash_delete(ent);
        clear_bit(n,sbi->symlink_bitmap);
        kfree(sbi->symlink[n].data);
-       d_delete(dentry);
+       d_drop(dentry);
        
        return 0;
 }
@@ -257,7 +268,7 @@ static int autofs_root_rmdir(struct inode *dir, struct dentry *dentry)
 
        autofs_hash_delete(ent);
        dir->i_nlink--;
-       d_delete(dentry);
+       d_drop(dentry);
 
        return 0;
 }
index a141eefe8048f01a7636cd3b34a8f5d4faed238f..395aed829c993163d60d6e5afe18f6039347ca62 100644 (file)
@@ -158,6 +158,7 @@ struct dentry * d_alloc(struct dentry * parent, const struct qstr *name)
        dentry->d_name.name = str;
        dentry->d_name.len = name->len;
        dentry->d_name.hash = name->hash;
+       dentry->d_revalidate = NULL;
        return dentry;
 }
 
@@ -239,6 +240,7 @@ static inline void d_remove_from_parent(struct dentry * dentry, struct dentry *
        dput(parent);
 }
 
+
 /*
  * When a file is deleted, we have two options:
  * - turn this dentry into a negative dentry
@@ -266,12 +268,10 @@ void d_delete(struct dentry * dentry)
        }
 
        /*
-        * If not, just unhash us and wait for dput()
-        * to pick up the tab..
+        * If not, just drop the dentry and let dput
+        * pick up the tab..
         */
-       list_del(&dentry->d_hash);
-       INIT_LIST_HEAD(&dentry->d_hash);
-
+       d_drop(dentry);
 }
 
 void d_add(struct dentry * entry, struct inode * inode)
index f192072923e4676d3213d354cdc603e5759d3c59..3feac5bd81d304a88b885f9b3701502018ff75b5 100644 (file)
@@ -216,7 +216,6 @@ void ext2_free_inode (struct inode * inode)
                es->s_free_inodes_count =
                        cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) + 1);
                mark_buffer_dirty(sb->u.ext2_sb.s_sbh, 1);
-               mark_inode_dirty(inode);
        }
        mark_buffer_dirty(bh, 1);
        if (sb->s_flags & MS_SYNCHRONOUS) {
index 6602de949e92e711ef56bae67b718d90a3514141..22a96ff17a971b8cd646bd9bd3a47b92b23952e3 100644 (file)
@@ -319,32 +319,34 @@ struct inode * get_empty_inode(void)
 {
        static unsigned long last_ino = 0;
        struct inode * inode;
-       struct list_head * tmp = inode_unused.next;
+       struct list_head * tmp;
 
+       spin_lock(&inode_lock);
+       tmp = inode_unused.next;
        if (tmp != &inode_unused) {
                list_del(tmp);
                inode = list_entry(tmp, struct inode, i_list);
 add_new_inode:
-               INIT_LIST_HEAD(&inode->i_list);
                INIT_LIST_HEAD(&inode->i_hash);
                inode->i_sb = NULL;
                inode->i_ino = ++last_ino;
                atomic_set(&inode->i_count, 1);
+               list_add(&inode->i_list, &inode_in_use);
                inode->i_state = 0;
+               spin_unlock(&inode_lock);
                clean_inode(inode);
                return inode;
        }
 
        /*
         * Warning: if this succeeded, we will now
-        * return with the inode lock, and we need to 
-        * unlock it.
+        * return with the inode lock.
         */
+       spin_unlock(&inode_lock);
        inode = grow_inodes();
-       if (inode) {
-               spin_unlock(&inode_lock);
+       if (inode)
                goto add_new_inode;
-       }
+
        return inode;
 }
 
@@ -368,6 +370,13 @@ struct inode * get_pipe_inode(void)
                        PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
                        PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
                        PIPE_LOCK(*inode) = 0;
+                       /*
+                        * Mark the inode dirty from the very beginning,
+                        * that way it will never be moved to the dirty
+                        * list because "make_inode_dirty()" will think
+                        * that it already _is_ on the dirty list.
+                        */
+                       inode->i_state = 1 << I_DIRTY;
                        inode->i_pipe = 1;
                        inode->i_mode |= S_IFIFO | S_IRUSR | S_IWUSR;
                        inode->i_uid = current->fsuid;
@@ -465,6 +474,12 @@ void iput(struct inode *inode)
                 */
                if (atomic_read(&inode->i_count) == 1) {
                        void (*put)(struct inode *);
+
+                       if (inode->i_pipe) {
+                               free_page((unsigned long)PIPE_BASE(*inode));
+                               PIPE_BASE(*inode)= NULL;
+                       }
+
                        if (inode->i_sb && inode->i_sb->s_op) {
                                put = inode->i_sb->s_op->put_inode;
                                if (put)
@@ -507,13 +522,13 @@ int fs_may_mount(kdev_t dev)
        return 1;
 }
 
-int fs_may_umount(kdev_t dev, struct dentry * root)
+int fs_may_umount(struct super_block *sb, struct dentry * root)
 {
        shrink_dcache();
        return root->d_count == 1;
 }
 
-int fs_may_remount_ro(kdev_t dev)
+int fs_may_remount_ro(struct super_block *sb)
 {
-       return 0;
+       return 1;
 }
index 173a399bcee5c8214100ba28d6c6878cfc153ca8..3c0dbdc16df9698c01450f3a8fd92dbfe5f0b2bf 100644 (file)
@@ -280,15 +280,8 @@ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name)
        struct dentry * dentry = d_lookup(parent, name);
 
        if (dentry) {
-               /*
-                *   FIXME!   We should have something like
-
-               dentry = dentry->revalidate(dentry);
-
-                * here - we need to ask the low-level filesystem permission
-                * to use the cached entry (NFS needs to time them out, and
-                * /proc might go away etc).
-                */
+               if (dentry->d_revalidate)
+                       dentry = dentry->d_revalidate(dentry);
 
                /*
                 * The parent d_count _should_ be at least 2: one for the
index 718b6f9059b69cf5226254430026da4fd2de6de4..f880ad37b396ee80681ed1a48ac372b29fcce8c1 100644 (file)
@@ -611,7 +611,7 @@ static int do_umount(kdev_t dev,int unmount_root)
         * too bad there are no quotas running anymore. Turn them on again by hand.
         */
        quota_off(dev, -1);
-       if (!fs_may_umount(dev, sb->s_root))
+       if (!fs_may_umount(sb, sb->s_root))
                return -EBUSY;
 
        /* clean up dcache .. */
@@ -785,7 +785,7 @@ static int do_remount_sb(struct super_block *sb, int flags, char *data)
                /*flags |= MS_RDONLY;*/
        /* If we are remounting RDONLY, make sure there are no rw files open */
        if ((flags & MS_RDONLY) && !(sb->s_flags & MS_RDONLY))
-               if (!fs_may_remount_ro(sb->s_dev))
+               if (!fs_may_remount_ro(sb))
                        return -EBUSY;
        sb->s_flags = (flags & ~MS_RDONLY) | (sb->s_flags & MS_RDONLY);
        if (sb->s_op && sb->s_op->remount_fs) {
index 5664bfb0fdf6b82ec0250800774c0ea4b7b27b92..51800cab01a13d98d73c275a27cd674d85c52faa 100644 (file)
@@ -49,8 +49,28 @@ struct dentry {
        struct list_head d_alias;       /* inode alias list */
        struct list_head d_lru;         /* d_count = 0 LRU list */
        struct qstr d_name;
+       struct dentry * (*d_revalidate)(struct dentry *);
 };
 
+/*
+ * d_drop() unhashes the entry from the parent
+ * dentry hashes, so that it won't be found through
+ * a VFS lookup any more. Note that this is different
+ * from deleting the dentry - d_delete will try to
+ * mark the dentry negative if possible, giving a
+ * successful _negative_ lookup, while d_drop will
+ * just make the cache lookup fail.
+ *
+ * d_drop() is used mainly for stuff that wants
+ * to invalidate a dentry for some reason (NFS
+ * timeouts or autofs deletes).
+ */
+inline void d_drop(struct dentry * dentry)
+{
+       list_del(&dentry->d_hash);
+       INIT_LIST_HEAD(&dentry->d_hash);
+}
+
 /*
  * These are the low-level FS interfaces to the dcache..
  */
index 6c3bb69a1675037c8aaf5d08731b30e000791901..f09303ae8bd4b5f5606e8d71e2310bddc265cd1a 100644 (file)
@@ -629,8 +629,8 @@ extern struct file_operations rdwr_pipe_fops;
 extern struct file_system_type *get_fs_type(const char *name);
 
 extern int fs_may_mount(kdev_t dev);
-extern int fs_may_umount(kdev_t dev, struct dentry * root);
-extern int fs_may_remount_ro(kdev_t dev);
+extern int fs_may_umount(struct super_block *, struct dentry * root);
+extern int fs_may_remount_ro(struct super_block *);
 
 extern struct file *inuse_filps;
 extern struct super_block super_blocks[NR_SUPER];
index 84dcdac28a2b91fa8fe8ae2b2ce08eaac2b7a035..1aa495384ce70a3a727adfd8f270f7440bec62c4 100644 (file)
@@ -148,6 +148,8 @@ 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(insert_file_free);
 EXPORT_SYMBOL(check_disk_change);
 EXPORT_SYMBOL(invalidate_buffers);